Vue 插槽 slot
组件虽然能够提高对公有特性进行抽取,但无法解决这些公有需求中的个性化问题,此时我们可以为组件定义插槽来解决组件个性化的问题,我们需要对组建中需要灵活变动的东西使用插槽,当组件被其它组件或 Vue 实例使用的时候再来决定这些插槽中具体插入什么东西。
一. 匿名插槽
匿名插槽我们只需要在组件中使用 <slot>
标签注明插槽定义的位置,然后在使用组件中,在标签内部定义插槽中具体的值即可:
<div id="app">
<cpn>
<button>保存</button> //将要写的内容写在标签内,像 HTML 标签一样
</cpn>
<cpn>
<button>保存</button>
<button>取消</button>
</cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
这是一个组件
<slot>这里可以给插槽一个默认值</slot> //插槽
</div>
</template>
const app = new Vue({
el: '#app',
components: {
cpn:{
template:"#cpn"
}
}
});
二. 具名插槽
匿名插槽在只有一个插槽的情况下没有任何问题,但是如果我们需要在一个组件中定义若干个插槽时,匿名插槽就不能满足我们的需求了。
2.6.0 之前版本
<slot>
标签有一个 name 属性用于定义插槽的名字,需要注意的是:如果我们在定义插槽时不指定 name 属性,那它会有一个名为 default
的默认值。
<div id="app">
<cpn>
<button slot="slot1">保存</button>
<span slot="slot1">-----</span>
<button slot="slot2">保存</button>
</cpn>
</div>
<template id="cpn">
<div>
这是一个组件
<slot name="slot1">这里可以给插槽一个默认值 1</slot>
<slot name="slot2">这里可以给插槽一个默认值 2</slot>
</div>
</template>
const app = new Vue({
el: '#app',
components: {
cpn:{
template:"#cpn"
}
}
});
2.6.0 版本改动
自 2.6.0 起新增 v-slot
指令来替代 slot
属性,slot 属性已废弃使用。在 Vue2.x 版本中还会继续支持该属性,但是到了 Vue3.0 中将会被正式废弃。上面 slot
属性转换成 v-slot
是这样写的:
<div id="app">
<cpn>
<template v-slot:slot1>
<button>保存</button>
<span>-----</span>
</template>
<template v-slot:slot2>
<button>取消</button>
</template>
</cpn>
</div>
注意 v-slot 只能添加在 <template>
上 (只有 一种例外情况 ),这一点和已经废弃的 slot
attribute 不同。
三. 作用域插槽
3.1 编译作用域
在理解作用域插槽之前我们需要理解编译作用域的概念。我们先看看下面这段代码,在 Vue 实例和组件中都有各自的 isShow
属性,如果我们在使用组件时通过 isShow
来决定是否显示,那它实际上是由 Vue 实例中的属性决定。
<div id="app">
<cpn v-show="isShow"></cpn>
</div>
<template id="cpn">
<div>
<span>HelloWorld!</span>
</div>
</template>
const app = new Vue({
el: '#app',
data:{
isShow: true
},
components: {
cpn:{
template:"#cpn",
data(){
return {
isShow: false
}
}
}
}
});
这也就是 Vue 官方给出的说明:父组件模板中所有东西都会在父级作用域内编译;子组件模板中的所有东西都会在子级作用域内编译。
3.2 作用域插槽
前面匿名插槽和具名插槽都是使用父组件中的数据进行渲染的。作用域插槽解决的问题是,让插槽使用子组件中的数据进行渲染。
2.6.0 之前版本
在 <template>
上使用特殊的 slot-scope
attribute,可以接收传递给插槽的 prop:
<div id="app">
<cpn>
<template slot-scope="scope">
{{scope.student.name}}
---{{scope.student.age}}
</template>
</cpn>
</div>
<template id="cpn">
<div>
<slot :student="student"></slot>
</div>
</template>
const app = new Vue({
el: '#app',
components: {
cpn:{
template:"#cpn",
data(){
return {
student:{
name:"张三",
age:12
}
}
}
}
}
});
2.6.0 版本改动
与 2.6.0 之前版本一样,我们仍然需要使用 v-bind 指令,将子组件的值绑定到插槽中:
<template id="cpn">
<div>
<slot :student="student"></slot>
</div>
</template>
绑定在 <slot>
元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot
来定义我们提供的插槽 prop 的名字:
v-slot
指令语法:v-slot:插槽名称="变量名称"
<cpn>
<template v-slot:default="scope">
{{scope.student.name}}
---{{scope.student.age}}
</template>
</cpn>
完整实例:
<div id="app">
<cpn>
<template v-slot:slot1="scope">
{{scope.student.name}}
---{{scope.student.age}}
</template>
<template v-slot:slot2="scope">
{{scope.student.name}}
---{{scope.student.age}}
</template>
</cpn>
</div>
<template id="cpn">
<div>
<slot name="slot1" :student="student"></slot>
<slot name="slot2" :student="person"></slot>
</div>
</template>
const app = new Vue({
el: '#app',
data:{
isShow: true
},
components: {
cpn:{
template:"#cpn",
data(){
return {
student:{
name:"张三",
age:12
},
person:{
name:"李四",
age:32
}
}
}
}
}
});
插槽内容时使用子组件中的数据进行渲染。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: Vue 自定义组件
下一篇: 谈谈自己对于 AOP 的了解
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论