vue2 和 vue3 对比

一、Vue3的优点

  • 1、diff算法的提升

vue2中的虚拟DOM是全量的对比,也就是不管是写死的还是动态节点都会一层层比较,浪费时间在静态节点上。

vue3新增静态标记(patchflag ),与之前虚拟节点对比,只对比带有patch flag 的节点,可通过flag信息得知当前节点要对比的具体内容。

例如: 当代码中包含数据时,会标记为动态。

  • 2、静态提升

vue2不管是否参与更新,都会重新创建再渲染。

vue3对于不参与更新的元素,会做静态提升,只被创建一次,在渲染时直接复用即可。

  • 3、事件侦听器缓存。
  • 4、 ssr渲染
  • 5、更好的ts支持
  • 6、Composition Api

vue2的组件内部都是options api风格,也就是在data, methods, mounted等来组织代码,这样会让逻辑很分散,每次变动需要反复查找位置。

vue3中使用setup,逻辑都放到里边。

  • 7、更先进的组件

vue2不允许template下写两个组件,vue3允许,将为我们创建一个虚拟的Fragment节点。

  • 8、自定义渲染api
const { createApp } from 'vue'
import App from "./src/App"
createApp(App).mount(('#app')
  • 9、按需编译,体积比vue2更小
  • 10.支持多根节点组件

 、响应式原理不同:

  • vue2实现双向数据绑定原理,是通过ES5的Object.defineProperty,根据具体的key去读取和修改。其中的setter方法来实现数据劫持,getter实现数据修改。但是必须要先知道拦截和修改的key,所以vue2对于新增的属性无能为力,比如无法监听属性的新增和删除,数组索引和长度的变更,解决方法使用Vue.set(object, properName,value)等嵌套对象添加响应式。 
function observe(obj, callback) {
    let newObj = {};
    Object.keys(obj).forEach((key) => {
        Object.defineProperty(newObj, key, {
            enumerable: true,
            configurable: true,
            get() {
                return obj[key];
            },
            set(val) {
                obj[key] = val;
                callback(key, val);
            }
        })
    })
    return newObj;
}
let obj = observe({ name: 'alan', age: '1888' }, (key, value) => { console.log(`打印${value}`) });
  •  在vue3中使用es5中得更快的proxy,替代了Object.defineProperty。proxy可以理解为在对象外加了一层拦截,任何人要访问该对象,都要通过这层拦截。且proxy直接对对象拦截而非属性,并返回一个对象,具有更好的响应式支持。

 

function obseve2(obj, callback) {
    return new Proxy(obj, {
        set(target, key, value) {
            target[key] = value;
            callback(key, value);
        },
        get(taget, key) {
            return taget[key];
        }
    }
    )
}
let obj2 = obseve2({ x: 1, y: 2 }, (key, value) => { console.log('坐标系') })

 

 

 

三、生命周期变化

 

 初始化加载顺序:

setup => beforeCreate => created => onBeforeMount => onMounted

vue3压缩后变快,很大程度是因为这些使用都需要引入了。

!!!  vue3中的核心api都支持了tree-shaking,这些api都是通过包引入的方式而不是直接在实例化时就注入,只会对使用到的功能或特性进行打包(按需打包),这意味着更多的功能和更小的体积。

四、mixins更改

 在vue2 使用mixins来实现相同逻辑的抽离,每个组件只需要引入mixins,就能实现复用。

创建js文件,写入

export default {
  data(){
    return {}
  },
  methods:{},
  computed:{},
  filters:{},
  created(){},
  mounted(){
    console.log("我是mixins");
  }
}

使用方法:

引入js文件,写入mixins:[ ]

缺点:mixins的声明周期会和引入mixins的组件的生命周期整合在一起。且minxins的生命周期比组件调用快。组件的data,methods会覆盖同名data,methods。

1.变量来源不明确(隐式传入),不利于阅读,使代码变得难以维护。

2.多个mixins的生命周期会融合到一起运行,但是同名属性、同名方法无法融合,可能会导致冲突。

3.mixins和组件可能出现多对多的关系,复杂度较高(即一个组件可以引用多个mixins,一个mixins也可以被多个组件引用)。

vue3中的改进:

自定义hook的作用类似vue2的mixin,封装可复用的功能函数。

import { ref,computed } from "vue";

export  function useCount(){
    const num = ref(10);
    const doubles = computed(() => num.value * 2);
    return {
        num,
        doubles
    }
}
 import {useCount} from './useCount'

//初始化
const {num,doubles}=useCount();

 五、父子传值的变化

在vue2中使用props传值。

在vue3中依旧使用,但是传值写法有所变化。

vue3  父组件

 <page2 :name="ageRef" @clickParent="clickParent"></page2>

 function clickParent() {
      console.log('我想点击父组件')
    }

子组件

<template>
    <div>
        我是子组件page2啊:
        <div @click="emitP">{{name}}</div>
    </div>
</template>
<script>
import { toRefs } from 'vue'
export default{
    props:{
        name: String,
    },
    setup(props,context){
        let {name}=toRefs(props);
        let {slots,emit}=context;
        function emitP(){
            emit('clickParent');
        }
        return{
            name,
            emitP
        }
    }
}
</script>

context:

包含 attrsslotsemit 等数据方法:

  • attrs:获取组件上的属性
  • slots:获取 slot 插槽的节点
  • emit :emit 方法(子组件向父组件传递数据

setup 函数是 Vue3 中新增的一个生命周期函数,会在 beforeCreate 之前调用。因为此时组件的 data 和 methods 还没有初始化,因此在 setup 中是不能使用 this 的。所以 Vue 为了避免我们错误的使用,它直接将 setup 函数中的 this 修改成了undefined。并且,我们只能同步使用setup函数,不能用async将其设为异步。

setup 函数接收两个参数 props和 context, 语法为:setup(props,context){}

props

props 里面包含父组件传递给子组件的所有数据。在子组件中使用 props 进行接收。

props 是响应式的, 当传入新的 props 时,会及时被更新。
由于是响应式的, 所以不可以使用 ES6 解构,解构会消除它的响应式。可以使用toRefs

provide,inject 父组件向子组件传递方法和数据

api均从vue中引入。

在父组件直接provide(‘别名’,变量或方法);

在子组件直接inject(‘别名’)

六、碎片化节点

在vue2中,template下只允许存在一个根节点,在vue3中可以有多个跟结点。

 

 

参考文章:

https://www.cnblogs.com/bingcola/p/15210566.html

 

posted @ 2022-02-10 14:32  阿兰儿  阅读(5667)  评论(0编辑  收藏  举报