插槽内容
slot
元素作为承载内容分发的出口,在slot
插槽中可以包含任何模板代码或者其他组件
在组件中:
<button class="btn-primary">
<slot></slot>
</button>
在调用时:
<todo-button>
<i class="fas fa-plus"></i>
Add todo
</todo-button>
todo-button>
<font-awesome-icon name="plus"></font-awesome-icon>
Add todo
</todo-button>
如果组件中没有slot
元素,那么组件起始标签和结束标签之间的内容都会被抛弃
渲染作用域
在插槽中使用数据时,例如
<todo-button action="delete">
Delete a {{ item.name }}
</todo-button>
插槽之间的内容与模板其余部分有相同的作用域,可以访问组件实例所有的Property
但是插槽不能访问<todo-button>的作用域,例如上面的例子中,是无法访问action的 ,因为action是被传递到<todo-button>中的,不要是在父级作用域中被定义的
父级模板的所有内容都是在父级作用域中编译的,子模板的所有内容都是在子作用域中定义的
备用内容
在<slot>标签之间的内容会作为备用内容存在,当父组件中不提供任何插槽内容时,备用内容会被渲染,如果提供了内容,备用内容会被提供的内容所取代
具名插槽
<slot>元素上添加name属性,可以用来定义指定插槽的名称
<!-- base-layout -->
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
不带name
的插槽会带有隐含的名称default
在向具名插槽提供内容时,可以在<template>
元素上使用v-slot
指令,参数值就是对应的插槽名称,<template>
的内容就会被传入相应的插槽:
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
注意,除了只有默认插槽独立存在的情况外,v-slot
只能用在<template>
上
作用域插槽
作用域插槽的目的就是为了让插槽内容(在父组件中)访问子组件中的数据(例如上面例子中的action
),这时候需要在子组件的<slot>
元素上将要传递出去的数据内容作为属性来绑定:
<el-button type="primary">
<slot :message="message"></slot>
</el-button>
绑定在<slot>元素上的属性被称为插槽Prop,此时在父作用域上就可以使用带值的v-slot来获取插槽Prop
<slot-child>
<template v-slot:default="slotProps">{{ slotProps.message }} -- ok</template>
</slot-child>
具名插槽的缩写
和v-on缩写为@,v-bind缩写为:一样,v-slot缩写为#,例如v-slot:header缩写为#header:
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<template #default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template #footer>
<p>Here's some contact info</p>
</template>
</base-layout>