Vue3的响应系统
<!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>vuejs响应式</title>
</head>
<body>
<div class="wrapper">
<div class="text">0</div>
<div class="input">
<input id="input" type="text">
</div>
</div>
</body>
<script>
// 用一个全局变量存储被注册的副作用函数
let activeEffect
// effect用于注册副作用函数
function effect(fn) {
// 当调用effect注册副作用函数时,将副作用函数fn赋值给activeEffect
activeEffect = fn
// 执行副作用函数
fn()
}
// 存储副作用函数
const bucket = new WeakMap()
// 原始数据
const data = { text: 'hello word' }
// 对原始数据的代理
const obj = new Proxy(data, {
// 拦截读取操作
get(target, key) {
// 把副作用函数activeEffect添加到桶里去
track(target, key)
// 返回属性值
return target[key]
},
// 拦截设置操作
set(target, key, newVal) {
// 设置值
target[key] = newVal
// 把副作用函数从桶里去除并执行
trigger(target, key)
}
})
effect(() => {
document.querySelector('.text').innerHTML = obj.text
})
// 在get拦截函数内调用track函数追踪变化
function track(target, key) {
// 没有副作用函数,直接返回
if (!activeEffect) return target[key]
// 根据target从桶中取得depsMap,它也是夜歌Map类型:key --> effects
let depsMap = bucket.get(target)
// 如果不存在的depsMap,那么新建一个Map并与target关联
if (!depsMap) {
bucket.set(target, (depsMap = new Map()))
}
// 再根据key从deosMap中取得deps,他是一个Set类型
// 里面存储这所有与当前key相关联的副作用函数:effects
let deps = depsMap.get(key)
// 如果deps不存在,同样新建一个与Set并与key关联
if (!deps) {
depsMap.set(key, (deps = new Set()))
}
// 将副作用函数存储至桶中
deps.add(activeEffect)
}
// 在set拦截函数内调用trigger函数触发变化
function trigger(target, key) {
// 把副作用函数拿出来执行
const depsMap = bucket.get(target)
if (!depsMap) return
const effects = depsMap.get(key)
effects && effects.forEach(fn => fn())
}
let input = document.querySelector('#input')
input.addEventListener('input', function () {
obj.text = this.value
})
</script>
<style>
.wrapper {
position: absolute;
top: 30%;
left: 20%;
}
</style>
</html>
*来源于 Vue.js设计与实现 霍春阳 4.3 设计一个完善的响应系统
分类:
前端 / Vue学习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!