手写vue2.0源码三之data对象响应式
文章类型:Vue
发布者:hp
发布时间:2023-05-25
前面已经实现了通过vm.xxx来获取数据,但是数据不是响应式的,这节,将对对象进行响应式处理,就需要用到观察者模式
一:初始化的时候,定义一个方法来观察,观察数据
/*
我们就需要观察这些对象
*/
observe(data)
二:把数据进行判断是否存在,存在则交给一个专门的函数,观察者去处理
/*
观察数据
*/
import Observer from "./observer"
export default function observe(data){
if(typeof data!=='object' || data===null) return
/*否则就需要把数据交给观察者 */
return new Observer(data)
}
三:观察者拿到具体的数据,那么就需要进行区分,是对象还是数组,走不同的方法去处理
export default function Observer(data){
/*
针对对象和数组方式
采取不一样的方式
说白了就是不同的处理方式
*/
if(Array.isArray(data)){
//数组
}else{
//对象
this.walk(data)
}
}
四:针对对象,挂载一个原型方法去处理,循环找到每个属性,然后交给另外一个函数去专门处理对象
//增加一个原型方法
Observer.prototype.walk=function(data){
/*
这里就需要对对象的所有属性进行重新定义
绑定get,set方法
*/
var keys=Object.keys(data)
console.log(keys)
for (let index = 0; index < keys.length; index++) {
var key=keys[index],
value=data[key]
defineReactiveData(data,key,value)
}
}
五:专门处理对象响应式的函数,进行添加get,set,对象里面也阔能是对象,那么就需要重新走之前的逻辑,也就是观察->观察者->数据处理,说白了就是递归进行
export default function defineReactiveData(data,key,value){
/*value
有阔能还是数组或者对象
那么就还需要进行递归遍历
*/
observe(value)
Object.defineProperty(data,key,{
get(){
console.log("响应式读取",value)
return value
},
set(newValue){
/*修改的时候,如果相等,那么就没必要修改 否则修改 */
if(newValue===value) return
/*有可能还是对象数组,那么又重新观察->观察者->数据属性添加 */
observe(value)
value=newValue
}
})
}
六:这样就实现响应式了,每个对象属性都添加了get,set,通过读取能触发到
let vm=new Vue({
el:'#app',
data(){
return{
msg:456,
info:{
name:'张三',
age:18
}
}
}
})
console.log('vm')
console.log(vm)
console.log(vm.info.name)