Vue在渲染函数createELement和JSX中使用插槽slot
Vue對于插槽有兩個(gè)專門的APIvm.$slots和vm.$scopedSlots,分別是普通插槽和作用域插槽,使用JSX語法或渲染函數(shù)的時(shí)候,定義插槽將使用上述兩個(gè)API。
渲染函數(shù)createElement
普通插槽和作用域插槽在定義上相差不大,但是在使用方法上略微有點(diǎn)區(qū)別,詳見渲染函數(shù)>數(shù)據(jù)對象
普通插槽,插槽內(nèi)容以children子節(jié)點(diǎn)形式,然后在數(shù)據(jù)對象中指定插槽名
// 定義帶插槽的組件,`$slots.default`為匿名插槽,其余的則是具名插槽,匿名插槽的插槽名可以省略 const MySlot = {render (h) {return h('div', [h('header', [this.$slots.header]),h('main', [this.$slots.header]),h('footer', [this.$slots.footer])])} }// 在`children子節(jié)點(diǎn)`中指定插槽名以使用具名插槽,未指定插槽名的則放入匿名插槽中 export default {components: { MySlot },render (h) {return h('MySlot', [h('template', { slot: 'header' }, 'hello world'),'children node',h('div', { slot: 'footer' }, 'this is footer')])} }作用域插槽,與普通插槽不同,作用域插槽的內(nèi)容直接放入渲染函數(shù)的數(shù)據(jù)對象中的
// 定義作用域插槽 const MySlot = {data () {return { user: 'John', content: 'vue', copytight: 'CopyRight' }},render (h) {return h('div', [h('header', [this.$scopedSlots.header({ user: this.user })]),h('main', [this.$scopedSlots.default({ content: this.content })]),h('footer', [this.$scopedSlots.footer({ copytight: this.copytight })])])} }// 要使用作用域插槽的數(shù)據(jù)內(nèi)容,則插槽必須在組件的數(shù)據(jù)對象`scopedSlots`中使用,如`header`所示 // 作用域插槽也可以當(dāng)作普通插槽使用,如`default`和`footer` export default {components: { MySlot },render (h) {return h('MySlot', {scopedSlots: {header: props => `hello, ${props.user}`}}, ['children node',h('div', { slot: 'footer' }, 'this is footer')])} }關(guān)于靜態(tài)插槽和作用域插槽:
你可以通過 this.$slots 訪問靜態(tài)插槽的內(nèi)容,每個(gè)插槽都是一個(gè) VNode 數(shù)組
也可以通過 this.$scopedSlots 訪問作用域插槽,每個(gè)作用域插槽都是一個(gè)返回若干 VNode 的函數(shù)
this.$slots 返回的是數(shù)組,this.$scopedSlots 返回的是函數(shù),這里踩一個(gè)坑,使用 this.$scopedSlots 定義的插槽如果未被使用則會報(bào)錯(cuò)
例如刪除或注釋掉具名插槽footer內(nèi)容后,控制臺報(bào)錯(cuò)
[Vue warn]: Error in render: "TypeError: this.$scopedSlots.footer is not a function"如何避免這個(gè)問題暫時(shí)沒有找到解決方案,研究還不夠深入
2021年1月25日補(bǔ)充:
使用 this.$scopedSlots 定義的插槽如果未被使用則會報(bào)錯(cuò)
原因: 以footer插槽為例,其實(shí)不用想的太復(fù)雜,作用域插槽this.$scopedSlots.footer()就是一個(gè)函數(shù),MySlot組件使用了這個(gè)函數(shù),但是父組件卻沒有傳入此函數(shù)的定義,所以MySlot再調(diào)用這個(gè)函數(shù)的時(shí)候發(fā)生報(bào)錯(cuò)。
解決辦法: 在MySlot調(diào)用this.$scopedSlots.footer()前進(jìn)行一次判斷此函數(shù)是否存在即可。
JSX語法
JSX是createElement的語法糖,在用法上沒有什么區(qū)別,對照著上面的內(nèi)容稍微改一改就好了
靜態(tài)插槽
const MySlot = {render (h) {return (<div><header>{this.$slots.header}</header><main>{this.$slots.default}</main><footer>{this.$slots.footer}</footer></div>)} }export default {render (h) {return (<MySlot><template slot='header'>hello world</template>children node<div slot='footer'>this is footer</div></MySlot>)} }作用域插槽
const MySlot = {data () {return { user: 'John', content: 'vue', copytight: 'CopyRight' }},render (h) {return (<div><header>{this.$scopedSlots.header({ user: this.user })}</header><main>{this.$scopedSlots.default({ content: this.content })}</main><footer>{this.$scopedSlots.footer({ copytight: this.copytight })}</footer></div>)} }export default {render (h) {return (<MySlotscopedSlots={{header: props => `hello, ${props.user}`}}>children node<div slot='footer'>this is footer</div></MySlot>)} }總結(jié)
以上是生活随笔為你收集整理的Vue在渲染函数createELement和JSX中使用插槽slot的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue-router和react-rou
- 下一篇: vue完全编程方式与react在书写和运