Vue双向数据绑定原理-下这一篇文章主要讲解Vue双向数据绑定的原理,主要是通过Object.defineProperty()来实现的,这里我们手写Vue双向数据绑定的原理。

首先我提出一个需求,我的需求是,快速监听对象中所有属性的变化

首先得要有一个对象,对象的定义代码如下:

<script>
let obj = {
name: 'BNTang',
age: 33
};
</script>

然后我们需要监听这个对象中所有属性的变化,最最最简单的做法如下,这里我们可以使用Object.defineProperty()来实现,代码如下:

Object.defineProperty(obj, 'name', {
get() {
return 'BNTang';
},
set(newValue) {
}
}); Object.defineProperty(obj, 'age', {
get() {
return 18;
},
set(newValue) {
}
});

这样我们就可以监听到对象中所有属性的变化了,但是这样写的话,代码量太大了,如果有100个属性,那么就要写100次,这样的话,代码量太大了,所以我们需要写一个函数来实现这个功能(例如自定义类)。

博主这里采用的是自定义类的方式来实现,首先定义一个类,代码如下:

class Observer {

}

只要将需要监听的那个对象传递给Observer这个类,这个类就可以快速的给传入的对象的所有属性都添加get/set方法, 该类的主要功能就是给传入的对象的所有属性都添加get/set方法。

首先我定义了一个构造函数,绑定了一个形参,就是需要监听的对象,代码如下:

constructor(data) {
}

在然后我定义了一个 observer 方法,将需要监听的对象传递给 observer 方法,遍历取出传入对象的所有属性,给遍历到的属性都增加get/set方法,代码如下:

observer(obj) {
if (obj && typeof obj === 'object') {
for (let key in obj) {
}
}
}

在 for 循环中,我使用了 defineReactive 方法(自定义一个方法单独来处理),该方法的作用是给传入的对象的所有属性都添加get/set方法,代码如下:

defineReactive(obj, attr, value) {
Object.defineProperty(obj, attr, {
get() {
return value;
},
set: (newValue) => {
if (value !== newValue) {
value = newValue;
console.log('监听到数据的变化, 需要去更新UI');
}
}
})
}

好了,现在我们已经定义了一个类,该类的主要功能就是给传入的对象的所有属性都添加get/set方法,那么我们就可以使用这个类了(Test 阶段),代码如下:

new Observer(obj);
obj.name = 'Example';

查看打印结果,可以看到,我们已经监听到了数据的变化,但是这里有一个问题,就是我们只能监听到对象中已经存在的属性的变化,不能监听对象中属性的对象的属性的变化,例如下面的对象代码:

let obj = {
name: {a: 'abc'},
age: 33
};

就是对象中的属性值又是一个对象,而这个属性的对象的属性值发生改变,我们自定义的 Observer 是无法进行监听到的。所以我们需要对这个问题进行处理(如果属性的取值又是一个对象, 那么也需要给这个对象的所有属性添加get/set方法)。

this.observer(value);

测试一下:

obj.name.a = 'Example';

可以看到,我们已经可以监听到对象中属性的对象的属性值的变化了。

但是这里还有一个问题,就是如果对象中的属性值是一个基本数据类型,我们在给这个对象绑定完毕get/set方法之后,再给这个对象赋值的时候, 赋值成了引用类型, 新赋值的属性的对象的值是不会被监听到的。例如下面的代码:

<script>
let obj = {
name: 'BNTang',
age: 33
}; class Observer {
constructor(data) {
this.observer(data);
} observer(obj) {
if (obj && typeof obj === 'object') {
for (let key in obj) {
this.defineReactive(obj, key, obj[key]);
}
}
} defineReactive(obj, attr, value) {
this.observer(value);
Object.defineProperty(obj, attr, {
get() {
return value;
},
set: (newValue) => {
if (value !== newValue) {
value = newValue;
console.log('监听到数据的变化, 需要去更新UI');
}
}
})
}
} new Observer(obj);
obj.name = {a: 'abc'};
obj.name.a = 'BNTang';
</script>

运行结果:

可以看到,只能监听到对象属性值初始化的时候的变化,不能监听到对象属性值重新赋值的为对象的属性值的变化。

所以我们需要对这个问题进行处理,我们需要在给对象属性值重新赋值的时候,给这个对象属性值重新绑定get/set方法(如果给属性赋值的新值又是一个对象, 那么也需要给这个对象的所有属性添加get/set方法),代码如下:

运行结果:

