vue3.0对比总结以及相关API区别总结

187 阅读3分钟

Vue3.0亮点

1.性能比vue2.x快1.2倍~2倍
2.按需编译,体积更小
3.组合API(类似React Hooks)
4.更好的TS支持
5.暴露了自定义渲染API

Vue3.0是如何变快

1.diff方法优化

vue2.x中虚拟dom是进行全量对比
Vue3中新增了静态标记(PatchFlag),在与上次虚拟节点对比时,只对比带有patch flag的节点,并且可以通过flag的信息得知当前节点要对比的具体内容

2.静态提升

vue2.x中无论元素是否参与更新,每次都会重新创建,然后再渲染 vue3中对于不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可

3.事件监听器缓存

默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化,但是因为是同一个函数,所以没有追踪变化,直接缓存起来复用即可

4.ssr渲染

当有大量静态的内容时候,这些内容会被当作纯字符串推进一个buffer里面,即使存在动态的绑定,会通过模版插值嵌入进去。这样会比通过虚拟dom来渲染的快上很多很多
当静态内容大到一定量级的时候,会用_createStaticVNode方法在客户端去生成一个static node,这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染

API:

reactive和ref区别:

ref(10)=>reactive({value:10})
ref包装的要加.value ,因为 ref 就是通过 reactive 包装了一个对象 ,然后是将值传给该对象中的 value 属性
建议

  • 基本类型值(String 、Nmuber 、Boolean 等)或单值对象(类似像 {count: 3} 这样只有一个属性值的对象)使用 ref
  • 引用类型值(Object 、Array)使用 reactive

ref 和toRef区别

  • ref对原始值是深拷贝,toRef对原始值是浅拷贝(引用值对话,俩个都是浅拷贝)
  • ref 的值改变会更新视图;toRef 的值改变不会更新视图

toRefs其作用就是将传入的对象里所有的属性的值都转化为响应式数据对象

shallowReactive和reactive区别

其实将 obj 作为参数传递给 reactive 生成响应式数据对象时,若 obj 的层级不止一层,那么会将每一层都用 Proxy 包装一次

image.png 如果一个对象层级比较深,那么每一层都用 Proxy 包装后,对于性能是非常不友好的
来看看shallowReactive

image.png 只有第一层被 Proxy 处理了,也就是说只有修改第一层的值时,才会响应式更新

shallowReactive 和shallowRef区别

这是一个浅层的 ref,与 shallowReactive 一样是拿来做性能优化的
shallowRef(10)=>shallowReactive({value:10})

shallowReactive 是监听对象第一层的数据变化用于驱动视图更新。shallowRef 则是监听 .value 的值的变化来更新视图的,将整个 .value 重新赋值了,视图才会更新,如果想改变对象里面一个属性值,然后更新视图,需要调用triggerRef,调用它就可以立马更新视图,其接收一个参数 state ,即需要更新的 ref 对象

<template>
	<p>{{ state.a }}</p>
	<p>{{ state.first.b }}</p>
	<p>{{ state.first.second.c }}</p>
	<button @click="change">改变</button>
</template>

<script>
import {shallowRef, triggerRef} from 'vue'
export default {
    setup() {
        const obj = {
            a: 1,
            first: {
                b: 2,
                second: {
                    c: 3
                }
            }
        }

        const state = shallowRef(obj)
        console.log(state);

        function change() {
            state.value.first.b = 8
            state.value.first.second.c = 9
            // 修改值后立即驱动视图更新
            triggerRef(state)
            console.log(state);
        }

        return {state, change}
    }
}
</script>