赞
踩
vue2响应式原理:核心使用Object.defineProperty给属性定义get和set方法
注意:对象的多次递归,针对数组需要重写数组方法
函数劫持:把函数内部进行重写同时继续调用老的方法,在继承原数组方法时使用到
主要方法介绍:
updataView:模拟更新视图时触发的方法
observer:观察者
defineReactive:核心部分,get和set方法
//针对数组部分 let oldArrayPrototype = Array.prototype; //继承旧数组的方法 let proto = Object.create(oldArrayPrototype) //js省略;写法注意在括号前面加分号 ;['push','shift','unshift'].forEach(method=>{ //函数劫持 proto[method] = function(){ updateView() oldArrayPrototype[method].call(this,...arguments) } }) function observer(target){ //基本数据类型不需要处理,直接返回 if(typeof target !== 'object' || typeof target == null){ return target } //拦截数组,给数组重写方法 if(Array.isArray(target)){ // Object.setPrototypeOf(target,proto) target.__proto__ = proto } //循环重新定义data里面的属性和值 for (let key in target){ defineReactive(target,key,target[key]) } } //get和set方法 function defineReactive(target,key,value){ observer(value)//递归观察 Object.defineProperty(target,key,{ get(){ //需要进行依赖收集 return value }, set(newValue){ if(value !== newValue){ observer(newValue)//更新后的数据也需要递归观察 updataView(); value = newValue } } }) } //模拟更新视图 function updataView(){ console.log("视图更新") } let data = {name:'fur',hobby:{play:"code"},age:[1,2,3]} observer(data) //三种写法,触发视图更新三次 data.hobby.play = {name:"js"}//视图更新 data.hobby.play.name = "ts"//视图更新 data.age = [1]//视图更新
vue2的缺陷很明显:
建议大家看vue3,源码下载
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。