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.$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>