原生JS用Object.defineProperty、Proxy、手动调用、Vue2 computed选项、Vue3 computed函数五种方式实现计算属性,分别通过依赖收集、缓存更新、事件绑定或框架响应式系统达成自动或可控的派生值计算。

一、使用原生JavaScript实现计算属性
在HTML5环境中,不依赖框架时可通过监听数据变化并手动触发更新逻辑来模拟计算属性行为。核心在于建立数据依赖关系,并在依赖项变更时重新执行计算函数。
1、定义一个响应式数据对象,使用Object.defineProperty为原始属性设置getter和setter。
2、在setter中触发所有依赖该属性的计算函数重新求值。
3、将计算函数的返回值缓存,仅在依赖项变化时更新,避免重复计算。
立即学习“前端免费学习笔记(深入)”;
4、通过闭包维护依赖收集机制,使每个计算函数能自动注册其访问过的响应式属性。
二、基于Proxy构造响应式系统实现计算属性
利用ES6 Proxy可拦截对象任意属性访问与赋值操作,比Object.defineProperty更全面地支持数组索引、新增属性等场景,适合构建现代计算属性机制。
1、创建一个reactive函数,接收普通对象并返回其Proxy代理实例。
2、定义computed函数,接收一个计算函数作为参数,内部创建一个Ref-like响应式容器存储结果。
3、在computed内部首次执行计算函数时,通过全局依赖收集器记录当前活跃的计算函数与所读取的响应式属性之间的映射。
4、当Proxy拦截到某属性set操作时,通知所有依赖该属性的计算函数重新执行并更新缓存值。
三、手动调用计算函数并绑定事件更新
适用于轻量级页面或需精确控制更新时机的场景。通过显式绑定DOM事件或数据变更钩子,在特定动作发生后主动调用计算逻辑。
1、将计算逻辑封装为独立函数,例如getFullName()、getTotalPrice()等。
2、在input事件监听器中调用该函数,并将返回值写入对应DOM元素的textContent或value属性。
3、对多个输入字段统一绑定change事件,事件处理函数内依次调用所有相关计算函数。
4、使用setTimeout或requestAnimationFrame包裹计算调用,确保DOM更新节奏可控,避免同步高频触发导致性能下降。
四、使用Vue 2的computed选项实现计算属性
Vue 2通过Object.defineProperty劫持data中属性的getter/setter,在内部追踪依赖关系,实现自动更新。computed选项声明的函数会被包装为Watcher实例,具备缓存与懒执行特性。
1、在Vue组件的computed配置项中定义函数,函数体中访问this上的响应式数据。
2、Vue自动分析函数执行过程中读取的响应式属性,并建立依赖关系。
3、当任一依赖属性发生变化时,对应computed函数被标记为“脏”,下次访问其返回值时才重新求值。
4、若计算属性被多次访问且依赖未变,则直接返回缓存结果,提升渲染效率。
五、使用Vue 3的computed函数实现计算属性
Vue 3采用Proxy重写响应式系统,computed函数作为独立API提供,既可用于组件内部,也可在setup()或任意JavaScript模块中使用,返回一个ref-like只读响应式引用。
1、导入{ computed } from 'vue',在setup()中调用computed传入计算函数。
2、计算函数中访问由ref()或reactive()创建的响应式状态,自动建立依赖追踪。
3、通过.value访问计算结果,其行为与ref一致,支持在模板中直接使用或传递给其他响应式API。
4、支持传入第二个参数配置对象,指定get和set方法,实现可写的计算属性,适用于双向绑定复杂逻辑场景。










