插槽
<slot>
元素作为承载分发内容的出口。- 当组件渲染的时候,
<slot>
元素将会被替换为父组件分发的具体内容。 - 插槽内可以包含任何模板代码,包括 HTML,甚至其他组件。
- 组件模板内如果没有放
<solt>
标签,那么组件标签内部的内容都将被遗弃。
以之前学校为例,需求:利用插槽为学校组件添加标题,内容是 ‘学校信息’。
完成这个需求需要俩个步骤:
- 在
App
组件内,School
组件标签内添加<h2>学校信息</h2>
。 - 在
School
组件内部,需要的接受信息位置添加<solt></solt>
标签。 - 注意:需要使用插槽的组件使用双标签。
App.vue
<template>
<div id="app">
<h1>{{msg}}</h1>
<School> <h2>学校信息</h2> </School>
</div>
</template>
<script>
import School from './components/School';
export default {
name: 'App',
data() {
return {msg:"你好啊!"}
},
components: {School},
}
</script>
<!--...-->
School.vue
<template>
<div class="school">
<slot></slot>
<p>学校名字:{{name}}</p>
<p>学校地址:{{add}}</p>
<p>办校年限:{{age}}</p>
</div>
</template>
<script>
import pubsub from 'pubsub-js';
export default {
name:'School',
props:['getSchoolName'],
data() {
return {
name:"五道口职业技术学校",
add:"北京",
age:100
}
},
}
</script>
<!--...-->
效果图片:
具名插槽
需要多个插槽时,就需要做标识了,默认的插槽不需要做标识,每个组件只能有一个默认的插槽。
出现多个插槽,最好把所有的插槽使用 标签包裹起来。
v-slot
只能使用在<template>
标签上。- 任何没有被包裹在带有
v-slot
的<template>
中的内容都会被视为默认插槽的内容。
App.vue
<template>
<div id="app">
<h1>{{msg}}</h1>
<School>
<h2>学校信息</h2>
<!-- v-slot标注插槽名字 -->
<template v-slot:schoolName>
<p>学校名字:五道口职业技术学校</p>
</template>
<!-- v-slot缩写 # -->
<template #schoolAge>
<p>办校年限:100</p>
</template>
<!-- 使用插槽插入别的组件 -->
<Student slot="student"></Student>
</School>
</div>
</template>
<script>
import School from './components/School';
import Student from './components/Student';
export default {
name: 'App',
data() {
return {msg:"你好啊!"}
},
components: {School,Student},
}
</script>
<!--...-->
School.Vue
<template>
<div class="school">
<slot></slot>
<slot name="schoolName"></slot>
<p>学校地址:{{add}}</p>
<slot name = "schoolAge">学校历史</slot>
<hr>
<slot name = "student">学生信息</slot>
</div>
</template>
<script>
export default {
name:'School',
props:['getSchoolName'],
data() {
return {
name:"五道口职业技术学校",
add:"北京",
}
}
}
</script>
<!--...-->
Student.Vue
<template>
<div class="student">
<p>学生姓名:{{name}}</p>
<p>学生年龄:{{age}}</p>
<p>学生性别:{{sex}}</p>
</div>
</template>
<script>
export default {
name:'Student',
data() {
return {
name:"张三",
age:18,
sex:"男"
}
}
}
</script>
<!--...-->
效果展示:
作用域插槽
在具名插槽的案例中,我们的 学校名字 和 办校年限 都直接写在了App组件中,没有使用到 School组件中的数据,因为两个组件作用不同App无法获取到School组件中的数据,作用域插槽正好解决这个问题,因为作用于插槽可以让插槽内容能够访问子组件中才有的数据。
- 注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确
App.vue
<template>
<div id="app">
<h1>{{msg}}</h1>
<School title="学校信息">
<template scope="SchoolInfo">
<ul>
<li>学校名字:{{SchoolInfo.SchoolInfo.schoolName}}</li>
<li>学校地址:{{SchoolInfo.SchoolInfo.add}}</li>
<li>学校历史:{{SchoolInfo.SchoolInfo.age}}</li>
</ul>
</template>
</School>
<School title="学校信息">
<template scope="{SchoolInfo}">
<h3>学校名字:{{SchoolInfo.schoolName}}</h3>
<h3>学校地址:{{SchoolInfo.add}}</h3>
<h3>学校历史:{{SchoolInfo.age}}</h3>
</template>
</School>
<School title="学校信息">
<template scope="SchoolInfo">
<p style="color:#ff0">学校名字:{{SchoolInfo.SchoolInfo.schoolName}}</p>
<p style="color:#0f0">学校地址:{{SchoolInfo.SchoolInfo.add}}</p>
<p style="color:#00f">学校历史:{{SchoolInfo.SchoolInfo.age}}</p>
</template>
</School>
</div>
</template>
<script>
import School from './components/School';
export default {
name: 'App',
data() {
return {
msg:"你好啊!"
}
},
components: {School},
}
</script>
<!--...-->
School.vue
<template>
<div class="school">
<h2>{{title}}</h2>
<slot :SchoolInfo="SchoolInfo"></slot>
</div>
</template>
<script>
export default {
name:'School',
props:['title'],
data() {
return {
SchoolInfo:{
schoolName:"五道口职业技术学校",
add:"北京",
age:100
}
}
}
}
</script>
<!--...-->
效果: