Vue源码学习(一):数据劫持(对象类型)
好家伙,了解一下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源码学习(一):数据劫持(对象类型)的更多相关文章
- Vue源码学习之数据初始化
首发地址:CJWbiu's Blog 在这里思考一个问题,使用Vue的时候需要在创建Vue实例时传入一个option,这里包含了我们定义的props.methods.data等.而在methods的方 ...
- Vue源码学习二 ———— Vue原型对象包装
Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...
- 【Vue源码学习】依赖收集
前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...
- Vue源码学习1——Vue构造函数
Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...
- Vue源码学习三 ———— Vue构造函数包装
Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...
- 最新 Vue 源码学习笔记
最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...
- 【Vue源码学习】响应式原理探秘
最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...
- Vue 源码学习(1)
概述 我在闲暇时间学习了一下 Vue 的源码,有一些心得,现在把它们分享给大家. 这个分享只是 Vue源码系列 的第一篇,主要讲述了如下内容: 寻找入口文件 在打包的过程中 Vue 发生了什么变化 在 ...
- Vue2.0源码学习(1) - 数据和模板的渲染(上)
准备 一.首先去GitHub上把vue源码download下来,传送门:https://github.com/vuejs/vue 二.搭建一个vue-cli跑起来,用于代码调试,不看着代码动起来只看源 ...
- Vue源码中的数据代理
直接开讲: 由于这个Vue底层封装的函数太多了,我这里只讲思路不说具体的执行了什么函数. const vm=new Vue({这里写一个data,可以是对象也可以是函数}) 在写这段代码的时候 ...
随机推荐
- vue入门第一坑:Eslint
Eslint是语法检查插件,它会严格要求你的代码,就你本身代码没错,但是一运行,Eslint就跳出来报错了.它会自动检查你的代码是否符合规范.所以,建议新手入门Vue创建项目的时候可以关掉Eslint ...
- 深入理解 python 虚拟机:花里胡哨的魔术方法
深入理解 python 虚拟机:花里胡哨的魔术方法 在本篇文章当中主要给大家介绍在 cpython 当中一些比较花里胡哨的魔术方法,以帮助我们自己实现比较花哨的功能,当然这其中也包含一些也非常实用的魔 ...
- HTML转为PDF,图片导出失败的终极解决方案
如题项目有需求将一个页面导出为pdf,然而页面中的图片却始终无法导出成功 文章目录 一.导出的方法 二.初步测试的结果 三.使用f12查找原油 四.方案一 五.方案二 六.方案三 七.完整代码 1.使 ...
- 多线程合集(三)---异步的那些事之自定义AsyncTaskMethodBuilder
引言 之前在上一篇文章中多线程合集(二)---异步的那些事,async和await原理抛析,我们从源码去分析了async和await如何运行,以及将编译后的IL代码写成了c#代码,以及实现自定义的Aw ...
- FTL潜规则:调优,才是算法精华
前言 在存储领域中有一个FTL的概念,这是一种Flash的内存管理算法,属于各个厂商的核心机密,每个厂商的处理方式不同,有的处理简单,有的处理复杂. FTL,即Flash Translations l ...
- ChatGPT:免费在线聊天网页版,探索智能人机交互的便捷新方式!
当今,机器智能相当流行.而在线人工智能聊天系统的兴起大大改变了我们与计算机互动的方式.本文将介绍一款名为 ChatGPT 的在线免费智能聊天网页版,让你体验智能对话的便利性. ChatGPT 是一种基 ...
- 2023-06-25:redis中什么是缓存穿透?该如何解决?
2023-06-25:redis中什么是缓存穿透?该如何解决? 答案2023-06-25: 缓存穿透 缓存穿透指的是查询一个根本不存在的数据,在这种情况下,无论是缓存层还是存储层都无法命中.因此,每次 ...
- Linux系统运维之MYSQL数据库集群部署(主从复制)
一.介绍 Mysql主从复制,前段时间生产环境部署了一套主从复制的架构,当时现找了很多资料,现在记录下 二.拓扑图 三.环境以及软件版本 主机名 IP 操作系统 角色 软件版本 MysqlDB_Mas ...
- Python运维开发之路《函数》
函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可以自己创建函 ...
- 🎉Avalonia 11.0.0 正式版发布
Avalonia 11.0.0 正式版发布! AvaloniaUI 发布11.0.0正式版 终于avalonia发布了正式版. 更新内容 A11y(辅助功能) 这个版本的Avalonia在使应用程序更 ...