发布时间:2022-11-29 文章分类:编程知识 投稿人:李佳 字号: 默认 | | 超大 打印

前言:

前天我们学了 ref 和 reactive ,提到了响应式数据和 Proxy ,那我们今天就来了解一下,vue3 的响应式

在了解之前,先复习一下之前 vue2 的响应式原理

vue2 的响应式:

原理:

对象类型:通过 Object.defineProperty() 对象的读取,修改进行拦截,也就是数据劫持,响应式的根基

缺点:因为只有 读取和修改(get,set)所以新增属性,和删除属性,页面是不会刷新的

数组类型:通过重写,更新数组的一系列方法来实现拦截,假如你调了一个数组的 push 方法,其实 push 是被二次重写封装的(对数组的变更方法进行了重写)

缺点:直接通过下标修改数组,页面不会更新

解决方法:用 this.$set(数据,添加名字,添加内容),this.$delete(数据,删除的数据名)

vue3 的响应式:

通过 Proxy 代理 :拦截对象中任意属性的变化,包括增,删,改,查

通过 Reflect 反射 : 对被代理对象(源对象)的属性进行操作

newProxy(data,{

//拦截读取的属性值

get(target,prop){

returnReflect.get(targert,prop)

}

//拦截设置和添加

set(target,prop,value){

returnReflect.set(targert,prop,value)

}

//拦截删除

deleteProperty(target,prop){

returnReflect.deleteProperty(targert,prop)

}

})

这差不多就是 vue3 响应式的简单原理,Proxy 比较之前的Object.defineProperty 功能更详细,和强壮

reactive 与 ref 的区别:

定义:

ref:用来定义基本数据类型

reactive:用来定义对象(数组)类型数据

ps:ref 也可以用来定义对象(或数组)类型数据,内部求助了 reactive

原理:

ref: 通过Object.defineProperty()的 get 与 set 来实现响应式也就是数据劫持

reactive:通过使用 Proxy 来实现响应式,并用 Reflect 操作源对象内部数据

使用:

ref:用 ref 定义的数据,操作需要 .value

reactive: 定义的数据,操作不需要

setup 的注意:

setup 的执行时机是在 beforeCreate 之前执行,this 是 undefined

setup的参数:

props :值为对象,包含:组件外部传递过来,并且组件内部声明接收了的属性

context:上下文对象,有三个值分别是 attrs,slots,emit

attrs :对象,没有在props 声明配置的属性,相当于 vue2 的 this.$attrs

slots :插槽,相当于 this.$slots

emit :分发自定义事件的函数,相当于 this.$emit

vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天

计算属性,computed函数

与 vue2 中的 computed 配置功能一致

vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天

watch 函数监听:

与 vue2 中的 watch 配置功能一致

watch 监视 ref 基本数据:

情况一 :监视 ref 定义的一个响应式数据

let sum = ref(0)

watch(sum,(newValue,oldValue)=>{

console.log('监听sum变了',newValue,oldValue)

})

情况二:监视 ref 定义的多个响应式数据

let msg = ref('你好啊')

let sum = ref(0)

watch([sum,msg],(newValue,oldValue)=>{

console.log('监听sum变了',newValue,oldValue)

},{immediate:true})

ps:watch 一共可以传递三个值,第一个 监视的数据,监视的行为,watch 的配置

watch 监视reactive 对象:

情况三:监视 reactive所定义数据中的全部属性

let preson = reactive({

name:'六扇老师',

age:18

})

watch(preson,(newValue,oldValue)=>{

console.log('监听preson变了',newValue,oldValue)

},{deep:false}) // 此处的 deep 配置无效

ps:此处无法正确的获得 oldValue,是 reactive 的问题无法解决

强制开启深度监视( deep 配置无效)

情况四:监视reactive 所定义数据中的某一个属性

watch(()=>preson.name,(newValue,oldValue)=>{

console.log('监听preson.name变了',newValue,oldValue)

})

情况五:监视 reactive 所定义数据中的某些属性

watch([()=>preson.name,()=>preson.age],(newValue,oldValue)=>{

console.log('监听preson.name/preson.age变了',newValue,oldValue)

})

特殊情况:

let preson =reactive({

name:'六扇老师',

age:18,

job:{

j1:{ salary:30}

}

})

watch(()=>preson.job,(newValue,oldValue)=>{

console.log('监听preson.job变了',newValue,oldValue)

},{deep:true})

ps:如果单独监视reactive 对象里面的对象的数据,则必须开启 deep:true 深度监视,否则监视无效

watchEffect 函数:

watchEffect 函数是 vue3 新增的一个函数

watch 区别:

watch:既要指明监视属性,也要指明监视的回调

watchEffect :不用指明监视属性,监视的回调中使用了那个属性,就默认监视那几个属性

watchEffectcomputed 有点像似

不一样的是,computed 注重计算出来的值,回调函数的返回值,所以必须要写返回值

watchEffect 更注重过程,回调函数的函数体,所以不用写返回值

let sum = ref(0)

let preson=reactive({

name:'六扇老师',

age:18,

job:{

j1:{ salary:30}

}

})

//watchEffect vue3 新增

//默认开启 immediate,也有 deep

watchEffect(()=>{

const x1=sum.value const

x2=preson.job.j1.salary

console.log('所指定的 watchEffect 的回调执行了')

})

vue2 和 vue3 生命周期对比:

vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天

vue2 开始不管你有没有使用都会先执行俩个钩子,然后才会去判断,vue3 则不会得明确得告诉 app 你服务于那个容器,才开始走,更智能了

剩下得生命周期都相差不多,但在 vue3 里用 beforeUnmount (卸载之前)和 unmounted (卸载完毕)替换了 beforeDestroy (销毁之前) 和 destroyed (销毁完毕),和 react 像似了

组合式 api 里面的生命周期:

用组合式 api 往 setup 里面写的生命周期,这种写法不见得非要用,只是了解就行,问题不大

beforeCreate setup
created setup

beforeCreate 和created 这俩钩子 vue3 并没有给我们提供组合式 api ,放不进去 setup,setup 就相当于他们俩个

beforeMount onbeforeMount
mounted onmounted
beforeUpdate onbeforeUpdate
updated onupdated
beforeUnmount onbeforeUnmount
unmounted onunmounted

就是在之前的生命周期,加上一个 on,而且 setup 的优先级更高

自定义 hook 函数:

hook 本质是一个函数,把 setup 函数中使用的 组合式 API 进行了自定义封装

类似于 vue2 中的 mixin

自定义 hook 复用代码,可以让 setup 中的逻辑更清楚,更容易懂,更简单

vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天

toRef:

创建一个 ref 对象,其 value 值指向另一个对象中的某个属性

回到我们之前的代码

vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天

可以看到页面上,想要获取数据,就要preson 点什么什么一大堆,看着也不美观,这时候就要用到 toRef 了

toRef 语法 : const name = toRef (preson ,‘nama’) 第一个参数对象,第二个是对象里的那个值

vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天

toRefs:

toRef 的升级版,可以批量处理一个对象里的所有属性

vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天

以上就是我们常用的组合式 API 了,知道了这些差不多就完成了一个 vue3 的入门,明天我们开始学习一些不常用的组合式 API ,虽然不常用当还是要了解滴,所以我们明天再见