一、写在前面
关于MVVM
开发模式,不得不说其响应式原理。响应式是MVVM
架构和MVP
之间最为显著的区别。在以前使用MVP
架构进行前端开发时,其中间层p
需要处理的逻辑特别多,导致比较臃肿。随着MVVM
架构的出现,大大减少了中间层处理的业务逻辑。原因是其响应式原理,视图可以触发其中的某一个指令来改变数据,当数据改变时,视图也会随之刷新。下面我们将简单实现一个响应式。
二、vue2和vue3的响应式的区别
在vue2
中我们对响应式数据进行监听时,使用的是Object.defineProperty
方法来实现的,在vue3
中使用的是Proxy
来实现响应式的。vue3
相比于vue2
来说可以监听更多类型的数据改变。
三、vue2的响应式实现
let activeFns = null
function reactive(obj) {
Object.keys(obj).forEach(key => {
let value = obj[key]
Object.defineProperty(obj, key, {
get() {
let depend = getDepend(obj, key)
depend.depend()
return value
},
set(newValue) {
let depend = getDepend(obj,key)
value = newValue
depend.notify()
}
})
})
return obj
}
class Depend {
constructor() {
this.deps = new Set()
}
depend() {
if(activeFns) {
this.deps.add(activeFns)
}
}
notify() {
this.deps.forEach(fn => fn())
}
}
let wmap = new WeakMap()
function getDepend(target, key) {
let targetMap = wmap.get(target)
if(!targetMap) {
targetMap = new Map()
wmap.set(target, targetMap)
}
let depend = targetMap.get(key)
if(!depend) {
depend = new Depend()
targetMap.set(key, depend)
}
return depend
}
function watchFn(fn) {
activeFns = fn
fn()
activeFns = null
}
let info = reactive({
name: "dmc",
age: 20
})
watchFn(function() {
console.log("------------" + info.name + "++++++++++++++++")
})
watchFn(function() {
console.log("------------" + info.age + "++++++++++++++++")
})
watchFn(function() {
console.log("------------" + info.name + "---------------")
})
info.name = "dl"
//打印结果
/*
------------dmc++++++++++++++++
------------20++++++++++++++++
------------dmc---------------
------------dl++++++++++++++++
------------dl---------------
*/
四、vue3的响应式实现
let activeFn = null
function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
let depend = getDepend(target, key)
depend.depend()
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
let depend = getDepend(target, key)
Reflect.set(target, key, newValue, receiver)
depend.notify()
}
})
}
let wmap = new WeakMap()
function getDepend(target, key) {
let targetMap = wmap.get(target)
if(!targetMap) {
targetMap = new Map()
wmap.set(target, targetMap)
}
let depend = targetMap.get(key)
if(!depend) {
depend = new Depend()
targetMap.set(key, depend)
}
return depend
}
class Depend {
constructor() {
this.deps = new Set()
}
depend() {
if(activeFn) {
this.deps.add(activeFn)
}
}
notify() {
this.deps.forEach(fn => fn())
}
}
function watchFn(fn) {
activeFn = fn
fn()
activeFn = null
}
let info = reactive({
name: "dmc",
age: 20
})
watchFn(function() {
console.log("--------" + info.name + "++++++++")
})
watchFn(function() {
console.log("********" + info.name + "0000000000")
})
watchFn(function() {
console.log("********" + info.age + "0000000000")
})
console.log("??????????????????????????????")
info.name = "sscls"
/*
--------dmc++++++++
********dmc0000000000
********200000000000
??????????????????????????????
--------sscls++++++++
********sscls0000000000
*/
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_47450807/article/details/123291635
内容来源于网络,如有侵权,请联系作者删除!