插槽的作用
讓用戶可以拓展組件眷射,去更好地復用組件和對其做定制化處理镇辉。
Vue 實現(xiàn)了一套內(nèi)容分發(fā)的 API词身,將<slot>元素作為承載分發(fā)內(nèi)容的出口厅目,這是vue文檔上的說明。具體來說,slot就是可以讓你在組件內(nèi)添加內(nèi)容的‘空間’损敷。
父組件在引用子組件時希望向子組價傳遞模板內(nèi)容<p>測試一下吧內(nèi)容寫在這里了能否顯示</p>?
子組件讓父組件傳過來的模板內(nèi)容在所在的位置顯示?
子組件中的<slot>就是一個槽葫笼,可以接收父組件傳過來的模板內(nèi)容,<slot> 元素自身將被替換?
<myslot></myslot>組件沒有包含一個 <slot> 元素拗馒,則該組件起始標簽和結(jié)束標簽之間的任何內(nèi)容都會被拋棄
插槽的分類
vue 在 2.6 版本中路星,對插槽使用 v-slot 新語法,取代了舊語法的 slot 和 slot-scope诱桂,并且之后的 Vue 3.0 也會使用新語法洋丐,這并不是僅寫法的不同,還包括了性能的提升
插槽分為普通插槽和作用域插槽挥等,普通插槽為父組件傳遞數(shù)據(jù)/元素/組件給子組件友绝,而子組件定義 <slot> 接收,當插槽有多個的時候肝劲,需要使用具名插槽 <slot name="xxx">迁客,用于將數(shù)據(jù)綁定在指定的插槽
普通插槽
//??父組件
<template?v-slot>
??<p>new?Nian糕</p>
</template>
//?舊語法?只需一行:<p?slot>old?Nian糕</p>
//?子組件
<slot?/>
具名插槽
//?父組件
<template?v-slot:item>
??<p>new?Nian糕</p>
</template>
//?舊語法:<p?slot="item">old?Nian糕</p>
//?子組件
<slot?name="item"?/>
作用域插槽為子組件 <slot> 綁定屬性,傳遞數(shù)據(jù)給父組件辞槐,父組件通過 v-slot:xxx="props" 接收子組件傳遞的屬性
作用域插槽 舊語法
//??父組件
<p?slot="love"?slot-scope="props">愛old?{{?props.name?}}真是太好了</p>
//?子組件
<slot?name="love"?v-bind="{?name?}"?/>
export?default?{
??data()?{
????return?{
??????name:?"Nian糕"
????}
??}
}
作用域插槽 新語法
//??父組件
<template?v-slot:love="props">
??<p>愛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'>?這就是默認值1</slot>????//綁定child1的數(shù)據(jù)
????????<slot?:value2='child2'>?這就是默認值2?</slot>??//綁定child2的數(shù)據(jù)掷漱,這里我沒有命名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?}}????//?通過v-slot的語法?將子組件的value1值賦值給slotone
????????????</template>
????????????<template?v-slot:default?=?'slottwo'>
????????????????{{?slottwo.value2?}}??//?同上,由于子組件沒有給slot命名催蝗,默認值就為default
????????????</template>
????????</ebutton>
????</div>
</template>
Vue3.0 slot簡寫
<!--?父組件中使用?-->
?<template?v-slot:content="scoped">
???<div?v-for="item?in?scoped.data">{{item}}</div>
</template>
<!--?也可以簡寫成:?-->
<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>
??????</>
????);
??},
};
上面代碼來源:Vue3.0在JSX/TSX下如何使用插槽(slot)https://www.cnblogs.com/pinkchampagne/p/14083724.html
關(guān)于jsx的,可以瞅瞅:vue3下jsx教學丙号,保證業(yè)務(wù)上手無問題先朦!https://juejin.cn/post/6911883529098002446
vue3 template與jsx寫法對比
ue template中的slot插槽如何在JSX中實現(xiàn)?和template對比犬缨,更加清晰
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>這是默認插槽</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>這是默認插槽</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 學習 之 vue3使用?http://www.reibang.com/p/91328e6934c9
【vue3】 使用JSX實現(xiàn)普通喳魏、具名和作用域插槽?https://blog.csdn.net/qq_24719349/article/details/116724681
轉(zhuǎn)載本站文章《vue2升級vue3:Vue2/3插槽——vue3的jsx組件插槽slot怎么處理》,
請注明出處:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8683.html