Vue2.0与Vue3.0的区别

Vue2.0

Vue3.0

双向绑定

利用ES5的ApiObject.defineProperty()对数据进行劫持,并结合发布订阅模式的方式实现

利用Es6的Proxy 对数据进行代理的方式实现

根节点

根节点只能是一个

根节点可以是多个

数据监听

computed watch

computed watch watcheffect

指令优先级

v-for优先于v-if生效

v-if优先于v-for生效

Diff算法

双端比较算法

去头尾的最长子序列算法

生命周期

beforeCreated组件创建之前

created组件创建之后

beforeMount组件挂载到页面之前执行

mounted组件挂载到页面之后执行

beforeUpdate组件更新之前

updated组件更新之后

set up开始创建组件

onBeforeMounted组件挂载到页面之前执行

onMounted组件挂载到页面之后执行

onBeforeUpdate组件更新之前执行

onUpdated组件更新之后

Object.defineProperty && Proxy

Object.defineProperty缺点:

  1. 只能针对对象的一个属性,也只能监听某个属性的第一层,如果对象里面还有对象是监听不了的,如果要对整个对象实行响应式需要自己去递归整个对象

  1. 无法监听数组的变化,Vue2对数组实现劫持的防方法是重写一些数组的方法

  1. 对象新增加的属性也不能劫持

let obj ={
    name:'小明',
    age:18,
    obj1:{
    sex:'男'
    }
}
function watchProperty(obj,key,val){
   Object.defineProperty(obj,key,{
    get(){
            console.log('get',key)
            return val
        },
    set(value){
            console.log('set')
            val=value
        }
    }) 
}

function watchObj(obj){
    object.keys(obj).forEach(key=>{
        const value = obj[key]
        if(value instanceof Object && !Array.isArray(value)){
            watchObj(value)
        }
        watchProperty(obj,key,value)
    })
}
watchObj(obj)

Proxy:

在Vue3中运用的是Proxy,他在目标对象之前架设一层“拦截”,外界对该对象的访问们都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写

补充:proxy也只能拦截一层对象,如果对象里面有新的对象就要用递归来劫持

let obj ={
    name:'小明',
    age:18,
    obj1:{
    sex:'男'
    },
    arr:[1,2,3,4,5,6]
}
function toProxy(obj){
    object.keys(obj).forEach(key=>{
        const value = obj[key]
        if(value instanceof Object ){
            obj[key] = toProxy(value)
        }
    })

    return new Proxy(obj,{
        get:function(taget,key){
            console.log(key,'get')
            return taget[key]
        },
        set(taget,key,val){
            console.log(key,'set')
            taget[key] = val
        },
    })
}

watch和watchEffect的区别

Vue3 中的组合式 API 中,watch 的作用和 Vue2 中的 watch 作用是一样的,他们都是用来监听响应式状态发生变化的,当响应式状态发生变化时,都会触发一个回调函数。

watch 基本用法

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <p>{{ message }}</p>
  <button @click="changeMsg">更改 message</button>
</template>
<script setup lang="ts">
import { ref, watch } from "vue";


const message = ref("姓名");
watch(message, (newValue, oldValue) => {
  console.log("新的值:", newValue);
  console.log("旧的值:", oldValue);
});
const changeMsg = () => {
  message.value = "张三";
};
</script>

上段代码中我们点击按钮就会更改响应式变量 message 的值。我们又使用 watch 监听器监听了 message 变量,当它发生变化时,就会触发 watch 监听函数中的回调函数,并且回调函数默认接收两个参数:新值和旧值。

watch 监听类型

前面我们一直强调 watch 监听的是响应式数据,如果我们监听的数据不是响应式的,那么可能会抛出警告

1、ref 和计算属性

ref 定义的数据我们是可以监听到的,因为我们前面的代码以及证明了。除此之外,计算属性也是可以监听到的,比如下列代码:

2、getter 函数

这里的 getter 函数大家可以简单的理解为获取数据的一个函数,说白了该函数就是一个返回值的操作,有点类似与计算属性。

3、监听响应式对象

4、监听多个来源的数组

const x1 = ref(12);
const number = reactive({ count: 0 });
const countAdd = () => {
  number.count++;
};
watch([x1, () => number.count], (newValue, oldValue) => {
  console.log("新的值:", newValue);
  console.log("旧的值:", oldValue);
});

3.watchEffect

我们前面使用 watch 监听数据状态时,不知道大家有没有发现这样一个问题:只有当我们监听的数据源发生了变化,监听函数的回调函数才会执行。但是需求总是多变的,有些场景下我们可能需要刚进页面,或者说第一次渲染页面的时候,watch 监听器里面的回调函数就执行一遍。

watchEffect 也是一个监听器,只不过它不会像 watch 那样接收一个明确的数据源,它只接收一个回调函数。而在这个回调函数当中,它会自动监听响应数据,当回调函数里面的响应数据发生变化,回调函数就会立即执行。

所以我们可以将方式一中的代码使用 watchEffect 优雅的实现。

const number = reactive({ count: 0 });
const countAdd = () => {
  number.count++;
};
watchEffect(()=>{
  console.log("新的值:", number.count);
})

4.watch 和 watchEffect 区别

我们已经大概知道了 watch 和 watchEffect 的用法,那么它们之间的区别相信大家也了解了一些,这里我们总结一下它们之间的区别。

  • watch 和 watchEffect 都能监听响应式数据的变化,不同的是它们监听数据变化的方式不同。

  • watch 会明确监听某一个响应数据,而 watchEffect 则是隐式的监听回调函数中响应数据。

  • watch 在响应数据初始化时是不会执行回调函数的,watchEffect 在响应数据初始化时就会立即执行回调函数

手动停止监听器

通常来说,我们的一个组件被销毁或者卸载后,监听器也会跟着被停止,并不需要我们手动去关闭监听器。但是总是有一些特殊情况,即使组件卸载了,但是监听器依然存在,这个时候其实式需要我们手动关闭它的,否则容易造成内存泄漏。

比如下面这中写法,我们就需要手动停止监听器:

<script setup>
import { watchEffect } from 'vue'
// 它会自动停止
watchEffect(() => {})
// ...这个则不会!
setTimeout(() => {
  watchEffect(() => {})
}, 100)
</script>
const unwatch = watchEffect(() => {})
// ...当该侦听器不再需要时
unwatch()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值