插槽的作用
讓用戶可以拓展組件,去更好地復(fù)用組件和對(duì)其做定制化處理。
Vue 實(shí)現(xiàn)了一套內(nèi)容分發(fā)的 API,將<slot>元素作為承載分發(fā)內(nèi)容的出口,這是vue文檔上的說(shuō)明。具體來(lái)說(shuō),slot就是可以讓你在組件內(nèi)添加內(nèi)容的‘空間’。
父組件在引用子組件時(shí)希望向子組價(jià)傳遞模板內(nèi)容<p>測(cè)試一下吧內(nèi)容寫在這里了能否顯示</p>?
子組件讓父組件傳過(guò)來(lái)的模板內(nèi)容在所在的位置顯示?
子組件中的<slot>就是一個(gè)槽,可以接收父組件傳過(guò)來(lái)的模板內(nèi)容,<slot> 元素自身將被替換?
<myslot></myslot>組件沒(méi)有包含一個(gè) <slot> 元素,則該組件起始標(biāo)簽和結(jié)束標(biāo)簽之間的任何內(nèi)容都會(huì)被拋棄
插槽的分類
vue 在 2.6 版本中,對(duì)插槽使用 v-slot 新語(yǔ)法,取代了舊語(yǔ)法的 slot 和 slot-scope,并且之后的 Vue 3.0 也會(huì)使用新語(yǔ)法,這并不是僅寫法的不同,還包括了性能的提升
插槽分為普通插槽和作用域插槽,普通插槽為父組件傳遞數(shù)據(jù)/元素/組件給子組件,而子組件定義 <slot> 接收,當(dāng)插槽有多個(gè)的時(shí)候,需要使用具名插槽 <slot name="xxx">,用于將數(shù)據(jù)綁定在指定的插槽
普通插槽
//??父組件
<template?v-slot>
??<p>new?Nian糕</p>
</template>
//?舊語(yǔ)法?只需一行:<p?slot>old?Nian糕</p>
//?子組件
<slot?/>
具名插槽
//?父組件
<template?v-slot:item>
??<p>new?Nian糕</p>
</template>
//?舊語(yǔ)法:<p?slot="item">old?Nian糕</p>
//?子組件
<slot?name="item"?/>
作用域插槽為子組件 <slot> 綁定屬性,傳遞數(shù)據(jù)給父組件,父組件通過(guò) v-slot:xxx="props" 接收子組件傳遞的屬性
作用域插槽 舊語(yǔ)法
//??父組件
<p?slot="love"?slot-scope="props">愛(ài)old?{{?props.name?}}真是太好了</p>
//?子組件
<slot?name="love"?v-bind="{?name?}"?/>
export?default?{
??data()?{
????return?{
??????name:?"Nian糕"
????}
??}
}
作用域插槽 新語(yǔ)法
//??父組件
<template?v-slot:love="props">
??<p>愛(ài)new?{{?props.name?}}真是太好了</p>
</template>
//?子組件
<slot?name="love"?v-bind="{?name?}"?/>
export?default?{
??data()?{
????return?{
??????name:?"Nian糕"
????}
??}
}
案例2
//子組件?:?(假設(shè)名為:ebutton)
<template>
????<div?class=?'button'>
????????<button>?test</button>
????????<slot?name=?'one'?:value1='child1'>?這就是默認(rèn)值1</slot>????//綁定child1的數(shù)據(jù)
????????<slot?:value2='child2'>?這就是默認(rèn)值2?</slot>??//綁定child2的數(shù)據(jù),這里我沒(méi)有命名slot
????</div>
</template>
<script>
new?Vue({
??el:'.button',
??data:{
????child1:'數(shù)據(jù)1',
????child2:'數(shù)據(jù)2'
??}
})
</script>
//父組件:(引用子組件?ebutton)
<template>
????<div?class=?'app'>
????????<ebutton>
????????????<template?v-slot:one?=?'slotone'>
????????????????{{?slotone.value1?}}????//?通過(guò)v-slot的語(yǔ)法?將子組件的value1值賦值給slotone
????????????</template>
????????????<template?v-slot:default?=?'slottwo'>
????????????????{{?slottwo.value2?}}??//?同上,由于子組件沒(méi)有給slot命名,默認(rèn)值就為default
????????????</template>
????????</ebutton>
????</div>
</template>
Vue3.0 slot簡(jiǎn)寫
<!--?父組件中使用?-->
?<template?v-slot:content="scoped">
???<div?v-for="item?in?scoped.data">{{item}}</div>
</template>
<!--?也可以簡(jiǎn)寫成:?-->
<template?#content="{data}">
????<div?v-for="item?in?data">{{item}}</div>
</template>
Vue3.0在JSX/TSX下如何使用插槽(slot)
先看看官方:https://github.com/vuejs/jsx-next/blob/dev/packages/babel-plugin-jsx/README-zh_CN.md#插槽
在 jsx 中,應(yīng)該使用 v-slots 代替 v-slot
const?A?=?(props,?{?slots?})?=>?(
??<div>
????<h1>{?slots.default???slots.default()?:?'foo'?}</h1>
????<h2>{?slots.bar?.()?}</h2>
??</div>
);
const?App?=?{
??setup()?{
????const?slots?=?{
??????bar:?()?=>?<span>B</span>,
????};
????return?()?=>?(
??????<A?v-slots={slots}>
????????<div>A</div>
??????</A>
????);
??},
};
//?or
const?App?=?{
??setup()?{
????const?slots?=?{
??????default:?()?=>?<div>A</div>,
??????bar:?()?=>?<span>B</span>,
????};
????return?()?=>?<A?v-slots={slots}?/>;
??},
};
//?or
const?App?=?{
??setup()?{
????return?()?=>?(
??????<>
????????<A>
??????????{{
????????????default:?()?=>?<div>A</div>,
????????????bar:?()?=>?<span>B</span>,
??????????}}
????????</A>
????????<B>{()?=>?"foo"}</B>
??????</>
????);
??},
};
上面代碼來(lái)源:Vue3.0在JSX/TSX下如何使用插槽(slot)https://www.cnblogs.com/pinkchampagne/p/14083724.html
關(guān)于jsx的,可以瞅瞅:vue3下jsx教學(xué),保證業(yè)務(wù)上手無(wú)問(wèn)題!https://juejin.cn/post/6911883529098002446
vue3 template與jsx寫法對(duì)比
ue template中的slot插槽如何在JSX中實(shí)現(xiàn)?和template對(duì)比,更加清晰
template寫法
子組件
<template>
????<div>
????????<span>I'm?Child</span>
????????<slot></slot>
????????<slot?name="header"></slot>
????</div>
</template>
<script>
export?default?{
????name:?"Test"
}
</script>
父組件
<template>
????<TestComponent>
????????<template?#default>
????????????<span>這是默認(rèn)插槽</span>
????????</template>
????????<template?#header>
????????????<span>這是header插槽</span>
????????</template>
????</TestComponent>
</template>
<script>
import?TestComponent?from?'./TestComponent'
export?default?{
????name:?"Parent",
????components:?{
????????TestComponent
????}
}
</script>
JSX的寫法:
子組件
import?{?defineComponent?}?from?"@vue/runtime-core";
export?default?defineComponent({
????name:?"Test",
????render()?{
????????return?(
????????????<>
????????????????<span>I'm?Child</span>
????????????????{?this.$slots.default?.()?}
????????????????{?this.$slots.header?.()?}
????????????</>
????????)
????}
})
作用域插槽
import?{?defineComponent?}?from?"@vue/runtime-core";
export?default?defineComponent({
????name:?"Test",
????setup()?{
????????return?{
????????????value:?{
????????????????name:?'xzw'
????????????}
????????}
????},
????render()?{
????????return?(
????????????<>
????????????????<span>I'm?Child</span>
????????????????{?this.$slots.content?.(this.value)?}
????????????</>
????????)
????}
})
父組件
import?{?defineComponent?}?from?'vue'
import?TestComponent?from?'./TestComponent'
export?default?defineComponent({
????name:?"Test",
????components:?{
????????TestComponent
????},
????render()?{
????????return?(
????????????<TestComponent?v-slots={{
????????????????default:?()?=>?(
????????????????????<div>這是默認(rèn)插槽</div>
????????????????),
????????????????header:?()?=>?(
????????????????????<div>這是header插槽</div>
????????????????)
????????????}}>
????????????</TestComponent>
????????)
????}
})
作用域插槽
import?{?defineComponent?}?from?'vue'
import?TestComponent?from?'./TestComponent'
export?default?defineComponent({
????name:?"Test",
????components:?{
????????TestComponent
????},
????render()?{
????????return?(
????????????<TestComponent?v-slots={{
????????????????content:?scope?=>?(?<div>{scope.name}</div>)
????????????}}>
????????????</TestComponent>
????????)
????}
})
參考文章:
Vue3中的 JSX 以及 jsx插槽的使用https://juejin.cn/post/6983130251702304781
Vue3 中插槽(slot)的用法?https://www.cnblogs.com/recode-hyh/p/14544808.html
vue3 學(xué)習(xí) 之 vue3使用?http://www.itdecent.cn/p/91328e6934c9
【vue3】 使用JSX實(shí)現(xiàn)普通、具名和作用域插槽?https://blog.csdn.net/qq_24719349/article/details/116724681
轉(zhuǎn)載本站文章《vue2升級(jí)vue3:Vue2/3插槽——vue3的jsx組件插槽slot怎么處理》,
請(qǐng)注明出處:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8683.html