什么是vue响应式原理,该如何实现
详细请看官方文档
Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty(数据劫持) 把这些 property 全部转为 getter/setter。
getter是使用数据的时候触发,setter是在修改数据的时候触发,修改数据的时候触发setter,同时也触发了底层的watcher监听,通知dom修改刷新。
<script>
var data = {
name: 'Liao',
age: 18,
child: {
one: 'Xin'
},
person: [1,3,5,7]
}
var oldArrayProto = Array.prototype //保存原型
var newProto = Object.create(oldArrayProto) //将oldArrayProto保存的原本的数组的原型作为新的数组原型
console.log('olg',oldArrayProto)
console.log('new',newProto)
var arr = ['push','pop','shift','unshift','slice']
arr.forEach((methodName)=>{
newProto[methodName] = function(){
console.log('更新视图')
oldArrayProto[methodName].call(this,...arguments)
//既会更新视图,也会执行原有的功能
}
})
//变成响应式数据
observe(data)
function observe(target){
//判断是否是对象或者数组或者为空
if(typeof target !== 'object' || target === null){
return target
}
//判断是否为数组
if(Array.isArray(target)){
target.__proto__ = newProto
}
//遍历对象,将对象,属性,值进行访问拦截
for(let key in target){
defineReactive(target,key,target[key])
}
}
function defineReactive(target,key,value){
//处理值为复杂对象,进行深度观察
console.log(key)
observe(value)
Object.defineProperty(target,key,{
get(){
return value
},
set(newVal){
//进行深度观察,监听新设置的newVal
observe(newVal)
//判断当前值是否为最新的值,如果不是进行更新
if(value !== newVal){
value = newVal
console.log('更新视图')
}
}
})
}
//data.person[0] = 8 可以更新
data.person.push(10)
</script>
- 本文作者: étoile
- 版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!