好家伙,了解一下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. OpenAI 官宣首个 ChatGPT iOS 应用

    最近,OpenAI 宣布推出官方 iOS 应用,允许用户随时随地访问其高人气 AI 聊天机器人,此举也打破了近几个月内苹果 App Store 上充斥似是而非的山寨服务的窘境. 该应用程序是 Chat ...

  2. Windows与网络基础

    Windows 基础命令 一.目录和文件的应用操作 1.cd命令 cd /d d:\ //切换到d盘目录,因为改变了驱动器,所以要加上/d选项 cd c:\ //如果没有改变驱动器号,就不需要加/d选 ...

  3. Spring源码:Bean生命周期(终章)

    前言 本系列前面讲解了Spring的bean定义.bean实例化.bean初始化等生命周期.这些步骤使我们能够了解bean从创建到准备好使用所经历的过程.但是,除了这些步骤,bean的销毁也是非常重要 ...

  4. odoo开发教程四:onchange、唯一性约束

    一:onchange机制[onchange=前端js函数!可以实现前端实时更新以及修改验证] onchange机制:不需要保存数据到数据库就可以实时更新用户界面上的显示. @api.onchange( ...

  5. java中单例模式 如何使用

    引用: 原文链接:https://blog.csdn.net/qq_41458550/article/details/109243456

  6. Mysql基础篇(三)之多表查询

    一. 多表关系 一对多(多对一) 多对一 一对一 1. 一对多 (1). 案例:部门与员工的关系 (2). 关系:一个部门对应多个员工,一个员工对应一个部门 (3). 实现:在多的一方建立外建,指向一 ...

  7. MODBUS RTU转 EtherNet/IP 网关连接森兰变频器与欧姆龙系统通讯

      捷米特JM-EIP-RTU(Modbus转Ethernet/Ip)网关,用于将多个 MODBUS 从站设备接入 ETHERNET/IP 主站网络,实现 MODBUS 转 ETHERNET/IP 功 ...

  8. zabbix 修改模板中单个主机的触发器

    参考文档:zabbix 修改模板中单个主机的触发器 在主机的 Triggers,克隆后修改,再disable原来的触发器.

  9. test.sh

    #!/bin/bash echo "=== show OS version ===" cat /etc/os-release echo "=== show IP addr ...

  10. Robot Framework 自动化测试部署常见问题及处理方法(一)

    1.在Python>>Scripts中运行python ride.py时报错 现象: 1 Traceback (most recent call last): 2 File "E ...