二、vue响应式解析

响应式原理

在使用vue时,需要修改设计属性值的时候,页面的数据直接更新。
使用js中 Object.defineProperty()这个方法实现

//上述方法需要的参数
Object.defineProperty(对象,'设置什么属性名',{
	writeable  // 可编辑
	enumerable //控制属性是否可枚举 是不是可以被for in 取出来
	set() //赋值触发
    get() //取值触发
})

将对象转换为响应式

var o = {
	name:'zs',
	age:23,
	gender:'nan'
}
function defineReactive(target,key,value,enumerable){
	//函数内部就是一个局部作用域,这个value就只在函数内使用变量
	Object.defineProperty(target,key,{
		configurable:true,
		enumerable:!enumerable,
		get(){
			console.log(`读取o的 ${key} 属性`)
			return value;
		},
		set(newVal){
			console.log(`修改o的 ${key} 属性`)
			value = newVal
		}
	})
}

//将对象转换为响应式的
let keys = Object.keys(o)
for(let i = 0;i<keys.length;i++){
	defineReactive(o,keys[i],o[keys[i]],true)
}

打开浏览器在控制台中输入 o.age = 40
age的值就变成40啦
在这里插入图片描述
监听对象的方法是get和set,但是对于数组,data.list.push(1) 进行push操作的时候并不会触发get() set()方法,所以我们要重写数组的方法,将数组改为响应式

// 首先定义一组数组  使用数组时的一些方法
let ARRAY_METHOD = [
	'push',
	'pop',
	'shift',
	'unshift',
	'reverse',
	'sort',
	'splice'
]
let array_method = Object.create(Array.prototype);
ARRAY_METHOD.forEach(method =>{
	array_method[method] = function(){
		console.log('拦截的' + method + '方法')
		// 将数组进行响应式化
		for(let i = 0;i<arguments.length;i++){
			reactify(arguments[i])
		}
		//调用原来的方法
		let res = Array.prototype[method].apply(this,arguments);
		return res;
	}
})
function reactify(o){
	let keys = Object.keys(o);
	for(let i = 0;i<keys.length;i++){
		let key = keys[i]; // 属性名
		let value = o[key]
		if(Array.isArray(value)){
			value.__proto__ = array_method; //数组就可以响应式了
			for(var j = 0;j<value.length;j++){
				reactify(value[j]) //递归
			}
		}else{
			// 对象或值类型
			defineReactive(o,key,value,true)
		}
	}
}
function defineReactive(target,key,value,enumerable){
	if(typeof value === 'object' && value != null && !Array.isArray(value)){
		// 是非数组的引用类型
		reactify(value)
	}
	Object.defineProperty(target,key,{
		configurable:true,
		enumerable:!enumerable,
		get(){
			console.log(`读取${key}属性`)
			return value
		},
		set(newVal){
			console.log(`修改${key}属性`)
			value = newVal
		}
	})

}
 let o = {
            name:'zs',
            age:22,
            course:[
                {name:'数学'},
                {name:'英语'},
                {name:'语文'}
            ],
            obj:{
                obj:'coding'
            }
        };
reactify(o)

这一波操作之后对数组进行添加或者修改最后数组里的值都是响应式的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值