其实这个特性我见的不多,所以一直没去了解他的功能,现在觉得这个特性挺灵活的,能写出高复用性的组件。
概述
slot scope 是对 slot 功能的增强,主要功能是将子组件中的数据带出给父组件使用,以函数作为例子,可以看作是:
1 | function (list) { |
让子组件可以对 props 做一系列的操作,之后将结果通过 slot scope 传递给父组件,让父组件决定显示的方式。
这种需求之所以要用到 slot scope,原因在于在父组件的作用域中,是无法访问子组件作用域的,就算子组件和父组件同时拥有 user 这个属性,在父组件中 this.user
指向的还是自己本身的 user,所以需要 slot scope 把数据带出来。
举个例子🌰
1 | <template> |
这个组件叫做 MakeOrderedList,用于作为有序列表的容器,在父组件中是这样的:
1 | <make-ordered-list :list="[{name: 'a', age: 12}, {name: 'abc', age: 10}]"> |
list 是任意格式的列表,子组件会将 list 拆分为 key 和 value,并将这两个属性通过 v-bind 的形式回传,在父组件中通过 slot-scope="scope"
新建一个名为 scope 的对象承接子组件回传的属性,template 中的就是显示的具体结构了。
换个例子🌰
刚刚的例子仅仅是为了展示功能,没有意义,这里举 UI 框架中常见的 table 组件作为例子,在 Vuetify 中,table 组件的用法为:
1 | <v-data-table |
data table 这个组件接受了两个 props,他根据 headers 渲染出表头,接受 items 作为表内容,但是不立即渲染出来,而是将元素回传给父组件,目的是让父组件去决定显示的效果。
关于语法
以上两个例子用了不同的 slot 语法,第二个例子中的语法是新的,大概是 2.6.0 更新的。
改动:
插槽的语法从 slot
与 slot="name"
变成了 v-slot
与 v-slot:name
。
插槽作用域从 slot-scope
改成了 v-slot:slotName
,旧版本只能和 slot
组合使用以指定插槽。
特性:
新增了动态插槽,通过 v-slot:[dynamicSlotName]
来声明,参考 ES6 的语法。
新增了具名插槽的缩写 #
,比如 #name
、#header
,要注意的是具名,默认插槽不能简写,可参考 v-bind 或 v-on(除非写成 #default
)。