vue2升級(jí)vue3:Vue2/3插槽——vue3的jsx組件插槽slot怎么處理

插槽的作用

讓用戶可以拓展組件,去更好地復(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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容