Detailed explanation of incompatible changes of rendering function in vue3

  • 2021-11-01 02:17:03
  • OfStack

Directory rendering function API change
Render function parameter rendering function signature change VNode Props formatting slot system 1
Remove $listeners
$attrs now includes class and style

Render function API change

This change does not affect < template > Users

h is now imported globally instead of being passed as a parameter to the rendering function The rendering function parameter is changed to be more 1 between stateful components and function components vnode now has a flat prop structure

Render function parameter


// 2.0  Rendering function 
export default {
 render(h) {
  return h('div')
 }
}

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

Render function signature change


// 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++
  }
  //  Return render Function 
  return () => h(
   'div',
   {
    onClick: increment
   },
   state.count
  )
 }
}

VNode Props Formatting


// 2.x
{
 class: ['button', 'is-outlined'],
 style: {color: '#fffff'},
 attr: {id: 'submit'},
 domProps: {innerHTML: ''},
 on: {click: submitForm},
 key: 'submit-button'
}
// 3.x VNode The structure is flat 
{
 class: ['button', 'is-outlined'],
 style: { color: '#34495E' },
 id: 'submit',
 innerHTML: '',
 onClick: submitForm,
 key: 'submit-button'
}

slot Series 1

Changed normal slot and scope slot

this. $slots now exposes slots as a function Remove this. $scopedSlots

// 2.x
h(LayoutComponent, [
 h('div', {slot: 'header'}, this.header),
 h('div', {slot: 'header'}, this.header)
])
//  Scope slot : 


// 3.x
h(LayoutComponent, {}, {
 header: () => h('div', this.header),
 content: () => h('div', this.content)
})
//  Scope needs to be introduced programmatically slot At that time, they are now unified 1 Here we are $slots Options in 
// 2.x Scope of slot
this.$scopedSlots.header
// 3.x The writing style of 
this.$slots.header

Remove $listeners

$listeners Object has been removed in vue3, and now the event listener is $attrs Part 1 of

In vue2, you can use this. attrs and this. attrs and this. listeners to access the attribute and time listener passed to the component, respectively. Combined with inheritAttrs: false, developers can apply these attribute and listener to other elements instead of the root element


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

In the virtual DOM of vue, the event listener is now only attribute prefixed with on, so it becomes part of the attrs object, so it is part of the attrs object, so listeners is removed


<template>
 <label>
  <input type="text" v-bind="$attrs" />
 </label>
</template>
<script>
export default {
 inheritAttrs: false
}
//  If this component receives 1 A  id attribute  And 1 A  v-on:close  Listener, then  $attrs  The object will now look like this 
{
 id: 'my-input',
 onClose: () => console.log('close Event Triggered')
}
</script>

$attrs now includes class and style

The current $attr contains all attribute, including class and style

In 2. x, virtual dom does special treatment for class and style, so they are not included in $attr
There are side effects when using inheritAttr: false

attribute in $attrs is no longer automatically added to the root element, but it is up to the developer to decide where to add it. But class and style are not part of $attrs and still apply to the root element of the component:

<template>
 <label>
  <input type="text" v-bind="$attrs" />
 </label>
</template>
<script>
export default {
 inheritAttrs: false
}
</script>
<!--  Write  -->
<my-component id="my-id" class="my-class"></my-component>
<!-- vue2  Will generate  -->
<label class="my-class">
 <input type="text" id="my-id" />
</label>
<!-- vue3  Will generate  -->
<label>
 <input type="text" id="my-id" class="my-class" />
</label>

The above is a detailed explanation of vue3 rendering function incompatible changes in detail, more information about vue rendering function incompatible changes please pay attention to other related articles on this site!


Related articles: