经常的,我们在日常工作中,会使用第三方UI组件库,比如:element-ui、vant-ui、iview、ant-design等等。不管是为了业务考虑还是单纯的为了提高效率,我们会把一些经常用到的组件抽离、封装成公共组件,这样方便我们在不同的地方使用这个组件,减少重复代码的编写。
我们把对于第三方组件库的封装称为组件的二次封装,那么这带来有个思考,当我们在二次封装时,我们在封装什么?
在 vue 组件封装时,我们需要注意的主要是三部分:prop、event、slot。
$attrs
和 $listeners
我们多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,这就有点大材小用了。所以就有了 $attrs / $listeners
,通常配合 inheritAttrs 一起使用。
感觉还是挺晦涩难懂的,简单的说就是 inheritAttrs:true 继承除props之外的所有属性;inheritAttrs:false 只继承class属性。
$attrs
: 包含了父作用域中不被认为 (且不预期为) props 的特性绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs"
传入内部组件。当一个组件没有声明任何 props 时,它包含所有父作用域的绑定 (class 和 style 除外)。* $listeners
: 包含了父作用域中的 (不含 .native 修饰符) v-on 事件监听器。它可以通过 v-on="$listeners"
传入内部组件。它是一个对象,里面包含了作用在这个组件上的所有事件监听器,相当于子组件继承了父组件的事件。attrs和attrs 和 attrs和listeners 在做组件二次封装时非常有用。$attrs
和 $listeners
上面说了那么多,我们来看一个例子:
在使用 el-input-number时,当我们给他赋默认值 null
或者空字符串 ""
时,会显示 0 ,而这在我们一些业务场景里并不是很友好,并且值是居中显示的,那么现在我们想要做的改造是:值居左显示,没有默认值显示0的问题,且默认不展示控制按钮