好家伙,了解一下Vue如何实现数据劫持

1.Vue中data的使用

首先,我得搞清楚这玩意的概念,我们先从vue的使用开始吧

想想看,我们平时是如何使用vue的data部分的?

无非是这两种情况

(你可千万不要带着惊讶的表情说"啊!原来有两种写法的吗")

//函数写法
data() {
return {
msg: "I like beef"
}
}

//对象写法
data:{
return {
msg: "I like beef"
}
}

 像这样:

 

2.那么什么是数据劫持?

对属性的读取和修改拦截

简单来说就是数据的任何变化都要能监测到,这样才能根据数据变化做对应操作

就像"劫持"这个词的意思"抢过里来,盯着"

3.为什么要用数据劫持?

Vue2最好用的部分----响应式数据,数据一经更改,页面上的数据就会进行局部更新

如果不进行数据劫持,不知道数据状态就无法更新数据

 

4.如何实现数据劫持

然后我们开始思考,数据劫持是从什么时候开始的?

在 Vue 中,数据劫持是在创建 Vue 实例时完成的

具体来说,当你实例化一个 Vue 对象时,Vue 会通过使用 Object.defineProperty() 方法来劫持(或称为监听)对象的属性,以便在属性被访问或修改时能够执行相应的操作。

Vue 的数据劫持是通过将数据对象传递给一个称为“响应式系统”的函数来实现的。

这个函数会遍历数据对象的所有属性,并为每个属性设置 getter 和 setter。

当我们获取或修改这些属性时,getter 和 setter 会触发对应的操作,以实现数据的响应式更新。

5.代码部分:

(并非源码,这是一个例子)

//对对象中的属性进行劫持
function defineReactive(data, key, value) {
Object.defineProperty(data, key, {
get() {
// console.log('获取')
return value
},
set(newValue) {
// console.log('设置')
if (newValue == value) {
return;
}
value = newValue
}
}) }

关于defineProperty()方法:Object.defineProperty() - JavaScript | MDN (mozilla.org)

这是一个简化版的数据劫持示例。

这个 defineReactive() 函数接受一个数据对象 `data`、一个属性名 `key` 和初始值 `value`,并使用 Object.defineProperty() 方法定义了一个 getter 和一个 setter。

在 getter 中,当获取属性值时,会返回存储在 `value` 变量中的当前值。

在 setter 中,当尝试设置属性值时,会将新值存储在 `value` 变量中,

这个 defineReactive() 函数可以用于对对象中的某个属性进行劫持,使得在对该属性进行访问或修改时能够触发相应的操作。

完整的例子:

export function observer(data) {
// console.log(data) //判断数据
if (typeof data != 'object' || data == null) {
return data
}
//对象通过一个类
return new Observer(data)
} class Observer {
constructor(value) {
Object.defineProperty(value, "__ob__", {
enumerable: false,
value: this
})
//判断数据
// console.log(value)
if (Array.isArray(value)) {
//value.__proto__ = ArrayMethods
// console.log("shuzhu")
//如果你是数组对象
//this.observeArray(value)
} else {
this.walk(value)
}
}
walk(data) {
let keys = Object.keys(data)
for (let i = 0; i < keys.length; i++) { //对象我们的每个属性进行劫持
let key = keys[i]
let value = data[key]
defineReactive(data, key, value)
} }
observeArray(value) { //[{a:1}]
for (let i = 0; i < value.length; i++) {
observer(value[i])
}
}
}
//对对象中的属性进行劫持
function defineReactive(data, key, value) {
observer(value) //深度代理
Object.defineProperty(data, key, {
get() {
// console.log('获取')
return value
},
set(newValue) {
// console.log('设置')
if (newValue == value) {
return;
}
observer(newValue)
value = newValue
}
}) }

 深度代理明天更...

 

