2.6.0中,使用v-slot(以前具名插槽:slot,作用域插槽:slot-scope)。
v-slot的几种用法
用法一 插槽内容—template
核心:承载组件的分发内容。
// 定义,在 <navigation-link> 的模板中
<a
v-bind:href="url"
class="nav-link"
>
<slot></slot>
</a>
// 调用,调用<navigation-link>对应的组件
<navigation-link url="/profile">
<span class="fa fa-user"></span>
Your Profile
</navigation-link>
// 渲染结果
<a
v-bind:href="url"
class="nav-link"
>
<span class="fa fa-user"></span>
Your Profile
</a>
用法一 插槽内容—render
// 定义,在 <navigation-link> 的render函数中
render: function (createElement) {
// `<div><slot></slot></div>`
return createElement('div', this.$slots.default)
}
// 调用,调用<navigation-link>对应的组件
同上
// 渲染结果
同上
用法二 后备内容
核心:插槽可以设置默认内容
// 定义
<button type="submit">
<slot>Submit</slot>
</button>
// 调用
<submit-button></submit-button>
// 渲染结果
<button type="submit">
Submit
</button>
用法三 具名插槽
核心:插槽内容与插槽通过名称一一对应
// 定义
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
// 调用
<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>
// 渲染结果
<div class="container">
<header>
<h1>Here might be a page title</h1>
</header>
<main>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</main>
<footer>
<p>Here's some contact info</p>
</footer>
</div>
用法四 作用域插槽—template用法
核心:父组件中插槽内容调用子组件中数据,处理后在插槽中渲染内容。
// 定义,其中user为该current-user组件的一个实例属性user:{firstName:xing, lastName:ming}
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
// 调用
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
// 渲染结果
<span>
xing
</span>
用法四 作用域插槽—渲染函数用法
核心:vm.$scopedSlots等于 < slot > 标签
// 定义,子组件
Vue.component('child', {
name: "child",
render: function (createElement) {
return createElement('div', [
this.$scopedSlots.default({
text: "scopedSlots 测试"
})
])
// `<div><slot :text="'scopedSlots 测试'"></slot></div>`
}
});
// 调用,父组件
import child from './child.vue';
Vue.component('parent', {
name: "parent",
components: {
child
},
render: function (createElement) {
return createElement('div', [
createElement('child', { // 引用子组件
scopedSlots: {// 获取子组件的scopedSlots
default: function (props) {// 获取scopedSlots.default,命名为props
return createElement('span', props.text) // scopedSlots.default.text
}
}
})
])
/*
<div>
<child v-slot:default='slotProps'>
<span>{{ slotProps.text }}</span>
</child>
</div>
*/
}
});
// 渲染结果
<div>
<div>
<span>scopedSlots 测试</span>
</div>
</div>
用法五 遍历示例
核心:for循环中每一项都有各自的不同的插槽内容。
// 定义
<ul>
<li
v-for="todo in filteredTodos"
v-bind:key="todo.id"
>
<!--
我们为每个 todo 准备了一个插槽,将 `todo` 对象作为一个插槽的 prop 传入。
-->
<slot name="todo" v-bind:todo="todo">
<!-- 后备内容 -->
{{ todo.text }}
</slot>
</li>
</ul>
// 调用
<todo-list v-bind:todos="todos">
<template v-slot:todo="{ todo }">
<span v-if="todo.isComplete">✓</span>
{{ todo.text }}
</template>
</todo-list>
// 渲染结果
/* 假设 todos=[
{id: 0, text: '列表0', isComplete: true},
{id: 1, text: '列表1', isComplete: true}
]
*/
<ul>
<li
key="0"
>
列表0
</li>
<li
key="1"
>
列表1
</li>
</ul>
<div>
<child scopedSlots=>
</child>
</div>