插槽
<slot>
元素,承载分发内容的出口。或者理解为占位符
,当父组件引用子组件时可以填充相应内容。
子组件<item-d>
<div class="demo">
<slot></slot>
</div>
父组件
<item-d>
插槽内容
</item-d>
当然插槽内可以包含任何模板代码,包括 HTML
如下父组件引用<item-d>
时插入个按钮
<item-d>
<button @click="account++">{{account}}</button>
</item-d>
编译作用域
在上例中,<button>
是作为父组件的内容进行编译的,所以可以访问父组件的实例属性account
。
后备内容
插槽的默认内容。当父组件使用子组件不提供插槽内容时,默认显示插槽的后备内容
在<item-d>
组件中
<div>
<slot>这是默认显示内容</slot>
</div>
父组件
<item-d></item-d>
<item-d>
父组件提供插槽内容
</item-d>
具名插槽
当子组件中有多个插槽时,想将不同的内容显示到对应插槽中,则要借助于<slot>
的name
属性。
在子组件<item-d>
中
<div class="demo">
<slot name="s1">插槽一</slot>
<slot>插槽二</slot>
<slot>
<h1>1</h1>
</slot>
</div>
父组件
<item-d>
<template v-slot:s1>1</template>
<template>2</template>
未定义
<template v-slot:s1>3</template>
</item-d>
在父组件中,
<template>2</template>
及未定义
都没有设置v-slot,默认属于default
插槽,而<template v-slot:s1>1</template>
和<template v-slot:s1>3</template>
属于同一个具名插槽;子组件中,<slot>插槽二</slot>
和<slot><h1>1</h1></slot>
都是default
插槽;在实际页面显示中可以看到2 未定义
出现了两次,即default
插槽使用了两次,而s1
插槽的位置上显示的是3
,则说明在父组件引用子组件时,后面的覆盖了前面的s1
插槽(或者说重定义)。
- 没有设置
name
属性值时,默认为default
- 父组件引用子组件时,任何没有被包裹在带有
v-slot
的<template>
中的内容都会被视为默认插槽的内容 - 如果出现相同
v-slot
的<template>
,后面的会覆盖前面的
作用域插槽
父组件通过插槽访问子组件的数据。子组件在<slot>
元素上绑定的属性称为插槽prop
,父组件使用v-slot
指令定义插槽prop
。定义的属性只能在对应的<template>
中使用,即作用域只在当前的<template>
中有效。
和父组件向子组件通信的prop
类似:将要访问的数据绑定到元素属性,然后在引用的地方“声明”下。
子组件
<div class="demo">
<slot name="s1" :title="title"></slot>
</div>
...
export default {
data(){
return {
title:'标题'
}
}
}
父组件
<item-d>
<template v-slot:s1="t1">{{t1.title}}</template>
</item-d>
其它
- 父组件使用
v-slot
指令定义插槽prop
,只在其<template>
中有效。 - 若子组件中只有默认插槽,如
v-slot:default="t1"
可以简写成v-slot="t1"
;当同时存在具名插槽
时,则不能这样简写(作用域不明确)。 -
v-slot:
可以简写成#
,v-slot="t1"
可以简写成#default="t1"
,v-slot:s1
可以简写成#s1
。(缩写只在其有参数的时候才可用)。 - 支持动态的插槽名,如在父组件内
s="s1"
,则#[s]
等同于#s1
,当然变量s
的值要是个字符串。