Vue双向数据绑定原理-下的更多相关文章

  1. vue双向数据绑定原理简单实现

    vue双向数据绑定原理实现 准备工作 ​ 新建一个index.js文件, 一个index.html文件 ​ index.js文件中, 定义Vue类, 并将Vue并称全局变量 window.Vue = ...

  2. vue双向数据绑定原理探究(附demo)

    昨天被导师叫去研究了一下vue的双向数据绑定原理...本来以为原理的东西都非常高深,没想到vue的双向绑定真的很好理解啊...自己动手写了一个. 传送门 双向绑定的思想 双向数据绑定的思想就是数据层与 ...

  3. Vue双向数据绑定原理分析(转)

    add by zhj: 目前组里使用的是前端技术是jQuery + Bootstrap,后端使用的Django,Flask等,模板是在后端渲染的.前后端没有分离,这种做法有几个缺点 1. 模板一般是由 ...

  4. Vue双向数据绑定原理深度解析

    首先,什么是双向数据绑定?Vue是三大MVVM框架之一,数据绑定简单来说,就是当数据发生变化时,相应的视图会进行更新,当视图更新时,数据也会跟着变化. 在分析其原理和代码的时候,大家首先了解如下几个j ...

  5. 手写MVVM框架 之vue双向数据绑定原理剖析

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. Vue双向数据绑定原理解析

    基本原理 Vue.采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter和getter,数据变动时发布消息给订阅者,触发相应函数的回调 ...

  7. Vue 双向数据绑定原理分析 以及 Object.defineproperty语法

    第三方精简版实现 https://github.com/luobotang/simply-vue Object.defineProperty 学习,打开控制台分别输入以下内容调试结果 userInfo ...

  8. vue 双向数据绑定原理

    博客地址: https://ainyi.com/8 采用defineProperty的两个方法get.set 示例 <!-- 表单 --> <input type="tex ...

  9. Vue双向数据绑定原理

    https://www.cnblogs.com/kidney/p/6052935.html?utm_source=gold_browser_extension

  10. 详解 vue 双向数据绑定的原理,并实现一组双向数据绑定

    1:vue 双向数据绑定的原理: Object.defineProperty是ES5新增的一个API,其作用是给对象的属性增加更多的控制Object.defineProperty(obj, prop, ...

随机推荐

  1. Unsatisfied dependency expressed through field 'restTemplate';

    Test 报错时,添加@注释 解决方案: @SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)错误如下: ...

  2. Intellij 查找排除JAR包的依赖关系(Maven Helper)

    Intellij 查找排除JAR包的依赖关系(Maven Helper) 安装插件 Windows 类似

  3. Linux CentOS 8 安装DHCP服务

    DHCP 如果虚拟机没有 /etc/dhcp/dhcpd.conf 文件,这可能是因为 DHCP 服务器软件包尚未安装,或者安装后配置文件未创建. 要创建 DHCP 服务器配置文件 dhcpd.con ...

  4. 柔性上肢康复机器人研究中的VR技术

    上肢康复机器人用于对脑卒中患者进行上肢康复治疗,能够维持和扩大患者关节活动度.增强肌肉力和协调性,以防止肌肉萎缩.关节痉挛等各类症状的出现,最终重建肢体功能,以便回归正常生活.现有的上肢康复机器人训练 ...

  5. Go--Println、Printf区别

    Println:打印字符串.变量:    同函数输出多项,之间存在空格    不同函数输出自动换行 Printf:打印需要格式化的字符串,可以输出字符串类型的变量:不可以输出整型变量和整型   同函数 ...

  6. nginx: [emerg] duplicate upstream "test2" in /usr/local/nginx/conf/sites-enabled/test2.conf:1

    使用/usr/local/nginx/sbin/nginx -t 检查nginx配置文件时报错: nginx: [emerg] duplicate upstream "test2" ...

  7. KMP 复习笔记

    KMP 学习(复习)笔记 KMP(Knuth-Morris-Pratt)是算法竞赛中常用的字符串匹配算法之一,它可以有效地利用失配信息来使得匹配全过程中不回溯,从而在线性时间内完成匹配. 本文已有前置 ...

  8. .NET静态代码织入——肉夹馍(Rougamo)发布2.2

    肉夹馍(https://github.com/inversionhourglass/Rougamo)通过静态代码织入方式实现AOP的组件,其主要特点是在编译时完成AOP代码织入,相比动态代理可以减少应 ...

  9. JS - 兼容到 IE 8

    使用 jQuery可以有效的兼容IE 浏览器 , 但jQuery从2.0开始不兼容IE8,最低支持IE9,所以需要引入更低的jQuery版本来兼容 <script type="text ...

  10. 【水一篇】骚操作之net 6的winform启动的同时启动Net 6 WebApi【同一套代码】

    引言 有段时间没有写博客了,不知道写什么,加上最近一直在玩单片机方面的东西,所以有一些懈怠.首先呢,为什么会有这么一个问题,是在一个QQ群里,有看到有人提问,能不能在启动Winform的同时去启动一个 ...