1. 概括
- $attrs 简化多层组件之间props传值;
- $listeners 简化多层组件之间事件传递;
- $Slots 更多拓展自定义组件传值,包括自定义html元素,及对象;
- props validator 增强组件传值稳健性,可自定义业务代码效验参数;
- $refs 对外提供API 增强组件灵活度和可控性;
2. 详细介绍
2.1 $attrs 简化多层组件之间props传值
封装业务组件的常规手段需要声明props,但是一个个声明属性传递太麻烦
这时我们可以使用$attrs
这里可以看到官方也是推荐我们使用这个属性来进行封装的,注意不能生命prop。
假如我们在my-input中的created生命周期函数中打印this.attrs,会看到刚刚传递的clearable
那么要怎么给封装组件使用呢?很简单v-bind=”$attrs” 在原子组件上就可以应用了
可以看到clearable已经给原子组件应用小叉叉了
这里需要注意vue会将被传入但未生命prop的元素作为html元素的属性放在跟元素上,所以需要设置inheritAttrs为false
2.2 $listeners 简化多层组件之间事件传递
业务组件将原子组件的事件传递给父组件,我们常规是这样写
父组件:
<my-input @clear="clearCallFn">
</my-input>
<script>
...
methods:{
clearCallFn(){
...
}
}
</script>
业务组件:
但还是上面说的,太麻烦,所以vue给我们提供了一个好方法,利用listeners属性(vue3迁移到了attrs)
在my-input中给原子属性使用$listeners转发父组件的监听进去,父组件的写法不变就可以。
需要注意的是不能同时使用两种写法(如下边蓝色框框),否则会调用两次。
2.3 $slots和$scopedSlots的使用
(1)$slots
这个属性包含了给父组件的非作用域插槽
看一下有什么值
for循环拿到原子组件插槽再定义业务组件的插槽
(2)$scopedSlots
如果想使用作用域插槽,那么使用scopedSlots看下图scopedSlots循环
2.4 props validator
一般我们会用对象的方式来生命prop,我们可以在对象中指定prop的默认值,也可以指定类型来对prop进行验证。
一个更灵活的方式是,传入并编写一个验证函数。
prop会作为一个参数传入该函数,函数返回false值时会抛出控制台警告,适合验证枚举值
如下例子:
在子组件有props
在父组件故意传错
会发现控制台
2.5 $refs
我们知道$refs可以访问被引用的组件,并访问其实例方法,但是如果我们封装了业务组件,主页面对原子组件的调用往往可读性较差,如下:
那么其实我们可以在业务组件methods写一个api来暴露引用,如下:
这时候我们就可以直接在主页面调用业务组件暴露出来的api,以此来调用原子组件方法。