# Vue2 vs Vue3
# Vue3优点
# diff算法优化
vue2是对所有虚拟dom的全量对比,vue3新增了静态标记(patch tag),在每次对比时,忽略静态dom,只对比动态dom
例如:下面的模板包含一个div,div内包含三个段落,其中前两个段落是静态固定不变的,而第三个段落的内容绑定的msg属性,当msg改变的时候,Vue会生成新的虚拟DOM然后和旧的进行对比。
<div>
<p>云驻共创</p>
<p>如何评价 vue3</p>
<p>{{msg}}</p>
</div>
当视图更新时,只对动态节点部分进行diff运算,减少了资源的损耗。Patchflag是个枚举,取值为1代表这个元素的文本是动态绑定的,取值为2代表元素的class是动态绑定的。
# 静态提升
在vue2中,元素是否参与更新,每次都会被重新创建渲染
在vue3中,对静态元素进行了提升,每次不会进行重新渲染,大大的减少了浏览器渲染负担。
提升前
export function render(...) {
return (
_openBlock(),
_createBlock('div', null, [
_createVNode('div', null, '共创1'),
_createVNode('div', null, '共创2'),
_createVNode(
'div',
null,
_toDisplayString(_ctx.name),
1 /* TEXT */
),
])
)
}
提升后
const _hoisted_1 = /*#__PURE__*/ _createVNode(
'div',
null,
'共创1',
-1 /* HOISTED */
)
const _hoisted_2 = /*#__PURE__*/ _createVNode(
'div',
null,
'共创2',
-1 /* HOISTED */
)
export function render(...) {
return (
_openBlock(),
_createBlock('div', null, [
_hoisted_1,
_hoisted_2,
_createVNode(
'div',
null,
_toDisplayString(_ctx.name),
1 /* TEXT */
),
])
)
}
# 双向数据绑定优化
在vue2中,数据的绑定是通过object.defineProperty()的getter,setter来实现的,但该中方式无法处理数组的改变。
在vue3中,改用es6 proxy来进行实现,较之前相比,proxy提供了更丰富的方法 ,除get,set外,还有has,isOwnProperty等供我们使用,再也不需要使用$set来处理数据的更新。
# Compostion Api
较vue2,template,script,style来说,它的出现是将js逻辑部分集中起来,更好的维护封装组件。 增加了可读性逻辑性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>hello vue3</title>
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.0-beta.14/dist/vue.global.js"></script>
<!-- <script src="../dist/vue.global.js"></script> -->
</head>
<body>
hello vue3
<div id='app'>
<h2>{{state.count}}--{{count2}}---{{state.doubleCount}}</h2>
<div @click="add">count: {{ state.count }}</div>
<div @click="add2">count: {{ count2 }}</div>
</div>
<script>
const { createApp, reactive, ref, computed, watch } = Vue
// reactive: 接收一个普通对象然后返回该普通对象的响应式代理。等同于 2.x 的 Vue.observable()
// ref: 接受一个参数值并返回一个响应式且可改变的 ref 对象。ref 对象拥有一个指向内部值的单一属性 .value。
// computed: 传入一个 getter 函数,返回一个默认不可手动修改的 ref 对象。
// watch API 完全等效于 2.x this.$watch (以及 watch 中相应的选项)。watch 需要侦听特定的数据源,并在回调函数中执行副作用。默认情况是懒执行的,也就是说仅在侦听的源变更时才执行回调。
const App = {
// setup 函数是一个新的组件选项。作为在组件内使用 Composition API 的入口点。
// 调用时刻是初始化属性props确定后,beforeCreate之前
setup() {
const count2 = ref(1)
// 响应化:接收一个对象,返回一个响应式的代理对象
const state = reactive({
count: 1,
// computed()返回一个不可变的响应式引用对象
// 它封装了getter的返回值
doubleCount: computed(() => state.count * 2)
})
watch(
() => state.count,
(count, prevCount) => {
/* ... */
console.log('state.count', count, prevCount);
}
)
watch(count2, (count, prevCount) => {
/* ... */
console.log('count2', count, prevCount);
})
function add() {
state.count++
}
function add2() {
count2.value++
}
// 返回对象将和渲染函数上下文合并
return { count2, state, add, add2 }
}
}
createApp(App).mount('#app')
</script>
</body>
</html>
← Redux - 03 Vue3迁移手册 →