什么是数据响应式原理?数据响应式原理就是当数据发生变化时,视图也会更新。即数据驱动页面变化。
vue2中是如何实现数据响应式的呢?vue2中就是利用就是利用Object.
defineProperty
数据劫持 和观察者模式实现的数据响应式的。
Object.defineProperty(target,key,value),接收三个参数,第一是目标对象,第二个是对象中的key值,第三个key值对应的value值。其中defineReactive这个方法主要是将Object.defineProperty封装到一个函数中,做这一步操作的原因是因为Object.defineProperty设置set属性时需要一个临时变量来存储变化前的值,通过封装利用闭包的思想引入val,这样就不需要在函数外面再设置临时变量了。
Object.defineProperty不能直接监听数组内部的变化,那么数组内容变化应该怎么操作呢?Vue主要采用的是改装数组方法的方式(push、pop、shift、unshift、splice、sort、reverse),在保留其原有功能的前提下,将其新添加的项变为响应式的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<p>数据响应式原理复杂引用数据对象</p>
</div>
<script>
const data={
name:'xiaoming',
age:20,
friend:{
friendname:'xiaohong'
},
colors:['red','orange','green']
};
const oldArrayProto=Array.prototype()
const newArrayProto=Object.create(oldArrayProto)
['pop','push','shift','unshift','splice'].forEach(methodName=>{
newArrayProto[methodName]=function(){
console.log('更新视图');
oldArrayProto[methodName].call(this,...arguments);
}
})
//变成响应式数据
observer(target)
function observer(target){
//判断数据类型
if(typeof target !== 'object' || target===null){
return target
}
//判断是否未数组
if(Array.isArray(target)){
target.__proto__=newArrayProto;
}
for(let key in target){
defineReactive(target,key,target[key])
}
}
function defineReactive(target,key,value){
observer(value)
Object.defineProperty(target,key,{
get(){
return value
},
set(newvalue){
if(newvalue !== value){
value=newvalue
console.log('更新视图')
}
}
})
}
data.age=21
//Object.defineProperty缺点没有办法处理属性新增和属性删除的,可以通过Vue.delete(删除),Vue.set(新增)
</script>
</body>
</html>
版权声明:本文为weixin_54018434原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。