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.xexport default {  render(h) {    return h('div')  }}// 3.ximport { 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.xh(LayoutComponent, [  h('div', {slot: 'header'}, this.header),  h('div', {slot: 'header'}, this.header)])// 作用域slot:// 3.xh(LayoutComponent, {}, {  header: () => h('div', this.header),  content: () => h('div', this.content)})// 须要以编程形式引入作用域slot时,他们当初被对立在了$slots选项中// 2.x的作用域slotthis.$scopedSlots.header// 3.x的写法this.$slots.header

移除$listeners

$listeners对象在vue3中曾经移除,当初事件监听器是$attrs的一部分

在vue2中,能够应用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对象的一部分,这样$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>