slot 翻译为插槽,插槽的目的是让我们原来的设备具备更多的扩展性。vue组件中使用插槽,也是为了让我们封装的组件更加具有扩展性,让使用者可以决定组件内部的一些内容到底展示什么。
在子组件中,使用特殊的元素 就可以为子组件开启一个插槽,该插槽插入什么内容取决于父组件如何使用。
当子组件的功能复杂时,子组件的插槽可能并非是一个。
比如我们封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边部分。
那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢?这个时候,我们就需要给插槽起一个名字,这就是具名插槽。
具名插槽的使用很简单,只要给 slot 元素一个 name 属性即可:
,然后在父组件中使用的时候slot='myslot'
在学习作用域插槽之前需要先理解一个概念:编译作用域
官方给出的准则:
父级模板
里的所有内容都是在父级作用域
中编译的;子模板
里的所有内容都是在子作用域
中编译的。eg:思考以下代码是否能够渲染出来
<div id="app">
<child v-show="isShow">child>
div>
<template id="child">
<div>我是子组件div>
template>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: "#app",
data: {
isShow: true // 父组件中的isShow为true
},
components: {
child: {
template: "#child",
data () {
return {
isShow : false // 子组件中的isShow为false
}
}
}
}
})
script>
答案:最终可以渲染出来。因为我们在使用
的时候,整个组件的使用过程是在父组件中,那么它的作用域就是父组件,使用的属性也是父组件中的isShow
属性,父组件中的isShow
为true
,所以最终可以渲染。
作用域插槽一句话总结就是:父组件替换插槽的标签,但是内容由子组件来提供。也可理解为子组件数据可以被父组件拿到。
eg:子组件中有一组数据,需要在多个界面进行展示,某些界面直接展示数组,某些界面用-
和*
进行分割。
1.子组件中定义数据,并用v-bind的形式绑定到data
上(这里data
可以随便命名)
2.父组件中通过定义(vue2.5.x以下必须用template模板,以后版本可用别的标签如div),再通过
slot.data
就可以拿到子组件中的数据了。("slot"随便命名)
vue
在 2.6.0
中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot
指令)。它取代了 slot
和 slot-scope
这两个目前已被废弃但未被移除且仍在文档中的特性,但是将会在vue3
中,被废弃的这两个,不会被支持即无效。
用法:v-slot:default
,可以省略不写,写上感觉和具名写法比较统一,容易理解
<div id="app">
<child v-slot:default>child>
div>
<template id="child">
<div>
<slot>插槽默认内容slot>
div>
template>
vue 2.6.0
之后 v-slot
只能用在 template上,用在 div 或 p 这种标签上是会报错的。
<div id="app">
<child v-slot:center>
替换掉中间内容
child>
div>
<template id="child">
<div>
<slot name="left">我是左边slot>
<slot name="center">我是中间slot>
div>
跟 v-on
和 v-bind
一样,v-slot
也有缩写,即把参数之前的所有内容 v-slot:
替换为字符 #
。如上述代码中 v-slot:center
可以被重写为 #center
<child #center>child>
匿名插槽想用的话必须加上default
<child #default>child>
v-slot : 插槽名称 = ' 传过来的值 '
<div id="app">
<child>
<template v-slot:myslot="slotdata">
{
{slotdata.mydata}}
template>
child>
div>
<template id="child">
<div>
<slot name="myslot" :mydata="languages">slot>
div>
template>
js:
const app = new Vue({
el: "#app",
components: {
child: {
template: "#child",
data() {
return {
languages: ['Java', 'PHP', 'JS','C', 'OC']
}
}
}
}
})
也可用缩写:
<template #myslot="slot">
<template v-slot:[dynamicSlotName]='msg'>
...
template>
这里的ynamicSlotName
会被作为一个 JavaScript
表达式进行动态求值,求得的值将会作为最终的参数来使用。 比如这里dynamicSlotName
最终的值为 default
则渲染出来的结果就是 v-slot:default=‘msg’
。