前言:v-slot 指令自 2.6.0 起被引入,提供更好的支持 slot 和 slot-scope 特性的 API 替代方案。在接下来全部的 2.x 版本中 slot 和 slot-scope 特性仍会被支持,但已经被官方废弃且不会出如今 Vue 3 中。数据结构
①内容:假如父组件须要在子组件内放一些DOM,那么这些DOM是显示、不显示、在哪一个地方显示、如何显示,就是slot分发负责的活app
②默认状况下,该组件起始标签和结束标签之间的任何内容都会被抛弃函数
//父组件 <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”写出来this
//父组件 <template> <div id="app"> <son> <div slot="default">我显示出来了</div> </son> </div> </template>
④多个slot:当须要多个插槽显示在不一样的地方时,须要给每一个插槽加上一个name,而且父组件内加上"slot=name",使二者之间具备有关联性,这就是具名插槽spa
//父组件 <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>
注:多个插槽也能有且最多只能一个默认插槽code
⑤当没有对应插槽的name时component
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)插槽内有默认内容,则会直接输出插槽内的内容blog
//父组件 <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