1.Vue3
副作用函数(onMounted、watchEffect)
帮助管理组件中的副作用逻辑,并自动追踪其依赖关系,以确保在数据变化时能够自动触发副作用函数的更新。
会自动追踪被其内部函数引用的响应式数据。当这些数据发生变化时,Vue 3 会自动重新运行副作用函数,确保副作用与数据的状态保持同步。
let activeEffect // 副作用函数 export const effect = (fn) => { const _effect = function () { activeEffect = _effect fn() } _effect() }
收集依赖
通过proxy里的调用收集依赖
// 收集依赖 const targetMap = new WeakMap() export const track = (target, key) => { // WeakMap // key为对象, 即target // value 为一个new Map() // { // key:{ // name: "名字", // age: 18 // }, // value: { // name: new Map(), // age: new Map() // } // } let depsMap = targetMap.get(target) if (!depsMap) { depsMap = new Map() targetMap.set(target, depsMap) } // 现在添加new Map() // key为属性名称, 即key // value为一个new Set() let deps = depsMap.get(key) if (!deps) { deps = new Set() depsMap.set(key, deps) } // 现在添加Set() // 给Set添加副作用函数 deps.add(activeEffect) }
更新依赖
// 更新依赖 export const trigger = (target, key) => { // 根据组件的响应式组件对象,拿到对应的map const depsMap = targetMap.get(target) // 通过具体key, 拿到对应副作用函数 const deps = depsMap.get(key) // 执行 deps.forEach((effect) => effect()) }
完整代码(effect.js)
let activeEffect // 副作用函数 export const effect = (fn) => { const _effect = function () { activeEffect = _effect fn() } _effect() } // 收集依赖 const targetMap = new WeakMap() export const track = (target, key) => { // WeakMap // key为对象, 即target // value 为一个new Map() // { // key:{ // name: "名字", // age: 18 // }, // value: { // name: new Map(), // age: new Map() // } // } let depsMap = targetMap.get(target) if (!depsMap) { depsMap = new Map() targetMap.set(target, depsMap) } // 现在添加new Map() // key为属性名称, 即key // value为一个new Set() let deps = depsMap.get(key) if (!deps) { deps = new Set() depsMap.set(key, deps) } // 现在添加Set() // 给Set添加副作用函数 deps.add(activeEffect) } // 更新依赖 export const trigger = (target, key) => { // 根据组件的响应式组件对象,拿到对应的map const depsMap = targetMap.get(target) // 通过具体key, 拿到对应副作用函数 const deps = depsMap.get(key) // 执行 deps.forEach((effect) => effect()) }
reactive实现(reactive.js)
import { track, trigger } from './effect.js' const isObject = (target) => target != null && typeof target == 'object' export const reactive = (target) => { return new Proxy(target, { get(target, key, receiver) { const res = Reflect.get(target, key, receiver) // 收集依赖 track(target, key) // 递归对象 if (isObject(res)) { return reactive(res) } return res }, set(target, key, value, receiver) { const res = Reflect.set(target, key, value, receiver) // 更新依赖 trigger(target, key) return res }, }) }
调用
<!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 id="app"> </div> <script type="module"> import { reactive } from './reactive.js' import { effect } from './effect.js' const user = reactive({ name: "名字", age: 18, foo: { bar: { sss: 123 } } }) effect(() => { document.querySelector('#app').innerText = `${user.name} - ${user.age}-${user.foo.bar.sss}` }) setTimeout(() => { user.name = '名字666' setTimeout(() => { user.age = '23' setTimeout(() => { user.foo.bar.sss = 66666666 }, 3000) }, 2000) }, 1000) </script> </body> </html>
2.Vue2
待完成....
标签:const,target,depsMap,effect,响应,Vue2,key,Vue3,new From: https://www.cnblogs.com/ssszjh/p/18163321