Vue.js是一款流行的JavaScript框架,它的不断演进让开发者们享受到更好的开发体验。Vue3 对比 Vue2 有很多新特性增加,也有很多功能属于破坏性更新。本文将列举一些值得关注的新特性和变化,以帮助开发者更好地理解Vue 2和Vue 3之间的差异。
值得关注的新特性
-
组合式 API
setup
与setup
语法糖模式Vue 3引入了组合式API,允许开发者更灵活地组织组件逻辑。
setup
函数以及相关的语法糖模式使代码更清晰、易于维护。 -
新增的内置组件
Teleport
与Suspense
Vue 3引入了
Teleport
组件,用于在DOM中移动元素,以及Suspense
组件,用于处理异步数据和组件的加载。 -
响应式原理的变化:从
Object.defineProperty
到Proxy
Vue 3采用了
Proxy
来实现响应式,相比Vue 2中的Object.defineProperty
,更加灵活和高效。 -
对 TypeScript 的友好支持
Vue 3对TypeScript提供了更好的支持,包括类型推断和更丰富的类型定义。
-
自定义 Hooks 逻辑拆分
开发者可以将逻辑拆分成自定义Hooks,提高了代码的可维护性和复用性。
-
v-memo
新指令v-memo
指令可以在一定程度上提升性能,允许开发者手动控制组件的渲染。
破坏性更新的API以及功能
不再需要手动实例化Vue
Vue 3废弃了
new Vue
的操作,取而代之的是使用createApp
来创建Vue应用实例,并使用mount
方法挂载到DOM上。
import {
createApp } from 'vue'
import App from './App.vue'
const app = createApp(App).mount('#app')
同时,返回的app
实例与之前不同,一些全局配置也被废弃。废弃了 Vue.config.productionTip
Vue.extend
具有影响的改动点 之前的 Vue.prototype
改为 app.config.globalProperties
//vue2
//定义全局属性或者方法
vue.prototype.xxxxxx
//vue3
app.config.globalProperties.xxxxxxx
nextTick 的变化
Vue 3的
nextTick
源码不再需要判断各种兼容性,直接使用Promise来实现。
//Vue2 还在判断 promise MutationObserver setImmediate setTimeout
let timerFunc
if (typeof Promise !== 'undefined' && isNative(Promise)) {
const p = Promise.resolve()
timerFunc = () => {
p.then(flushCallbacks)
if (isIOS) setTimeout(noop)
}
isUsingMicroTask = true
} else if (!isIE && typeof MutationObserver !== 'undefined' && (
isNative(MutationObserver) ||
MutationObserver.toString() === '[object MutationObserverConstructor]'
)) {
let counter = 1
const observer = new MutationObserver(flushCallbacks)
const textNode = document.createTextNode(String(counter))
observer.observe(textNode, {
characterData: true
})
timerFunc = () => {
counter = (counter + 1) % 2
console.log('counter', counter)
textNode.data = String(counter)
}
isUsingMicroTask = true
} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
timerFunc = () => {
setImmediate(flushCallbacks)
}
} else {
timerFunc = () => {
setTimeout(flushCallbacks, 0)
}
}
//Vue3.x 直接使用promise
export function nextTick<T = void>(
this: T,
fn?: (this: T) => void
): Promise<void> {
const p = currentFlushPromise || resolvedPromise
return fn ? p.then(this ? fn.bind(this) : fn) : p
}
v-model 终极破坏性更新
Vue 2中默认的props
名为value
,而Vue 3默认为modelValue
。同时,emit
的派发事件从input
变为了update:modelValue
。sync
修饰符和native
修饰符被废除,新增了多v-model
语法和自定义修饰符的支持。
<template>
<!--废弃-->
<div xxx.sync></div>
<A @click.native></A>
<!--新增多v-model用法以及自定义修饰符-->
<B v-model:xxx='a' v-model:cccc='a' v-model:ddd.yyy.ccc='a'></B>
</template>
export default {
props: {
modelValue: String // 以前是`value:String`
},
emits: ['update:modelValue'],
methods: {
changePageTitle(title) {
this.$emit('update:modelValue', title) // 以前是 `this.$emit('input', title)`
}
}
}
v-for v-if指令优先级调整
在Vue 2中,
v-for
会优先级高。但在Vue 3中,v-if
优先级高
异步组件的变化
Vue 2中异步组件可以直接返回一个Promise,而Vue 3需要使用
defineAsyncComponent
来包裹。
//vue2
const asyncModal = () => import('./Modal.vue')
//vue3
import {
defineAsyncComponent } from 'vue'
const asyncModal = defineAsyncComponent(() => import('./Modal.vue'))
生命周期名字改变
Vue 3中的生命周期选项名字发生了变化,
destroyed
改为onUnmounted
,beforeDestroy
改为beforeUnmount
。
transition组件部分class重命名
在Vue 3中,
leave-class
已经被重命名为leave-from-class
,并且可以在渲染函数中写作leaveFromClass
,类似地,enter-class
也发生了类似的改变。
自定义指令破坏性更新
主要是生命周期的替换方便记忆
- Vue2
- bind - 指令绑定到元素后调用。只调用一次。
- inserted - 元素插入父 DOM 后调用。
- update - 当元素更新,但子元素尚未更新时,将调用此钩子。
- componentUpdated - 一旦组件和子级被更新,就会调用这个钩子。
- unbind - 一旦指令被移除,就会调用这个钩子。也只调用一次。
- Vue3
- created - 新增!在元素的 attribute 或事件监听器被应用之前调用。
- bind → beforeMount
- inserted → mounted
- beforeUpdate:新增!在元素本身被更新之前调用,与组件的生命周期钩子十分相似。
- update → 移除!该钩子与 updated 有太多相似之处,因此它是多余的。请改用 updated
- componentUpdated → updated
- beforeUnmount:新增!与组件的生命周期钩子类似,它将在元素被卸载之前调用。
- unbind -> unmounted
移除的API以及方法
$on
、$off
和 $once
实例方法
Vue 3中已移除
$on
,$off
和$once
实例方法,推荐使用mitt
库代替。
filters过滤器已经移除
Vue 2中可以使用过滤器来处理文本输出,但Vue 3中已移除,推荐使用全局过滤器。
//vue2
<template>
<h1>Bank Account Balance</h1>
<p>{
{
accountBalance | currencyUSD }}</p>
</template>
<script>
export default {
props: {
accountBalance: {
type: Number,
required: true
}
},
filters: {
currencyUSD(value) {
return '$' + value
}
}
}
</script>
//vue3 可以添加一个全局过滤器使用
const app = createApp(App)
app.config.globalProperties.$filters = {
currencyUSD(value) {
return '$' + value
}
}
$children 移除
在Vue 2中,可以使用
$children
访问子组件实例,但在Vue 3中推荐使用ref
访问子组件。
全局函数 set
和 delete
以及实例方法 $set
和 $delete
。
Vue 3基于Proxy代理的变化检测不再需要这些方法。
按键修饰符
Vue 2中可以使用
Vue.config.keyCodes
来自定义按键修饰符,但Vue 3中建议使用 kebab-cased (短横线) 名称,而不再支持自定义按键修饰符。
总结
这些是Vue 2和Vue 3之间一些重要的新特性和变化。要深入了解每个特性和变化的详细信息,可以查阅官方文档或相关教程。在迁移或选择使用Vue版本时,考虑这些变化对于项目的影响非常重要。希望这些信息对你有所帮助!