Vue源码学习(一):数据劫持(对象类型)的更多相关文章

  1. Vue源码学习之数据初始化

    首发地址:CJWbiu's Blog 在这里思考一个问题,使用Vue的时候需要在创建Vue实例时传入一个option,这里包含了我们定义的props.methods.data等.而在methods的方 ...

  2. Vue源码学习二 ———— Vue原型对象包装

    Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...

  3. 【Vue源码学习】依赖收集

    前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...

  4. Vue源码学习1——Vue构造函数

    Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...

  5. Vue源码学习三 ———— Vue构造函数包装

    Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...

  6. 最新 Vue 源码学习笔记

    最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...

  7. 【Vue源码学习】响应式原理探秘

    最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...

  8. Vue 源码学习(1)

    概述 我在闲暇时间学习了一下 Vue 的源码,有一些心得,现在把它们分享给大家. 这个分享只是 Vue源码系列 的第一篇,主要讲述了如下内容: 寻找入口文件 在打包的过程中 Vue 发生了什么变化 在 ...

  9. Vue2.0源码学习(1) - 数据和模板的渲染(上)

    准备 一.首先去GitHub上把vue源码download下来,传送门:https://github.com/vuejs/vue 二.搭建一个vue-cli跑起来,用于代码调试,不看着代码动起来只看源 ...

  10. Vue源码中的数据代理

    直接开讲: ​ 由于这个Vue底层封装的函数太多了,我这里只讲思路不说具体的执行了什么函数. ​ const vm=new Vue({这里写一个data,可以是对象也可以是函数}) 在写这段代码的时候 ...

随机推荐

  1. import MySQLdb as Database ModuleNotFoundError: No module named ‘MySQLdb‘

    import MySQLdb as Database ModuleNotFoundError: No module named 'MySQLdb' import MySQLdb as Database ...

  2. MMCM and PLL Dynamic Reconfiguration

    Reconfiguration is performed through the DRP. The DRP provides access to the configuration bits that ...

  3. Redis 高级特性 Redis Stream使用

    Redis Stream 简介 Redis Stream 是 Redis 5.0 版本新增加的数据结构. Stream从字面上看是流类型,但其实从功能上看,应该是Redis对消息队列(MQ,Messa ...

  4. 2022年第十四届四川省大学生程序设计大赛 A

    A Adjacent Swapping 题意: 给定一个字符串,每次可以移动相邻字符,求最小移动次数可以把它变成s+s这样左右两边相同的字符串. 思路: 1:我们知道他一定是偶数长度,所以我们把字符串 ...

  5. 自定义组件模拟v-model

    在项目中常常会遇到一个组件中引入好几个子组件的情况,而引入的子组件和子组件之间又需要有数据交互,如果使用父组件作为桥梁进行数据交互这个也是可以的,只是有些麻烦,so最理想的是子组件和子组件自己去交互, ...

  6. Cobalt Strike 连接启动教程(1)

      第一步:把cobaltstrike4(解压后)拷贝到虚拟机Kali系统的root目录下 第二步:进入cobalstrike4文件夹中 第三步:选寻kali系统 IP地址 第四步: 启动服务端:(t ...

  7. postman接口关联1

    1.接口关联 在接口测试中,经常会遇到后一接口的请求数据需要用到前一接口响应数据 关联接口:简单描述就是一个接口的返回结果作为另一个接口入参,其中最典型的就是需要登录token验证的接口,需要先调用登 ...

  8. 关于进程、线程、协程的概念以及Java中的应用

    进程.线程.协程 本文将从"操作系统"."Java应用"上两个角度来探究这三者的区别. 一.进程 在我本人的疑惑中,我有以下3个问题. 1.1为什么要引入进程? ...

  9. TLS详解(原理和实践)

    主页 个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/ 引言 本文主要内容涉及到TLS协议发展历程.TLS协议原理以及在HTT ...

  10. Vue项目学习

    一.二维数组尝试 var vm = new Vue({ el: "#app", data: { huilv:[ [6.8540, 132.9787, 1298.7013, 1.32 ...