赞
踩
一、写在前面
关于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 */
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。