vue3中的render函數(shù)里定義插槽和使用插槽
render函數(shù)里定義插槽和使用插槽
vue3中this.slots和vue2的區(qū)別
vue3:this.slots是一個{ [name: string]: (…args: any[]) => Array | undefined }的對象,每個具名插槽的內(nèi)容都要通過函數(shù)調(diào)用。如v-slot:foo插槽分發(fā)的內(nèi)容通過this.slots.foo( )返回
vue2:this.slots是一個{ [name: string]: ?Array }的對象,v-slot:foo的內(nèi)容通過this.slots.foo來訪問 , 而this.scopedSlots才是和vue3里的this.$slots作用一樣.
定義插槽
this.$slots.[插槽名] 這個一個返回VNode數(shù)組的函數(shù),用于訪問靜態(tài)插槽內(nèi)容.
const BlogPost = defineComponent({ render(){ return h('div', [ h('h1',this.$slots.header&&this.$slots.header()||'默認header插槽'), h('p',this.$slots.default&&this.$slots.default({message:'我是作用域插槽的message'})||'默認default插槽'), h('h4',this.$slots.footer&&this.$slots.footer()||'默認footer插槽'), ]) } })
// 以上代碼相當于以下的template <template> <div> <h1> <slot name="header">默認header插槽</slot> </h1> <p> <slot>默認default插槽</slot> </p> <h4> <slot name="footer">默認footer插槽</slot> </h4> </div> </template>
定義有插槽的組件使用插槽
在h函數(shù)的第三個參數(shù)中使用{ [name: string]: (…args: any[]) => Array | undefined }形式的對象來定義組件的具體插槽內(nèi)容
const BlogPostWrapper = defineComponent({ ? render(){ ? ? return h('div', ? ? ? ? ? ? ?{style:'background:skyblue'}, ? ? ? ? ? ? ?h( ? ? ? ?? ??? ??? ?BlogPost, ? ? ? ? ? ? ? ??? ?null, ? ? ? ? ? ? ? ??? ?{ ? ? ? ? ? ? ? ? ? header(props){ ? ? ? ? ? ? ? ? ? ? return '我是傳進的header插槽內(nèi)容' ? ? ? ? ? ? ? ? ? }, ? ? ? ?? ??? ??? ? ?default(props){ ? ? ? ?? ??? ??? ? ?// 這里的props就是作用域插槽的插槽prop ? ? ? ? ? ? ? ? ? ? return 'BlogPostWrapper的default插槽內(nèi)容::>>'+props.message ? ? ? ? ? ? ? ? ? }, ? ? ? ? ? ? ? ? ? footer(props){ ? ? ? ? ? ? ? ? ? ? return '我是傳進的footer插槽內(nèi)容' ? ? ? ? ? ? ? ? ? } ? ? ?? ??? ??? ?} ? ? ?? ??? ?) ? ? ? ? ? ) ? ?? ?} })
// 相當于template <template> ?? ?<div> ?? ??? ?<BlogPost> ?? ??? ??? ?<tempalte #header>'我是傳進的header插槽內(nèi)容'</tempalte> ?? ??? ??? ?<tempalte #default="props"> ?? ??? ??? ??? ?{{'BlogPostWrapper的default插槽內(nèi)容::>>'+props.message}} ?? ??? ??? ?</tempalte> ?? ??? ??? ?<tempalte #footer>我是傳進的footer插槽內(nèi)容</tempalte> ?? ??? ?</BlogPost> ?? ?</div> </template>
vue3 render函數(shù)小變動
Render function API?是不是感覺有點陌生?那恭喜你,這個改動不會對你這位 <template> 用戶造成影響。
老規(guī)矩,上帝視角看一下:
h
需要從全局導入進來(不再是 render 函數(shù)的參數(shù)了)render
函數(shù)的參數(shù)改變了(為了在常規(guī)組件和函數(shù)組件中表現(xiàn)一致)VNodes
具備了扁平的屬性結構
render函數(shù)的參數(shù)
2.x 這么寫
在 Vue 2.x 的版本中,render 函數(shù)會以參數(shù)的形式自動接收 h 函數(shù)(aka:createElement):
export default { render(h) { return h('div'); } }
3.x 應該這么寫
在即將到來的 Vue 3.x 版本中,h 函數(shù)需要手動從全局引入進來:
import { h } from 'vue'; export default { render() { return h('div'); } }
render函數(shù)簽名
2.x 這么寫
上面也提到了,2.x 的 render 函數(shù)會自動接收 h 作為參數(shù):
export default { render(h) { return h('div'); } }
3.x 應該這么寫
在 3.x 版本中,render 函數(shù)不再接收任何參數(shù)了,它僅存的主要作用就是在 setup 函數(shù)中使用。這樣方便獲取作用域鏈中的響應式狀態(tài)以及各種函數(shù),當然了,也方便獲取任何傳遞給 setup 函數(shù)的參數(shù)。
import { h, reactive } from 'vue'; export default { setup(props, { slots, attrs, emit }) { const state = reactive({ count: 0 }); function increment() { state.count++ } // 返回一個 render 函數(shù) return () => { h( 'div', { onClick: increment, }, state.count, ) } } }
VNode屬性格式
2.x 是這樣的
domProps 是 VNode 屬性中的一個“嵌套列表”:
{ class: ['button', 'confirm-button'], style: { color: 'red' }, attrs: { id: 'confirm' }, domProps: { innerHTML: '' }, on: { click: confirmCreate }, key: 'submit-button', }
3.x 中則是這樣的
在 3.x 版本中,VNode 的所有屬性都已經(jīng)實現(xiàn)了“扁平化”的處理:
{ class: ['button', 'confirm-button'], style: { color: 'red' }, id: 'submit', innerHTML: '', onClick: confirmCreate, key: 'submit-button', }
其實我也很少用 render 函數(shù),畢竟 template 還是蠻香的。
如果想要獲得更多的詳細信息,請去這里:v3.vuejs.org/guide/migration/render-function-api.html(目前還沒有中文版)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
vue實現(xiàn)token過期自動跳轉(zhuǎn)到登錄頁面
本文主要介紹了vue實現(xiàn)token過期自動跳轉(zhuǎn)到登錄頁面,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10