前言:v-slot 指令自 2.6.0 起被引入,提供更好的支持 slot 和 slot-scope 特性的 API 替代方案。在接下来所有的 2.x 版本中 slot 和 slot-scope 特性仍会被支持,但已经被官方废弃且不会出现在 Vue 3 中。
①内容:假如父组件需要在子组件内放一些DOM,那么这些DOM是显示、不显示、在哪个地方显示、如何显示,就是slot分发负责的活
②默认情况下,该组件起始标签和结束标签之间的任何内容都会被抛弃
//父组件 <template> <div id="app"> <son>我想显示点内容</son> </div> </template> //子组件 <template> <div> <span>我是子组件</span> </div> </template>
③单个slot:当父组件需要显示一些东西在子组件里时,只需要将这个<slot>放置于子组件想要显示的地方即可,若没有name,则为默认插槽(匿名插槽),一个不带name
的<slot>
出口会带有隐含的名字“default”。
//父组件 <template> <div id="app"> <son>
<div>我显示出来了</div>
</son> </div> </template> //子组件 <template> <div> <p><slot></slot></p> <p>我是子组件</p> </div> </template>
上述代码中父组件等同于下面的代码,两者之间的区别是是否将隐含的“default”写出来
//父组件 <template> <div id="app"> <son> <div slot="default">我显示出来了</div> </son> </div> </template>
④多个slot:当需要多个插槽显示在不同的地方时,需要给每个插槽加上一个name,并且父组件内加上"slot=name",使两者之间具有有关联性,这就是具名插槽
//父组件 <template> <div id="app"> <son> <div slot="slotOne">我是插槽一</div> <div slot="slotTwo">我是插槽二</div> <div slot="slotThree">我是插槽三</div> </son> </div> </template> //子组件 <template> <div> <p><slot name="slotOne"></slot></p> <p><slot name="slotTwo"></slot></p> <p class="content">我是子组件</p> <p><slot name="slotThree"></slot></p> </div> </template>
注:多个插槽也能有且最多只能一个默认插槽
⑤当没有对应插槽的name时
1)插槽里没有默认的内容,则会什么的都不输出
//父组件 <template> <div id="app"> <son> <div>我想插入进去</div> </son> </div> </template> //子组件 <template> <div> <p class="content">我是子组件</p> <p><slot name="slotOne"></slot></p> </div> </template>
2)插槽内有默认内容,则会直接输出插槽内的内容
//父组件 <template> <div id="app"> <son> <div>我想插入进去</div> </son> </div> </template> //子组件 <template> <div> <p class="content">我是子组件</p> <p><slot name="slotOne">没有对应name时,我会显示</slot></p> </div> </template>
⑥当具名插槽和默认插槽混合使用的时候,任何没有包裹slot(或者slot="default")的都将视为默认插槽的内容,对于包裹相同slot值的标签会渲染在同一个位置
//父组件 <template> <div id="app"> <son> <div>匿名插槽第一段内容</div> <div slot="slotOne">相同具名一</div> <div>匿名插槽第二段内容</div> <div slot="slotOne">相同具名二</div> 匿名插槽第三段内容 </son> </div> </template> //子组件 <template> <div> <p style="border:1px solid #0ff"><slot></slot></p> <p style="border:1px solid #f00"><slot name="slotOne"></slot></p> </div> </template>
本文所有作用域插槽,子组件里news的数据
<script> export default { name: "name", data(){ return{ news:[ ‘十九届四中全会28日至31日在京召开‘, ‘珍爱和平团结合作 构建人类命运共同体‘, ‘法治是最好的营商环境‘, ‘夯实优化营商环境的法治基石‘, ‘中国营商环境全球排名再前进15名!‘ ], } } } </script>
①作用域插槽或者说是一个带数据的插槽
//父组件 <template> <div id="app"> <son> <template slot="news" slot-scope="newsData"> <ul> <li v-for="(item,index) in newsData.newsList" :key="index">{{item}}</li> </ul> </template> </son> </div> </template> //子组件 <template> <div> <p class="content">我是子组件</p> <p><slot name="news" :newsList = ‘news‘></slot></p> </div> </template>
这里有小坑:
1)这里的 slot-scope
声明了被接收的 prop 对象会作为 newData
变量存在于 <template>
作用域中。你可以像命名 JavaScript 函数参数一样随意命名 newData
。
2)这时的newData数据结构为:
newsData:{ newsList:[ ‘十九届四中全会28日至31日在京召开‘, ‘珍爱和平团结合作 构建人类命运共同体‘, ‘法治是最好的营商环境‘, ‘夯实优化营商环境的法治基石‘, ‘中国营商环境全球排名再前进15名!‘ ] }
3)slot-scope
特性也可以直接用于非 <template>
元素
<template> <div id="app"> <son> <div slot="news" slot-scope="newsData"> <ul> <li v-for="(item,index) in newsData.newsList" :key="index">{{item}}</li> </ul> </div> </son> </div> </template>
②slot-scope接收到的值也可以使用ES6解构
<template> <div id="app"> <son> <div slot="news" slot-scope="{news}"> <ul> <li v-for="(item,index) in news" :key="index">{{item}}</li> </ul> </div> </son> </div> </template>
重点来了,v-slot是 v2.6.0 引入的新的指令,目的是为了更好的支持slot、slot-scope的特性(其实就是把两个统一起来),新人上位,老人就应该退居幕后,并辅佐一段时间,所以slot、slot-scope在v2.6.0正式废弃(后续的2.x版本依旧支持,但不推荐),在将来的v3.x版本中正式废除(就是3.x版本不支持不能用了)
①默认插槽写法和以前没什么变化,v-slot主要针对具名插槽、作用域插槽
②具名插槽,v-slot:name
//父组件 <template> <div id="app"> <son> <template v-slot:slotOne>我想显示一点内容</template> </son> </div> </template> //子组件 <template> <div> <p><slot name="slotOne"></slot></p> </div> </template>
这里有小坑
1)除独占默认插槽的缩写语法外,v-slot
只能添加在一个 <template>
上
③作用域插槽,v-slot:name = customName
绑定在 <slot>
元素上的特性被称为插槽 prop。现在在父级作用域中,我们可以给 v-slot
带一个值来定义我们提供的插槽 prop 的名字
//父组件 <template> <div id="app"> <son> <template v-slot:news = "newsData"> <ul> <li v-for="(item,index) in newsData.newsList" :key="index"> {{index}}、{{item}} </li> </ul> </template> </son> </div> </template> //子组件 <template> <div> <p><slot name="news" :newsList = ‘news‘></slot></p> </div> </template>
在这个例子中,我们选择将包含所有插槽 prop 的对象命名为 newsData
,但你也可以使用任意你喜欢的名字。
④作用域插槽支持ES6解构
将上述例子中父组件改一下
<template> <div id="app"> <son> <template v-slot:news = "{newsList}"> <ul> <li v-for="(item,index) in newsList" :key="index"> {{index}}、{{item}} </li> </ul> </template> </son> </div> </template>
⑤独占默认插槽的缩写语法
当子组件内只有默认插槽时,组件的标签可以被当作插槽的模板来使用。这样我们就可以把 v-slot
直接用在组件上
//父组件 <template> <div id="app"> <son v-slot="{news}"> <ul> <li v-for="(item,index) in news" :key="index"> {{item}} </li> </ul> </son> </div> </template> //子组件 <template> <div> <p><slot :news="news"></slot></p> </div> </template>
这里有小坑
1)当子组件内只有默认插槽时,可以省略default,写作:v-slot = customName
2)当子组件内只有默认插槽时,如果v-slot也准备使用缩写时(#),default不能被省略,写作:#default = customName
⑥独占默认插槽的缩写语法不能与具名插槽混合使用
//父组件 <template> <div id="app"> <son v-slot="{news}"> <ul> <li v-for="(item,index) in news" :key="index"> {{item}} </li> </ul> <div v-slot:mixinSlot>默认插槽的缩写语法和具名插槽混用,导致作用域不明确</div> </son> </div> </template> //子组件 <template> <div> <p><slot :news="news"></slot></p> <p><slot name="mixinSlot"></slot></p> </div> </template>
⑦动态插槽名,用来来定义动态的插槽名
在v2.6.0版本中新增动态参数,可以用方括号([])括起来的 JavaScript 表达式作为一个指令的参数,动态参数我将在另一篇文章叙述
//父组件 <template> <div id="app"> <son> <template v-slot:[slotName] =‘{ news }‘> <ul> <li v-for="(item,index) in news" :key="index">{{item}}</li> </ul> </template> </son> </div> </template> <script> import son from "./components/son"; export default { name: "App", components: { son }, data(){ return{ isOK: false } }, computed: { slotName(){ return this.isOK ? ‘slot1‘ : ‘slot2‘ } }, }; </script> //子组件 <template> <div> <slot name="slot1" :news=‘news‘></slot> <slot name="slot2" :news=‘news2‘></slot> </div> </template> <script> export default { name: "name", data() { return { news: [ "十九届四中全会28日至31日在京召开", "珍爱和平团结合作 构建人类命运共同体", "法治是最好的营商环境", "夯实优化营商环境的法治基石", "中国营商环境全球排名再前进15名!" ], news2: [ ‘27省份前三季度GDP出炉 16省份GDP增速跑赢全国‘, ‘新航季来了!这些航班将飞大兴机场,坐飞机别走错‘, ‘北方回暖南方雨连绵 江南等多地气温将创新低‘, ‘水润民心 脱贫路上“领头雁” 钟声‘, ‘看看第六届世界互联网大会国际组织说了啥‘ ] }; } }; </script>
印象中,好像没什么地方需要用到动态插槽名,如果有大大遇到需要使用,还请留言,非常感谢,上述栗子如果用v-if,语义更明朗
⑧v-slot缩写为:#
具名插槽缩写为:#name
作用域插槽缩写
1)当为匿名作用域插槽时:#default = customName(#=customName这种写法为报错)
2)当为具名作用域插槽时:#name = customName
原文:https://www.cnblogs.com/bulici/p/11733840.html