vue变化侦测_vue3 检测用户是否有修改

本文介绍了Vue3中如何进行变化侦测。通过`parsePath`函数解析路径,`Observer`类创建响应式对象,`defineReactive`方法定义响应式属性,当属性值发生改变时,依赖项`Dep`会触发更新。示例展示了在用户修改对象属性或删除属性时,Vue如何响应这些变化。
摘要由CSDN通过智能技术生成

const bailRE = /[^\w.$]/;
export function parsePath(path){
if(bailRE.test(path)){
return;
}
const segments = path.split(“.”)
return function (obj){
for(let i = 0; i < segments.length; i++){
if(!obj){
return;
}
obj = obj[segments[i]];
}
return obj;
}
}


可以看到,先将keypath用.分割成数组,然后循环数组一层一层去读数据,最后拿到的obj就是keyPath中想要读的数据。


### 2.递归侦测所有key


现在,其实已经可以实现变化侦测的功能了,但是前面介绍的代码只能侦测数据中的某一个属性,我们希望把数据中的所有属性(包括子属性)都侦测到,所以要封装一个Observer类。这个类的作用是将一个数据内的所有属性(包括子属性)都转换成getter/setter的形式,然后去追踪它们的变化:



export class Observer{
constructor(value) {
this.value = value;
if (!Array.isArray(value)){
this.walk(value)
}
}

walk(obj){
    const keys = Object.keys(obj);
    for (let i = 0; i < keys.length; i++){
        defineReactive(obj, keys[i], obj[keys[i]])
    }
}

}

function defineReactive(data, key, val) {
if (typeof val == ‘object’){
new Object(val);
}
let dep = new Dep();
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function(){
dep.depend();
return val;
},
set: function(newVal){
if (val == newVal){
return;
}
val = newVal;
dep.notify();
}
})

}


在上面的代码中,我们定义了Observer类,它用来将一个正常的object转换成被侦测的object。  
 然后判断数据的类型,只有object类型的数据才会调用walk将每一个属性转换成getter/setter的形式来侦测变化。  
 最后,在defineReavtive中新增new Observer(val)来递归子属性,这样我们就可以把data中的所有属性(包括子属性)都转换成getter/setter 来侦测变化。


### 3.关于Object的问题


前面介绍了Object类型数据的变化侦测原理,了解了数据的变化是通过getter/setter来追踪的。也正是由于这种追踪方式,有些语法中即便是数据发生了变化,vue.is也追踪不到。  
 比如,向Object添加属性:



var vm = new Vue({
el: “#el”,
template: “#demo-tenplate”,
methods: {
action(){
this.obj.name = “berwin”;
}
},
data: {
obj: {}
}
})


在action方法中,我们在obj上面新增了name属性,vue无法侦测到这个变化,所以不会向依赖发送通知。  
 在比如,从obj中删除一个属性:



var vm = new Vue({
el: “#el”,
template: “#demo-tenplate”,
methods: {
action(){
delete this.obj.name;
}
},
data: {
name: ‘berwin’
}
})


在上面的代码中,我们在action方法中删除了obj中的name属性,而vue无法侦测到这个变化,所以不会向依赖发送通知。  
 vue通过Object.defineProperty来将对象的key转换成getter/setter的形式来追踪变化,但getter/setter只能追踪一个数据是否被修改,无法追踪新增属性和删除属性,所以才会导致上面的例子中提到的问题。


### 4.总结



### 最后

你要问前端开发难不难,我就得说计算机领域里常说的一句话,这句话就是『**难的不会,会的不难**』,对于不熟悉某领域技术的人来说,因为不了解所以产生神秘感,神秘感就会让人感觉很难,也就是『难的不会』;当学会这项技术之后,知道什么什么技术能做到什么做不到,只是做起来花多少时间的问题而已,没啥难的,所以就是『会的不难』。

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

**我特地针对初学者整理一套前端学习资料**

![前端路线图](https://img-blog.csdnimg.cn/img_convert/61cbaffe997b64d93289bbe96e6cc732.webp?x-oss-process=image/format,png)

题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

**我特地针对初学者整理一套前端学习资料**

[外链图片转存中...(img-OMEkhY3d-1714160799253)]

![vue.js的36个技巧](https://img-blog.csdnimg.cn/img_convert/70018317afdebbaf7db1fcceef69ef14.webp?x-oss-process=image/format,png)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值