詳解vue3中渲染函數的非兼容變更

渲染函數API變更

此更改不會影響到<template>用戶

  • h現在全局導入,而非作為參數傳遞給渲染函數
  • 渲染函數參數更改為在有狀態組件和函數組件之間更加一致
  • vnode現在又一個扁平的prop結構

Render函數參數 

// 2.0 渲染函數
export default {
 render(h) {
  return h('div')
 }
}

// 3.x語法
export default {
 render() {
  return h('div')
 }
}

渲染函數簽名更改

// 2.x
export default {
 render(h) {
  return h('div')
 }
}

// 3.x
import { h, reactive } from 'vue'
export default {
 setup(prop, {slots, attrs, emit}) {
  const state = reactive({
   count: 0
  })
  function increment() {
   state.count++
  }
  // 返回render函數
  return () => h(
   'div',
   {
    onClick: increment
   },
   state.count
  )
 }
}

VNode Props 格式化

// 2.x
{
 class: ['button', 'is-outlined'],
 style: {color: '#fffff'},
 attr: {id: 'submit'},
 domProps: {innerHTML: ''},
 on: {click: submitForm},
 key: 'submit-button'
}
// 3.x VNode的結構是扁平的
{
 class: ['button', 'is-outlined'],
 style: { color: '#34495E' },
 id: 'submit',
 innerHTML: '',
 onClick: submitForm,
 key: 'submit-button'
}

slot統一

更改瞭普通slot和作用域slot

  • this.$slots現在將slots作為函數公開
  • 移除this.$scopedSlots
// 2.x
h(LayoutComponent, [
 h('div', {slot: 'header'}, this.header),
 h('div', {slot: 'header'}, this.header)
])
// 作用域slot:


// 3.x
h(LayoutComponent, {}, {
 header: () => h('div', this.header),
 content: () => h('div', this.content)
})
// 需要以編程方式引入作用域slot時,他們現在被統一在瞭$slots選項中
// 2.x的作用域slot
this.$scopedSlots.header
// 3.x的寫法
this.$slots.header

移除$listeners

$listeners對象在vue3中已經移除,現在事件監聽器是$attrs的一部分

在vue2中,可以使用this.attrs和this.attrs和this.listeners分別訪問傳遞給組件的attribute和時間監聽器,結合inheritAttrs: false,開發者可以將這些attribute和監聽器應用到其他元素,而不是根元素

<template>
<label>
 <input type="text" v-bind="$attrs" v-on="$listeners">
</label>
</template>
<script>
 export default {
  inheritAttrs: false
 }
</script>

在vue的虛擬DOM中,事件監聽器現在隻是以on為前綴的attribute,這樣就成瞭attrs對象的一部分,這樣attrs對象的一部分,這樣listeners就被移除瞭

<template>
 <label>
  <input type="text" v-bind="$attrs" />
 </label>
</template>
<script>
export default {
 inheritAttrs: false
}
// 如果這個組件接收一個 id attribute 和一個 v-on:close 監聽器,那麼 $attrs 對象現在將如下所示
{
 id: 'my-input',
 onClose: () => console.log('close Event Triggered')
}
</script>

$attrs現在包括class和style

現在的$attr包含所有的attribute,包括class和style

在2.x中,虛擬dom會對class和style進行特殊處理,所以他們不包括在$attr中
在使用inheritAttr: false的時候會產生副作用

  • $attrs 中的 attribute 不再自動添加到根元素中,而是由開發者決定在哪添加。
  • 但是 class 和 style 不屬於 $attrs,仍然會應用到組件的根元素:
<template>
 <label>
  <input type="text" v-bind="$attrs" />
 </label>
</template>
<script>
export default {
 inheritAttrs: false
}
</script>
<!-- 寫入 -->
<my-component id="my-id" class="my-class"></my-component>
<!-- vue2 將生成 -->
<label class="my-class">
 <input type="text" id="my-id" />
</label>
<!-- vue3 將生成 -->
<label>
 <input type="text" id="my-id" class="my-class" />
</label>

以上就是詳解vue3中渲染函數的非兼容變更的詳細內容,更多關於vue 渲染函數非兼容變更的資料請關註WalkonNet其它相關文章!

推薦閱讀: