插槽
基本使用:
使用slot标签在子组件中定义一个插槽:
<template>
<div>
<h2>组件的开始</h2>
<slot></slot>
<h2>组建的结束</h2>
</div>
</template>
在父组件中使用这个子组件,并在子组件标签中放入插槽元素:
<template>
<div>
<my-slot-cpn>
<button>我是按钮</button>
<my-button/>
</my-slot-cpn>
</div>
</template>
在slot标签中添加元素可以指定插槽的默认元素:
<template>
<div>
<h2>组件的开始</h2>
<slot>
<i>我是默认的i元素</i>
</slot>
<h2>组建的结束</h2>
</div>
</template>
具名插槽
通过给slot标签增加name属性来设置具名插槽:
<template>
<div class="nav-bar">
<div class="left">
<slot name="left"></slot>
</div>
<div class="center">
<slot name="center"></slot>
</div>
<div class="right">
<slot name="right"></slot>
</div>
</div>
</template>
使用过程中通过template的v-slot属性来指定使用某一个插槽:
<template>
<div>
<nav-bar :name="name">
<template v-slot:left>
<button>左边的按钮</button>
</template>
<template v-slot:center>
<h2>我是标题</h2>
</template>
<template v-slot:right>
<button>右边的按钮</button>
</template>
</nav-bar>
</div>
</template>
动态命名插槽:可以结合props来动态指定一个插槽的名称:
// NavBar.vue
<template>
<div class="nav-bar">
<div class="addition">
<slot :name="name"></slot>
</div>
</div>
</template>
<script>
export default {
props:{
name:String
}
}
</script>
// App.vue
<template>
<div>
<nav-bar :name="name">
<template v-slot:[name]>
<button>动态名称</button>
</template>
</nav-bar>
</div>
</template>
<script>
import NavBar from "./NavBar.vue";
export default {
components:{
NavBar
},
data() {
return {
name:"sk"
}
},
}
</script>
插槽有默认的名称default。
v-slot:的缩写是#
作用域插槽
作用域的概念是:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的;
在slot标签中增加属性,此属性的值可以在父组件中通过template的v-slot获取到一个实例(如slotProps),并通过slotProps来访问slot的属性:
// ShowNames.vue
<template>
<div>
<template v-for="(item,index) in names">
<slot :item="item" :index="index"></slot>
</template>
</div>
</template>
<script>
export default {
props:{
names:{
type: Array,
default:()=>[]
}
}
}
</script>
// App.vue
<template>
<div>
<show-names :names="names">
<template v-slot="slotProps">
<button>{{slotProps.item}}-{{slotProps.index}}</button>
</template>
</show-names>
</div>
</template>
如果是具名插槽,在父组件的template中可以指定某一个具体的名称:
<template v-slot:left="slotProps">
独占默认插槽的缩写:如果只有一个插槽,并且是非具名的,可以有以下缩写
<show-names :names="names" v-slot="slotProps">
<button>{{slotProps.item}}-{{slotProps.index}}</button>
</show-names>