为什么使用slot
生活中:
- 插槽的目的是让我们原来的设备具备更多的扩展性
- 比如电脑的USB, 我们可以插入U盘,硬盘、手机、音响、鼠标、键盘等等
组件的插槽:
-
也是为了让我们封装的组件更加具有扩展性
-
让使用者可以决定组件内部的一些内容到底展示什么
插槽的基本使用
显示效果:
具名插槽的使用:
需求:封装一个导航栏组件,左边、中间、右边都可根据需求显示不同的东西
实现:
<!-- 定义 -->
<template id="cpn">
<div>
<slot name="left">左边</slot>
<slot name="center">中间</slot>
<slot name="right">右边</slot>
</div>
</template>
<script>
new Vue({
el:"#app",
components:{
cpn:{
template:'#cpn'
}
}
})
</script>
<!-- 使用 -->
<div id="app">
<cpn>
<!-- 通过slot 的 name属性,决定替换那个插槽 -->
<span slot="center">标题</span>
<button slot="right">...</button>
</cpn>
<cpn>
<button slot="left">返回</button>
</cpn>
</div>
效果:
作用域插槽的使用
什么是编译作用域:
父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用内编译
案例:
效果:
作用域插槽:
父组件替换插槽的标签,但是内容由子组件来提供。
语法:
定义插槽时,为插槽绑定data属性(data可改为其他的名称,但必须是小写)
<!-- 匿名插槽 -->
<slot :data="变量名"><slot>
<!-- 具名插槽 -->
<slot :data="变量名" name="插槽名"></slot>
使用插槽时,通过v-slot 获取传过来的值 (data使用与定义时保持一致)
<!-- 匿名插槽 -->
<template v-slot="随便起的名">
{{随便起的名.data}} <!-- 获取data -->
</template>
<!-- 具名插槽 -->
<template v-slot:插槽名="随便起的名">
{{随便起的名.data}}
</template>
<!-- v-slot的缩写:# -->
<!-- 匿名插槽 -->
<template #default="随便起的名">
{{随便起的名.data}}
</template>
<!-- 具名插槽 -->
<template #插槽名="随便起的名">
{{随便起的名.data}}
</template>
案例:
<div id="app">
<cpn>
<!-- 目的是获取子组件中的数据 -->
<template v-slot="slotProps">
<p>{{slotProps.data.join(' + ')}}</p>
</template>
<template v-slot:slot1="slot1Props">
<p>{{slot1Props.data.join(' - ')}}</p>
</template>
</cpn>
<cpn>
<!--v-slot的缩写 # -->
<template #default="slotProps">
<p>{{slotProps.data.join(' * ')}}</p>
</template>
<template #slot1="slot1Props">
<p>{{slot1Props.data.join(' * ')}}</p>
</template>
</cpn>
</div>
<!-- 组件模板 -->
<template id="cpn">
<div>
<!-- 匿名插槽 -->
<slot :data="pLanguages"></slot>
<!-- 具名插槽-->
<slot :data="fruits" name="slot1"></slot>
</div>
</template>
<!--2.6 以上版本使用v-slot -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
new Vue({
el:"#app",
components: {
cpn: {
template: '#cpn',
data() {
return {
pLanguages:['javascript', 'c', 'c++', 'c#', 'java', 'python'],
fruits:['苹果', '香蕉', '柿子', '李子', '梨子']
}
}
}
}
})
效果: