将以下代码保留为文件 即可查看成果!
<script type="text/javascript"> const weakMap = new WeakMap const effectStack = [] let activeEffect function pushStack(o) { effectStack.push(o); activeEffect = o } function popStack() { effectStack.pop(); activeEffect = effectStack[effectStack.length - 1] } function trigger(obj, k) { let k2depMap = weakMap.get(obj) if (!k2depMap) return const dep = k2depMap[k] if (!dep) return dep.forEach(e => e()) } function track(obj, k) { if (!activeEffect) return let k2depMap = weakMap.get(obj) if (!k2depMap) weakMap.set(obj, k2depMap = {}) let dep = k2depMap[k] if (!dep) dep = k2depMap[k] = new Set dep.add(activeEffect) } function effect(fn, option = {}) { const effect = function() { try { pushStack(fn) return fn() } finally { popStack() } } if (!option.lazy) effect() return effect } function reactive(state) { return new Proxy(state, { set(target, k, v) { target[k] = v trigger(target, k, v) }, get(target, k) { track(target, k) return target[k] } }) }</script><button id="btn" onclick="btn_click()"></button><div id="circle" onclick="circle_click()">切换圆角</div><script type="text/javascript"> const state = reactive({ count: 1, circle: true }) effect(() => { const div = document.getElementById('btn') div.innerText = '计数 _ ' + state.count }) effect(() => { const div = document.getElementById('circle') const style = { borderRadius: state.circle ? '20px' : 0 } Object.assign(div.style, style) }) function btn_click() { state.count++ } function circle_click() { state.circle = !state.circle }</script><style type="text/css"> #circle { display: flex; justify-content: center; align-items: center; margin-top: 10px; width: 100px; height: 100px; background-color: #dd8538; }</style>