好家伙,了解一下Vue如何实现数据劫持
首先,我得搞清楚这玩意的概念,我们先从vue的使用开始吧
想想看,我们平时是如何使用vue的data部分的?
无非是这两种情况
(你可千万不要带着惊讶的表情说"啊!原来有两种写法的吗")
**//函数写法
data() {
return {
msg: "I like beef"
}
}
//对象写法
data:{
return {
msg: "I like beef"
}
}**
像这样:
对属性的读取和修改拦截
简单来说就是数据的任何变化都要能监测到,这样才能根据数据变化做对应操作
就像"劫持"这个词的意思"抢过里来,盯着"
Vue2最好用的部分----响应式数据,数据一经更改,页面上的数据就会进行局部更新
如果不进行数据劫持,不知道数据状态就无法更新数据
然后我们开始思考,数据劫持是从什么时候开始的?
在 Vue 中,数据劫持是在创建 Vue 实例时完成的。
具体来说,当你实例化一个 Vue 对象时,Vue 会通过使用 Object.defineProperty() 方法来劫持(或称为监听)对象的属性,以便在属性被访问或修改时能够执行相应的操作。
Vue 的数据劫持是通过将数据对象传递给一个称为“响应式系统”的函数来实现的。
这个函数会遍历数据对象的所有属性,并为每个属性设置 getter 和 setter。
当我们获取或修改这些属性时,getter 和 setter 会触发对应的操作,以实现数据的响应式更新。
(并非源码,这是一个例子)
**//对对象中的属性进行劫持
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
}
})
}**
深度代理明天更…
手机扫一扫
移动阅读更方便
你可能感兴趣的文章