“我报名参与金石计划1期挑战——瓜分10万奖池,这是我的第2篇文章,点击查看活动详情”


条件概要:

作为一个前端搬砖工程师经常需求搬砖,封装一些第三方组件,在添加新的特点、插槽、事情时分就会想应该怎样去保留,向外抛出封装本来第三方组件供给的特点、插槽、事情;可是如果是一个个特点和事情以及插槽进行重新声明界说,虽然也是可行的,可是不免也太过于麻烦了,而且这种做法在晋级了本来依赖的UI库后某些新增或者break-change的时分就会发生不明所以的bug了。

因此这篇文章就简略的介绍怎样分别来优雅的保留着第三方UI库组件原供给的特点(Attributes)、插槽(Slots)和自界说事情(Events),进步生产力功率和代码质量!


一、特点【Attributes】:

$attrs:组件实例的该特点包括了父效果域中不作为prop被识别(且获取)的attribute绑定(classstyle在外)。当一个组件没有声明任何prop时,这儿会包括一切父效果域的绑定(classstyle在外),而且能够经过v-bind="$attrs"传入内部的UI库组件中。

inheritAttrs:默许情况下父效果域的不被认作props的attribute绑定(attribute bindings)将会“回退”且作为一般的HTML attribute应用在子组件的根元素上,也便是下面比如的MyButton组件上面也会存在这些想要透传的特点,这可能不会总是符合预期行为。因此此时需求经过设置inheritAttrsfalse,将Vue.js的这个默许行为给去掉。而经过实例的$attrs能够让这些透传的attribute生效,且经过v-bind显性的绑定到非根元素第三方UI库的组件上了。

// MyButton.vue
<template>
  <a-button v-bind="$attrs" >
    <slot />
  </a-button>
</template>
<script> 
  export default { 
    inheritAttrs: false,
  }
</script>

二、自界说事情【Events】:

$listeners:组件实例的该特点包括了父效果域中的(不含.native修饰器的)v-on事情监听器。它能够经过v-on="$listeners"转发传入内部组件,进行对事情的监听处理。

需求留心:如果既使用了v-on="$listeners"进行转发事情,而且二次封装的组件内也对原UI库组件的事情进行监听调用,此时事情会触发两次,需求注意这个问题!

// MyInput.vue
<template>
  <a-input v-bind="$attrs" v-on="$listeners" />
</template>
<script> 
  export default { 
    inheritAttrs: false,
  }
</script>

三、插槽【Slots】:

$slots:一般插槽比较好理解,使用$slots这个变量拿到非效果域的插槽分发内容,然后循环渲染对应的一般签字插槽,这样就能够直接打通封装组件的插槽和第三方组件供给的原插槽;

$scopedSlots:效果域插槽则绕了一圈,使用了一个插槽的语法糖(签字插槽的缩写)而且结合着动态插槽名的用法;循环$scopedSlots而且刺进到第三方组件供给的原效果域插槽方位,在里面才创建封装组件自己的效果插槽方位和传递对应的参数,间接打通了效果域插槽的通道。

// MyTable.vue
<template>
  <a-table v-bind="$attrs" v-on="$listeners">
    <!-- 一般插槽 -->
    <slot v-for="(_, slotName) in $slots" :name="slotName" :slot="slotName"/>
    <!-- 效果域插槽 -->
    <template v-for="(_, scopeSlotName) in $scopedSlots" #[scopeSlotName]="scope" >
      <slot :name="scopeSlotName" v-bind="scope" />
    </template>
  </a-table>
</template>
<script>
  export default {
    inheritAttrs: false,
  };
</script>

四、额外加餐

我们应该都知道上面描述首要都是Vue 2.x的场景(毕竟现在2.x仍是在市场上占用不少的比例的嘛),在Vue 3.x傍边有些API是有所调整的,因此这儿也简略讲述下Vue 3.x的改变调整,首要仍是一些组件实例的特点之间的合并。

$attrs$listeners 合并

在 Vue 3.x 傍边,取消了$listeners这个组件实例的特点,将其事情的监听都整合到了$attrs这个特点上了,因此在 Vue 3.x 傍边是简化了操作,直接经过v-bind$attrs特点就能够进行 props 特点和 event 事情的透传分发了。

// MyButton.vue
<template>
  <a-button v-bind="$attrs" >
    <slot />
  </a-button>
</template>
<script> 
  export default { 
    inheritAttrs: false,
  }
</script>
<template>
  <my-button size="small" @click="handleClickEvent" >
    这是二次封装的按钮组件
  </my-button>
</template>
<script setup>
  const handleClickEvent = () => {
    // TODO:xxxx
  }
</script>

$slot$scopedSlots 合并

相同,在 Vue 3.x 傍边取消了效果域插槽$scopedSlots的特点,将一切插槽都统一在$slots傍边,因此在 Vue 3.x 傍边最简略粗暴的办法便是直接无分默许插槽、签字插槽和效果域插槽进行统一的处理。

// MyTable.vue
<template>
  <a-table v-bind="$attrs">
    <template v-for="(_, scopeSlotName) in $slots" #[scopeSlotName]="scope" >
      <slot :name="scopeSlotName" v-bind="scope" />
    </template>
  </a-table>
</template>
<script>
  export default {
    inheritAttrs: false,
  };
</script>

参考资料:

同系列文章:

  • Vue 使用技巧:devtools 的一些使用秘籍

相关常识参考资料:

  • 透传 Attributes | Vue.js:cn.vuejs.org/guide/compo…
  • 组件实例 $attrs | Vue.js:cn.vuejs.org/api/compone…
  • 其他杂项选项 inheritattrs | Vue.js:cn.vuejs.org/api/options…
  • 插槽 Slots | Vue.js:cn.vuejs.org/guide/compo…
  • 组件实例 $slots | Vue.js:cn.vuejs.org/api/compone…
  • $listeners在vue3中使用-CSDN博客:blog.csdn.net/qq_41068783…
  • Vue3.0破坏性改变—-$slots:events.jianshu.io/p/d9c493781…
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。