vue3 和 vue2的比较
Posted 朦胧之月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3 和 vue2的比较相关的知识,希望对你有一定的参考价值。
一、vue3相对于vue2的优化
- 类型判断的优化: 由flow.js 改为 typescript。
数据劫持的优化: 由Object.defineProperty 改为 Proxy, 因为:
- 对于比较深的对象,Object.defineProperty需要递归遍历所有属性,将所有属性变为响应对象,降低了性能
- Proxy 对于访问到对象内部的才会变为响应对象
编译阶段的优化:模版编译的优化、slot的编译优化、事件监听函数的缓存优化及diff算法的重写
- slot优化,将slot编译为lazy函数,将slot的渲染的决定权交给子组件
- 模版编译的优:通过编译阶段对静态模板的分析,编译生成了
Block Tree
。Block Tree
是一个将模版基于动态节点指令切割的嵌套区块,每个区块内部的节点结构是固定的,而且每个区块只需要以一个Array
来追踪自身包含的动态节点 - diff算法重写是因为:vue2中单个组件内,VDOM diff需要遍历整个DOM树,更新需要重新生成DOM树;vue3的VDOM增加静态标记、静态提升、事件缓存,会预先缓存DOM树,通过上下文拿到缓存的DOM树,只diff 动态节点
<div id="content">
<p>text</p> // 静态节点
<p>text</p> // 静态节点
<p>{{ message }}</p> // 动态节点
<p>text</p> // 静态节点
<p>text</p> // 静态节点
</div>
逻辑复用的优化:由mixins 改为 hook钩子函数,因为:
- 定义的变量名容易冲突
- 变量数据来源不清
// hook
import { ref, onMounted, onUnmounted } from \'vue\'
export default () => {
const width = ref(window.innerWidth);
const height = ref(window.innerHeight);
const update = () => {
width.value = window.innerWidth;
height.value = window.innerHeight;
}
onMounted(() => {
window.addEventListener("resize", update)
})
onUnmounted(() => {
window.removeEventListener("resize", update)
})
return { width, height }
}
二、vue3相对于vue2的变化
- 生命周期的变化
vue3 | vue2 |
---|---|
setup() 开始创建组件 | beforeCreate() + created() |
onBeforeMount() 组件挂载到页面之前 | beforeMount() |
onMounted() 组件挂载到页面之后 | Mounted() |
onBeforeUpdate() 组件更新之前 | beforeUpdate() |
onUpdated() 组件更新之后 | updated() |
onBeforeUnmount() 组件卸载之前 | beforeDestroy() |
onUnmount() 组件卸载之前 | destroyed() |
onActivated() | activated() |
onDeactivated() | deactivated() |
- 全局API的变化
## Before
import Vue from \'vue\'
import App from \'./App.vue\'
Vue.use(...)
Vue.component(...)
Vue.prototype.customProperty = ...
new Vue({
render: h => h(App)
}).$mount(\'#app\')
## After
import { createApp } from \'vue\'
import App from \'./App.vue\'
const app = createApp(App)
app.use(...)
app.component(...)
app.config.globalProperties.customProperty = ...
app.mount(\'#app\')
- 全局弹窗
## Before
import vue from \'vue\'
import toastComponent from \'./toast.vue\'
const ToastConstructor = vue.extend(toastComponent)
function showToast() {
const toastDom = new ToastConstructor({...})
}
vue.prototype.$toast = showToast
## After
<div>
<teleport to="body">
...
</teleport>
</div>
- 子组件向父组件传值
## Before
export default {
methods: {
change() {
this.$emit("todata", params);
}
}
}
## After
export default defineComponent({
emits: ["todata"],
setup(props, {emit}) {
const change = () => {
const params = {
user:"ylw"
};
emit("todata", params);
};
}
})
三、组件内的使用
// sfc组件
<script lang="ts">
import { defineComponent, ref, Ref, computed, watchEffect, PropType } from \'vue\'
interface Config {
name: string;
}
const Iprops = {
age: {
type: Number as PropType<number>
},
config: {
type: Object as PropType<Config>
required: true
}
} as const
export default defineComponent({
name: \'App\',
props: Iprops,
data() {
return {}
},
mounted() {
},
setup(props, { slots, attrs, emit }) {
const nameRef: Ref<number> = ref(0)
const setName = () => {
nameRef.value++
}
const computedNameRef: Computed<number> = computed(() => {
return nameRef.value + 2
})
watchEffect(() => {
console.log(nameRef.value)
})
return {
name: nameRef,
name2: computedNameRef,
setName
}
}
})
</script>
// jsx组件
import { defineComponent, ref, computed, watchEffect } from \'vue\'
export default defineComponent({
const numberRef: Ref<number> = ref(1)
setup() {
const number = numberRef.value
return () => {
return (<div>
<p>{ number }</p>
</div>)
}
}
})
四、Vite和webpack
vite的特性
- vite是一个基于浏览器原生ES imports的开发服务器
- 利用浏览器去解析imports,在服务器端按需编译返回,完全跳过了打包这一步,服务器随起随用;而webpack开发环境,需要编译打包es6、es7等,然后启动开发服务器
- vite支持热更新:vite是按需加载,webpack是全部加载
- vite依赖es module的特性
vite的打包原理
打包过程 | 原理 | |
---|---|---|
webpack | 识别入口->逐层识别依赖->分析/转换/编译/输出代码->打包后的代码 | 逐级递归识别依赖,构建依赖图谱->转化AST语法树->处理代码->转换为浏览器可识别的代码 |
vite | - | 基于浏览器原生 ES module,利用浏览器解析 imports,服务器端按需编译返回 |
vite的改进点
webpack缺点 | vite改进点 |
---|---|
服务器启动缓慢 | 将应用模块区分为依赖 和 源码 两类; 使用esbuild构建;在浏览器请求源码时进行转换并按需提供源码 |
基于nodejs | esbuild(Go 编写) 预构建依赖,比node快 10-100 倍 |
热更新效率低下;编辑单个文件会重新构建整个包;HMR 更新速度随规模增大下降 | HMR基于原生 ESM 上,更新速度与应用规模无关;利用http2的缓存+压缩优势 |
vite的缺点
- 生态不及webpack,加载器、插件不够丰富
- 生产环境esbuild构建对于css和代码分割不够友好
- 没被大规模重度使用,会隐藏一些问题
以上是关于vue3 和 vue2的比较的主要内容,如果未能解决你的问题,请参考以下文章
Vue3官网-高级指南(十七)响应式计算`computed`和侦听`watchEffect`(onTrackonTriggeronInvalidate副作用的刷新时机`watch` pre)(代码片段