“我报名参与金石计划1期挑战——瓜分10万奖池,这是我的第2篇文章,点击查看活动详情”
条件概要:
作为一个前端搬砖工程师经常需求搬砖,封装一些第三方组件,在添加新的特点、插槽、事情时分就会想应该怎样去保留,向外抛出封装本来第三方组件供给的特点、插槽、事情;可是如果是一个个特点和事情以及插槽进行重新声明界说,虽然也是可行的,可是不免也太过于麻烦了,而且这种做法在晋级了本来依赖的UI库后某些新增或者break-change的时分就会发生不明所以的bug了。
因此这篇文章就简略的介绍怎样分别来优雅的保留着第三方UI库组件原供给的特点(Attributes)、插槽(Slots)和自界说事情(Events),进步生产力功率和代码质量!
一、特点【Attributes】:
$attrs
:组件实例的该特点包括了父效果域中不作为prop被识别(且获取)的attribute绑定(class
和style
在外)。当一个组件没有声明任何prop时,这儿会包括一切父效果域的绑定(class
和style
在外),而且能够经过v-bind="$attrs"
传入内部的UI库组件中。
inheritAttrs
:默许情况下父效果域的不被认作props的attribute绑定(attribute bindings)将会“回退”且作为一般的HTML attribute应用在子组件的根元素上,也便是下面比如的MyButton组件上面也会存在这些想要透传的特点,这可能不会总是符合预期行为。因此此时需求经过设置inheritAttrs
到false
,将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…