vue3的变化
全局api
createApp 返回实例 替代 new Vue 使得返回实例不再共享全局配置 全局的方法也从Vue上转移到了实例上
2.x全局API | 3.x实例API(app) |
---|---|
Vue.config | app.config |
Vue.config.productionTip | removed |
Vue.config.ignoredElements | app.config.isCustomElement |
Vue.component | app.component |
Vue.directive | app.directive |
Vue.mixin | app.mixin |
Vue.use | app.use |
Vue.prototype | app.config.globalProperties |
config.ignoredElements 就是现在 config.isCustomElement
引入此配置选项旨在支持本机自定义元素,因此重命名可以更好地传达其功能。新选项还期望一个比旧字符串/ RegExp方法具有更大灵活性的函数:
// before
Vue.config.ignoredElements = ['my-el', /^ion-/]
// after
const app = Vue.createApp({})
app.config.isCustomElement = tag => tag.startsWith('ion-')
Vue.prototype 取而代之 config.globalProperties
在Vue 2中,Vue.prototype通常用于添加所有组件都可以访问的属性。 Vue 3中的等效项是config.globalProperties。在实例化应用程序内的组件时,将复制这些属性:
// before - Vue 2
Vue.prototype.$http = () => {}
// after - Vue 3
const app = Vue.createApp({})
app.config.globalProperties.$http = () => {}
一个经过转换的例子如下
const app = createApp(MyApp)
app.component('button-counter', {
data: () => ({
count: 0
}),
template: '<button @click="count++">Clicked {{ count }} times.</button>'
})
app.directive('focus', {
mounted: el => el.focus()
})
// button-counter 组件与 focus指令 不会污染全局 只在当前实例
app.mount('#app')
Provide / Inject
// 在父级
app.provide('guide', 'Vue 3 Guide')
// 在任意层次的子级
export default {
inject: {
book: {
from: 'guide'
}
},
template: `<div>{{ book }}</div>`
}
Tree-shaking
因为内部都重写了,所以组件内部也完全是支持摇树优化的,带来的后果就是一些方法需要显式导入来使用
import { nextTick } from 'vue'
nextTick(() => {
// something DOM-related
})
//before
import { shallowMount } from '@vue/test-utils'
import { MyComponent } from './MyComponent.vue'
test('an async feature', async () => {
const wrapper = shallowMount(MyComponent)
// execute some DOM-related tasks
await wrapper.vm.$nextTick()
// run your assertions
})
//after
import { shallowMount } from '@vue/test-utils'
import { MyComponent } from './MyComponent.vue'
import { nextTick } from 'vue'
test('an async feature', async () => {
const wrapper = shallowMount(MyComponent)
// execute some DOM-related tasks
await nextTick()
// run your assertions
})
####受影响的API
2.x全局API | 3.x用法 |
---|---|
Vue.nextTick | 拆分 |
Vue.observable | 替换为 Vue.reactive |
Vue.version | 拆分 |
Vue.compile | 仅完整版本 |
Vue.set | 仅在兼容版本中 |
Vue.delete | 仅在兼容版本中 |
$attrs的变化
在vue2中,class与style会被直接设置到组件的根元素并且不会出现在 $attrs中, 当inheritAttrs:false的时候
<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将生成以下html
<label class="my-class">
<input type="text" id="my-id" />
</label>
vue3中$attr包含所有属性包括class与style vue3将生成以下html
<label>
<input type="text" id="my-id" class="my-class" />
</label>
$listeners 在vue3也被移除,现在是$attrs的一部分
自定义指令的生命周期变化
简要总结:
- API 已重命名,以便更好地与组件生命周期保持一致
- 自定义指令将由子组件通过 v-bind="$attrs"
对比
2.x | 3.x |
---|---|
bind | beforeMount |
inserted | mounted |
– | beforeUpdate |
update | 已经移除 改用 updated |
componentUpdated | updated |
– | beforeUnmount |
unbind | unmounted |
###生命周期变化 TODO
###scopedSlots正式弃用 v-slot 指令自 Vue 2.6.0 起被引入,提供更好的支持 slot 和 slot-scope attribute 的 API 替代方案。 v-slot 完整的由来参见这份 RFC 。 在接下来所有的 2.x 版本中 slot slot-scope 和 attribute 仍会被支持, 但不会出现在 Vue 3 中。 结合具名插槽要这样写
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
异步组件需要显式定义
Mixin合并行为变更
当来自组件的 data() 及其 mixin 或 extends 基类被合并时,现在将浅层次执行合并:
const Mixin = {
data() {
return {
user: {
name: 'Jack',
id: 1
}
}
}
}
const CompA = {
mixins: [Mixin],
data() {
return {
user: {
id: 2
}
}
}
}
vue2中结果是
{
user: {
id: 2,
name: 'Jack'
}
}
vue3中结果是
{
user: {
id: 2
}
}
发表回复