Vue slot插槽作用與原理深入講解
前言
在2.6.0中,具名插槽 和 作用域插槽 引入了一個(gè)新的統(tǒng)一的語(yǔ)法 (即v-slot 指令)。它取代了 slot 和 slot-scope。
什么是Slot
當(dāng)我們生成好組件模板后,為了方便用戶(hù)在調(diào)用組件的時(shí)候自定義組件內(nèi)部分元素的樣式或內(nèi)容。于是在設(shè)計(jì)組件模板的時(shí)候會(huì)挖一個(gè)坑,等待用戶(hù)使用v-slot來(lái)替換坑的slot位置。
栗子
// father.vue <template> <div> <child> <h1>AAAA</h1> </child> </div> </template>
<template> <div> <p>這里是子組件哦</p> <slot></slot> </div> </template>
可以看見(jiàn) <h1>AAAA</h1>被 插入到child的里面。
除了可以插入HTML模板代碼外,你也可以插入普通文本、其他組件、本組件的數(shù)據(jù)。
在插槽中使用數(shù)據(jù)
// father.vue <template> <div> <child> {{testName}} <h1>AAAA</h1> </child> </div> </template> <script> ... testName = 'Test101'; ... </script>
插槽可以使用當(dāng)前引用子組件的組件數(shù)據(jù),但是不能引用傳遞給子組件的數(shù)據(jù)。
// father.vue <template> <div> <child :childName="testName"> {{ childName }} <h1>AAAA</h1> </child> </div> </template> <script> ... testName = 'Test101'; ... </script>
// child.vue <template> <div> <p>這里是子組件{{ childName }}</p> <slot></slot> </div> </template> <script> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component() export default class AAChild extends Vue { @Prop() childName; } </script>
這里是獲取不到childName的,因?yàn)檫@個(gè)值是傳給<child>的
備胎插槽
// father.vue <div> <child :childName="testName"> </child> </div>
// child.vue <div> <p>這里是子組件{{ childName }}</p> <slot> 我是備胎 </slot> </div>
給插槽設(shè)置一個(gè)具體的默認(rèn)內(nèi)容,當(dāng)別的組件沒(méi)有給你內(nèi)容的時(shí)候,那么默認(rèn)的內(nèi)容就會(huì)被渲染。如果我們提供內(nèi)容,那么默認(rèn)的插槽內(nèi)容會(huì)被我們的內(nèi)容覆蓋。
具名插槽
當(dāng)我們一個(gè)組件里需要定義多個(gè)插槽時(shí),需要使用slot元素的特性name來(lái)定義額外的插槽。
// child.vue <template> <div> <p>插槽一的位置</p> <slot name="slot1"> </slot> <p>------------------------</p> <p>插槽二的位置</p> <slot> </slot> <p>------------------------</p> <p>插槽三的位置</p> <slot name="slot3"> </slot> </div> </template>
// father.vue <child> <template v-slot:slot1> <h1>slotOne</h1> </template> <template> <h1>slotTwo</h1> </template> <template v-slot:slot3> <h1>slotThree</h1> </template> </child>
如果一個(gè)<slot>不帶name屬性的話,那么它的name默認(rèn)為default,可以不用v-slot去指定它。(如果你非要折騰,也可以寫(xiě)name="default")
在向具名插槽提供內(nèi)容的時(shí)候,我們可以在<template>元素上使用v-slot指令,并以參數(shù)的形式提供其名稱(chēng)。
注:v-slot只能添加在一個(gè)<template>上,(只有一種例外情況,下面會(huì)說(shuō))
覆蓋問(wèn)題
當(dāng)存在同名的v-slot的時(shí)候,后面會(huì)覆蓋前面的。
當(dāng)存在兩個(gè)匿名的插槽的時(shí)候,兩者都會(huì)被丟進(jìn)去默認(rèn)插槽里。
只更改了father.vue
// father.vue <child> <template v-slot:slot1> <h1>slotOne</h1> </template> <template> <h1>slotTwo</h1> </template> <template v-slot:slot3> <h1>slotThree</h1> </template> <template v-slot:slot3> <h1>slotThreeAAAAAAAAA</h1> </template> <template> <h1>slotTwoAAAAAAAAAAAA</h1> </template> </child>
作用域插槽
插槽跟模板其他地方一樣都可以訪問(wèn)當(dāng)前father組件的作用域而不能訪問(wèn)<child>的作用域
如果要訪問(wèn)child的作用域該怎么辦呢?
// child.vue <template> <div> <p>下面有一個(gè)插槽</p> <slot :aName="name"></slot> </div> </template> <script> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component() export default class AAChild extends Vue { name = '123'; } </script>
// father.vue <template> <div> <child> <template v-slot:default="slotProps"> <h1>{{ slotProps.aName }}</h1> </template> </child> </div> </template>
v-slot:default="slotProps"接住了child組件里在slot元素上綁定的作用域?qū)傩?,同時(shí)吧template只想了默認(rèn)插槽。
具名插槽的作用域
// father.vue <template> <div> <child> <template v-slot:default="slotProps"> <h1>{{ slotProps.aName }}</h1> </template> <template v-slot:slotA="slotProps"> <h1>{{ slotProps.nameA }}</h1> </template> </child> </div> </template>
// child.vue <template> <div> <p>下面有一個(gè)插槽</p> <slot :aName="name"></slot> <slot :nameA="nameA" name="slotA"></slot> </div> </template> <script> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component() export default class AAChild extends Vue { name = '123'; nameA = '321'; } </script>
過(guò)時(shí)的寫(xiě)法:
<template slot="custom" slot-scope="item"></template >
現(xiàn)在的寫(xiě)法:
<template v-slot:custom="{item}"></template >
解構(gòu)插槽Prop
v-slot 的值實(shí)際上可以是任何能夠作為函數(shù)定義中的參數(shù)的 JS 表達(dá)式(作用域插槽 的內(nèi)部工作原理是將你的插槽內(nèi)容包括在一個(gè)傳入單個(gè)參數(shù)的函數(shù)里)
// child.vue <template> <div> <p>下面有一個(gè)插槽</p> <slot :nameData="nameObj"></slot> </div> </template> <script> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component() export default class AAChild extends Vue { nameObj = { name: '插槽君', key: '202203241567', }; } </script>
// father.vue <template> <div> <child> <template v-slot="slotProps"> <h1>{{ slotProps.nameData.name }}</h1> </template> </child> </div> </template>
father,vue可以改寫(xiě)為
// father.vue <template> <div> <child> <template v-slot="{ nameData }"> <h1>{{ nameData.name }}</h1> </template> </child> </div> </template>
這樣可以使模板更簡(jiǎn)潔。
具名插槽的縮寫(xiě)
跟 v-on 和 v-bind 一樣,v-slot 也有縮寫(xiě),即把參數(shù)之前的所有內(nèi)容 (v-slot:) 替換為字符 #。例如 v-slot:header 可以被重寫(xiě)為 #header:
// father.vue <template> <div> <child> <template v-slot:keyDDD="{ nameData }"> <h1>{{ nameData.name }}</h1> </template> </child> </div> </template>
等同于
// father.vue <template> <div> <child> <template #keyDDD="{ nameData }"> <h1>{{ nameData.name }}</h1> </template> </child> </div> </template>
$scopedSlots
和slot-scope 的區(qū)別?
- 作用相同:都是作用域插槽
- 場(chǎng)景不同:slot-scope 是模板語(yǔ)法,scopedSlots 則是編程式語(yǔ)法
- 使用不同:在 <template> 中使用 slot-scope,在 render() 函數(shù)中使用 scopedSlots
<template v-if="$scopedSlots.label" v-slot:title="{ data }"> <slot name="label" :data="data" > </slot> </template>
或者
render() { return this.$scopedSlots.default ? this.$scopedSlots.default(this.title) : null; }
到此這篇關(guān)于Vue slot插槽作用與原理深入講解的文章就介紹到這了,更多相關(guān)Vue slot插槽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+element+electron仿微信實(shí)現(xiàn)代碼
這篇文章主要介紹了vue+element+electron仿微信實(shí)現(xiàn),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12Vue中v-for的數(shù)據(jù)分組實(shí)例
下面小編就為大家分享一篇Vue中v-for的數(shù)據(jù)分組實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03vue路由$router.push()使用query傳參的實(shí)際開(kāi)發(fā)使用
在vue項(xiàng)目中我們用函數(shù)式編程this.$router.push跳轉(zhuǎn),用query傳遞一個(gè)對(duì)象時(shí)要把這個(gè)對(duì)象先轉(zhuǎn)化為字符串,然后在接收的時(shí)候要轉(zhuǎn)化為對(duì)象,下面這篇文章主要給大家介紹了關(guān)于vue路由$router.push()使用query傳參的實(shí)際開(kāi)發(fā)使用,需要的朋友可以參考下2022-11-11vue+elementUI實(shí)現(xiàn)多文件上傳與預(yù)覽功能實(shí)戰(zhàn)記錄(word/PDF/圖片/docx/doc/xlxs/txt)
這篇文章主要給大家介紹了關(guān)于利用vue+elementUI實(shí)現(xiàn)多文件上傳與預(yù)覽功能的相關(guān)資料,包括word/PDF/圖片/docx/doc/xlxs/txt等格式文件上傳,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08使用VUE實(shí)現(xiàn)一鍵復(fù)制內(nèi)容功能
這篇文章主要介紹了使用VUE實(shí)現(xiàn)一鍵復(fù)制內(nèi)容功能,功能就是當(dāng)我們點(diǎn)擊復(fù)制按鈕時(shí),會(huì)提示“復(fù)制成功”,這樣復(fù)制的內(nèi)容就可以在其他地方使用了,感興趣的朋友可以學(xué)習(xí)一下2023-04-04vue內(nèi)點(diǎn)擊url下載文件的最佳解決方案分享
這篇文章主要給大家介紹了關(guān)于vue內(nèi)點(diǎn)擊url下載文件的最佳解決方案,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02Vue3?$emit用法指南(含選項(xiàng)API、組合API及?setup?語(yǔ)法糖)
這篇文章主要介紹了Vue3?$emit用法指南,使用?emit,我們可以觸發(fā)事件并將數(shù)據(jù)傳遞到組件的層次結(jié)構(gòu)中,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07