聊聊vue2和vue3的区别
① vue2和vue3双向数据绑定原理
双向数据绑定的原理不同: Vue2使用的是ES5 的一个 API【Object.defineProperty】Object.defineProperty,通过发布/订阅实现
Vue3使用的是ES6的Proxy,对数据进行代理,能够监听对象和数组的变化
proxy的优势如下
- defineProperty只能监听某个属性,不能对全对象监听
- 可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)
- 可以监听数组,不用再去单独的对数组做特异性操作 vue3.x可以检测到数组内部数据的变化
典型的就是this.$set()没有必要使用了!
② 生命周期
Vue2的生命周期钩子函数 beforeCreate、created、beforeMount、mounted等
Vue3的生命周期钩子函数 setup、onBeforeMount、onMounted
等 并且提供了两个调试的钩子onRenderTracked和onRenderTriggered
Vue2和Vue3的生命周期
Vue2
Vue3
-
setup() :开始创建组件之前,在beforeCreate和created之前执行。创建的是data和method
-
onBeforeMount() : 组件挂载到节点上之前执行的函数。
-
onMounted() : 组件挂载完成后执行的函数。
-
onBeforeUpdate(): 组件更新之前执行的函数。
-
onUpdated(): 组件更新完成之后执行的函数。
-
onBeforeUnmount(): 组件卸载之前执行的函数。
-
onUnmounted(): 组件卸载完成后执行的函数
若组件被
<keep-alive></keep-alive>
包含,则多出下面两个钩子函数。-
onActivated(): 被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行 。
-
onDeactivated(): 比如从 A组件,切换到 B 组件,A 组件消失时执行。
-
③API
Vue2使用的是选项式API,里面有data、methods、mounted等
Vue3使用的是组合式API,使用的是setup函数
分别简单写出vue2和vue3的东西我们可以发现如下:
Vue2
js
<template>
<div>
<h2> {{title}}</h2>
</div>
</template>
<script>
export default {
components:{}, //组件
props:{title:String},
data(){return{title:'Vue2'}},
mounted(){},
methods:{},
conmputed:{
fullName(){
return this.firstName+''+this.lastName;
}
}
}
</script>
Vue3
js
<template>
<div>
<h2> {{title}}</h2>
</div>
</template>
<script>
import {ref,reactive} from 'vue'
export default {
components:{}, //组件
props:{title:String},
setup(){
// 数据
const state=reactive({
userName:'',
phone:conmputed(()=>{})
});
const numbertotal=()=>{
// 计算数字总和
};
return {
state,
numbertotal,
}
}
}
</script>
直接使用setup函数可以写成如图:
④支持碎片化((Fragments))
Vue2中,template下只允许存在一个根节点
Vue3中可以有多个根节点,为我们创建一个虚拟的Fragment节点。
Vue2
Vue3
⑤ 定义数据变量
Vue2中数据放在data里,方法放在methods里
Vue3在setup方法里定义数据,这个方法在组件初始化的时候触发,使用reactive和ref将数据变成响应式数据
Vue2
Vue3
在Vue3.0,使用一个新的setup()方法,此方法在组件初始化构造的时候触发。
⑥ v-for 和 v-if 的区别
在vue2中v-for与 v-if 可以同时用,【优先级】:v-for > v-if
v-for的优先级比v-if高,所以可以一起用, 但是每次页面渲染的时候都会重复的进行判断是十分消耗性能的,不推荐使用
因为v-if和v-for在同一层级,Vue在渲染组件的时 先根据v-for遍历所有 数据 并将他们都生成对应的虚拟DOM,之后再根据v-if的判断去对不符合条件的 元素进行从虚拟DOM的删除
这里为什么不推荐显而易见: 就是因为 会先执行v-for循环遍历出所有的数据 但是这个时候不是先进行v-if的 判断而是会去先对所有的数据都生成对应的虚拟DOM 然后再去通过v-if的判断 去 去掉不符合条件的虚拟DOM 这样就会造成性能的消耗 生成了没必要的虚拟 DOM元素 并且还对这些没必要的虚拟DOM元素进行了一次删除大大提高了 性能的损耗
Vue3中正好相反 v-if > for 【优先级】 v-if > v-for
所以在Vue3中想要把v-if和v-for一起放在标签内一起使用是不可能的会直接报
错
原因:在Vue3中的v-if是比v-for的优先级高的 所以会先执行v-if但是v-if 的
执行又需要依靠到v-for的数据 但是这里是先执行v-if这个时候v-for还没有遍
历数据 所以会报一个当前v-if判断的变量还没有被定义的错误
解决方案
1:嵌套使用
2:使用computed计算属性或提前对数组进行filter过滤操作
(1)嵌套使用:
我们把优先级高的指令放到内层嵌套的形式去写也就是在Vue3中我们外层 使用v-for 内层去使用v-if判断 这样就可以保证v-for先执行把数据都遍历出来供 我们的v-if使用 并且Vue可以先根据v-for遍历出来的所有子元素 去渲染只符合 v-if判断条件的元素将符合条件的渲染并且生成虚拟DOM,而不符合条件的不会生成虚拟DOM
这样可以避免不必要的性能消耗 提高页面渲染的速度
为什么使用嵌套不会产生额外的虚拟DOM元素呢 ? 因为在这里的嵌套是父子级 的关系 v-if是v-for的子级也就是说在v-for循环出来所有的数据之后 就会到子级 去执行生成对应子级虚拟DOM的任务 但是在子级的元素标签上有v-if的判断 不符合的不会渲染 所以 不符合的元素的虚拟DOM就不会生成了
(2)我们可以避免同时使用v-if和v-for
我们首先明确我们的目的 如果遇到了这种需要同时使用的时候一般是因为 我们的数组还没有经过处理 所以需要遍历数组的同时对数组中的值进行处理 所以我们可以先一步对数组进行处理后 再进行遍历 例如我们可以通过数组的filter方法提前过滤 或者放到computed 计算属性中提前处理好 只使用一个v-for去遍历通过computed计算属性过滤好的元素。 ------------------------------------------------
⑦兼容性
支持TypeScript性
Vue3完全支持TypeScript,提高项目的可维护性 Vue2对TypeScript的支持有限
⑧ Vue3新增组件
Vue3新增了Teleport传送门组件和Suspense组件
Teleport传送门组件
你写的组件挂载到任何你想挂载的DOM上
弹窗组件:
在app.vue中使用的时候跟普通组件调用 vue2你可能只能嵌套在#app中
但是vue3之中,Teleport 可以把modal组件渲染到任意你想渲染的外部Dom上,不必嵌套在#app中
(举例)
可将弹窗 移动到 #app中之外的位置
使用to属性去移动到想要的地方:
异步组件(Suspense)
允许程序在等待异步组件加载完成前渲染兜底的内容,如 loading ,使用户的体验更平滑。使用它,需在模板中声明,并包括两个命名插槽:default 和 fallback。Suspense 确保加载完异步内容时显示默认插槽,并将 fallback 插槽用作加载状态。