vue响应式原理简述(vue3 第二天vue响应式原理以及ref和reactive区别)
前言:
前天我们学了 ref 和 reactive ,提到了响应式数据和 Proxy ,那我们今天就来了解一下 ,vue3 的响应式
在了解之前 ,先复习一下之前 vue2 的响应式原理
vue2 的响应式:
原理:
对象类型:通过 Object.defineProperty() 对象的读取 ,修改进行拦截 ,也就是数据劫持 ,响应式的根基
缺点:因为只有 读取和修改(get ,set)所以新增属性 ,和删除属性 ,页面是不会刷新的
数组类型:通过重写 ,更新数组的一系列方法来实现拦截 ,假如你调了一个数组的 push 方法,其实 push 是被二次重写封装的(对数组的变更方法进行了重写)
缺点:直接通过下标修改数组 ,页面不会更新
解决方法:用 this.$set(数据 ,添加名字,添加内容) ,this.$delete(数据 ,删除的数据名)
vue3 的响应式:
通过 Proxy 代理 :拦截对象中任意属性的变化 ,包括增 ,删 ,改 ,查
通过 Reflect 反射 : 对被代理对象(源对象)的属性进行操作
这差不多就是 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
计算属性 ,computed函数
与 vue2 中的 computed 配置功能一致
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 :不用指明监视属性,监视的回调中使用了那个属性 ,就默认监视那几个属性
watchEffect 和 computed 有点相识
不一样的是 ,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
constx2 =
preson.job.j1.salary
console.log(所指定的 watchEffect 的回调执行了
)
})
这就是今天的全部内容 ,我们明天见!这里是六扇有伊人
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!