一、插槽(slot)
将父组件中的内容与子组件的模板进行混合使用。可以弥补视图的不足。
二、使用插槽的目的
使组件更具有扩展性。
三、插槽的使用
1.匿名插槽(默认插槽)
有且只能有一个。
Son.vue代码段:
<template> <div> <h2>子组件</h2> <p>西安邮电大学</p> <slot></slot> </div> </template> <script> export default { name: "Son" } </script> <style scoped> </style>
Father.vue代码段:
<template> <div> <son> <button>演示按钮</button> </son> </div> </template> <script> import Son from "./Son.vue"; export default { name: "Father" } </script> <style scoped> </style>
App.vue代码段:
import Father from "./components/Father.vue"; <template> <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" /> <Father/> </template>
效果图:
2.具名插槽
当子组件的功能复杂时,子组件的插槽可能并非是一个。每个插槽给个名称。 比如封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边。那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢?
这时候,就需要给slot指定一个name属性,也就是具名插槽。
- 子组件中定义插槽:<slot name=“名称”></slot>
- 父组件中使用插槽:<template v-slot:“插槽名”></template>
Father.vue代码段:
<template> <div> <Son> <template v-slot:top> <button>顶部按钮</button><br/> </template> <template v-slot:center> <input type="text"/> </template> <template v-slot:bottom> <h2>具名插槽</h2> </template> <template v-slot:default> //dafault代表匿名的插槽 <button>匿名插槽</button> </template> </Son> </div> </template> <script> import Son from './Son.vue' export default { name: "Father", components: { Son } } </script> <style scoped> </style>
Son.vue代码段:
<template> <div> <slot name="top"></slot> <slot name="center"></slot> <slot name="bottom"></slot> <slot></slot> </div> </template> <script> export default { name: "Son" } </script> <style scoped> </style>
App.vue代码段:
import Father from "./components/Father.vue"; <template> <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" /> <Father/> </template>
效果图:
3.作用域插槽
父组件在使用的时候可以替换slot插槽中的显示页面结构,但展示的数据还是来源于子组件。
- 子组件中定义:<slot :属性名=“变量名” name=“插槽名”>
- 父组件中使用:
<template v-slot:插槽名=“变量名”>
<h2>{{ 变量名.子组件中插槽绑定的属性名</h2>
</template>Son.vue代码段:
<template> <div> <slot :lang="languageList" name="sp"></slot> <slot :lang="languageList" name="cz"></slot> </div> </template> <script> export default { name: "Son", data(){ return { languageList:['Javascript','c++','Java','Python'] } } } </script> <style scoped> </style>
Father.vue代码段:
<template> <div> <!-- 水平方向展示--> <Son> <template v-slot:sp="slotProps"> <h2>{{ slotProps.lang.join('--') }}</h2> </template> </Son> <hr/> <!-- 垂直方向展示--> <Son> <template v-slot:cz="slotProps"> <ul> <li v-for="(item,index) in slotProps.lang" :key="index">{{ item }}</li> </ul> </template> </Son> </div> </template> <script> import Son from './Son.vue' export default { name: "Father", components: { Son } } </script> <style scoped> </style>
效果图:
注意:数据来源于子组件,展示方式由父组件决定;‘v-slot:‘指令可以缩写为’#’
上例中Father.vue代码段的改写如下(效果相同):
<!-- 水平方向展示--> <Son> <template #sp="slotProps"> <h2>{{ slotProps.lang.join('--') }}</h2> </template> </Son> <hr/> <!-- 垂直方向展示--> <Son> <template #cz="slotProps"> <ul> <li v-for="(item,index) in slotProps.lang" :key="index">{{ item }}</li> </ul> </template> </Son>