插槽
一般情况下,html 中的组件之间的内容会被抛弃,例如:
效果:
对于这种情况,我们可以使用 <slot> 在 <box></box> 内添加内容:
效果:
即:当组件渲染的时候,<slot></slot> 将会被替换为 "<p>content</p>",插槽内可以包含任何模板代码,即使是其他组件。
编译作用域
我们可以在插槽中访问来自 Vue 实例的 property:
效果:
但是不能访问到组件的 prop:
效果:
这里的 temp 是 undefined,因为该插槽内容是传递给 <box></box> 的,而不是在 <box></box> 组件的内部模板中定义的。
对此官方解释是:
父级模板里的所有内容都是在父级作用域中编译的,子模版里的所有内容都是在子作用域中编译的。
后备内容
后备内容也就是默认内容,类似于函数的默认参数,它只会在没有提供内容的时候被渲染,例如:
效果:
如果提供内容则会取代后备内容:
效果:
具名插槽
默认情况下,<slot></slot> 会被替换为提供的全部内容,即提供的内容会视为默认插槽的内容:
效果:
但是我们可能希望将对应的内容放在对应的标签内,对此,<slot> 元素 name attribute 可以用来定义额外的插槽:
一个不带 name 的 <slot> 会带有隐含的 name="default"
在向具名插槽提供内容时,可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:
现在 <template> 元素中的所有内容都会被传入对应的插槽,任何没有包裹在带有 v-slot 指令的 <template> 中的内容都会视为默认插槽的内容(ps:v-slot 只能添加在 <template> 上,除非被提供的内容只有默认插槽时)。
效果:
作用域插槽
默认情况下,插槽内容是不能访问到组件的 prop 的,对此,可以将组件的 prop 作为 <slot> 元素的一个 attribute 绑定上去:
绑定在 <slot> 元素上的 attribute 被称为插槽 prop,现在在父级作用域中,可以使用带值的 v-slot 来定义插槽 prop 的名字:
效果:
v-slot:default="slotProps" 中的 slotProps 是可自主命名的。