买了域名怎么做网站,公司做网站的作用,flash类网站开发,展示型网站方案computed#xff08;计算属性#xff09;并不是vue独创的#xff0c;而是源自计算机科学和响应式编程的长期发展
计算理论的奠基#xff1a;
函数式编程的纯函数思想#xff1a;计算属性的核心特征#xff08;无副作用、依赖输入确定输出#xff09;直接来源于函数式编程…computed计算属性并不是vue独创的而是源自计算机科学和响应式编程的长期发展
计算理论的奠基
函数式编程的纯函数思想计算属性的核心特征无副作用、依赖输入确定输出直接来源于函数式编程中的纯函数概念响应式编程的衍生值在响应式系统中任何可以依据其他的“可观察量”自动计算出的值都可以视为计算属性
vue中computed的演进
vue 1.x时代2014-2016
初步实现通过 computed 选项定义计算属性基于依赖收集的响应式系统
特点
基于Object.defineProperty实现响应式计算属性会被混入到Vue实例中像普通属性一样访问已具备缓存机制依赖不变时直接返回缓存值
Vue 2.x 时代2016-2020
优化改进
计算属性的惰性求值只在真正被访问时才计算更精细的依赖追踪基于 Watcher 类的依赖收集系统支持 setter允许通过赋值反向影响依赖项3
computed: {fullName: {get() { return this.firstName this.lastName },set(newValue) { /* 处理赋值逻辑 */ }}
}Vue 3.x 时代2020至今
组合式 API 重构
引入 computed() 函数可在 setup() 或 在 script setup 中使用基于 Proxy 的响应式系统解决 Vue 2 的检测限制与 Reactivity System 深度集成性能显著提升
import { computed } from vue
const count ref(1)
const double computed(() count.value * 2)computed设计核心原理
1、响应式依赖追踪
自动收集依赖执行计算属性时候访问的每个属性都会被记录依赖更新触发当任何属性变化时候标记计算属性为“脏”dirty, 下次访问时候再重新计算
2、缓存机制的实现
// 简化的 computed 实现原理
function computed(getter) {let valuelet dirty trueconst runner effect(getter, {lazy: true,scheduler: () {dirty true // 依赖变化时标记为需要重新计算trigger(obj, value) // 触发依赖此计算属性的副作用}})const obj {get value() {if (dirty) {value runner() // 执行 getter 计算新值dirty false}return value}}return obj
}在vue中 同步派生状态指的是基于现有响应式数据立即计算得出的新状态这种计算是同步完成的具有即时性和准确性这是computed计算属性的核心设计理念
同步派生状态的核心特征
1、即时计算当依赖变化时候派生值同步立即重新计算
const count ref(1);
const double computed(() count.value * 2); // 同步计算
console.log(double.value); // 2
count.value 3;
console.log(double.value); // 6 立即更新2、纯函数特性派生过程不允许修改外部状态仅依赖输入
// 纯派生结果仅取决于 count.value
const triple computed(() count.value * 3); 3、与异步派生对比特性同步派生 (computed)异步派生 (如 watch 状态)执行时机立即完成延迟完成需等待 Promise模板引用可直接使用需要处理加载中/错误状态响应式追踪自动追踪依赖需手动管理依赖返回值必须返回无返回值通过修改状态输出需要每次执行的逻辑
1、模板渲染的即时性需求vue模板渲染需要同步获取值进行渲染异步派生会导致渲染中断或需要额外的处理加载状态
2、响应式系统的设计基础vue的响应式依赖追踪依赖同步访问
3、缓存优化前提同步计算使得缓存机制能精准判断是否需要重新计算
同步派生使用场景
// 数据格式化
const price ref(100);
const formattedPrice computed(() ${price.value.toFixed(2)});// 过滤/筛选列表
const todos ref([/*...*/]);
const activeTodos computed(() todos.value.filter(todo !todo.completed)
);// 多状态组合
const width ref(10);
const height ref(20);
const area computed(() width.value * height.value);同步派生的优势:
性能高效基于依赖追踪的精准缓存心智模型简单输入输出关系明确调试友好无隐藏的异步时序问题组合方便可安全地被其他计算属性引用
vue中的“同步派生状态”是通过computed来实现的即时性、确定性的数据转换它是vue响应式系统的核心支柱这种设计确保了
模版渲染的即时性、可靠性状态变化的可预测性派生逻辑的高效性
computed为什么会有缓存机制
vue中的computed采用缓存机制主要是为了优化性能和保证一致性当计算属性依赖性没有变化时vue会直接返回上一次的计算结果而不会重新计算
缓存优势
1、性能优化
避免重复计算模版中多次引用同一个计算属性时依赖未变化就不需要重新计算如果没有缓存expensiveCalc 则会在每次渲染时候都需要计算
templatediv{{ expensiveCalc }}/div !-- 计算一次 --div{{ expensiveCalc }}/div !-- 直接读缓存 --
/template减少渲染开销 vue的渲染更新是批量的缓存机制可以避免同一轮更新中多次触发相同的计算
2、保证一致性
同步派生状态的确定性在同一个事件循环中无论访问多少次计算属性其结果都是相同避免副作用污染计算属性时纯函数缓存机制强调开发者遵守这一原则, 无法在计算属性中执行副作用
3、与响应式系统的协同
精准依赖追踪缓存机制依赖vue的响应式系统只有当确定的依赖项变化时候才需要重新计算
缓存实现的关键技术
1、惰性计算只有在真正访问属性时才会计算如果依赖性没有变化则直接读取缓存值
2、标记-清除机制“脏”dirty状态标记当依赖性发生变化时标记属性为“dirty”. 下次访问时候再重新计算
// 伪代码示意Vue内部逻辑
class ComputedRef {constructor(getter) {this._dirty true; // 初始标记为需要计算this._value undefined;}get value() {if (this._dirty) {this._value getter(); // 重新计算this._dirty false;}return this._value;}
}3、依赖收集的精准性
计算属性执行时会自动追踪所有被访问的响应式变量只有这些被追踪的变量变化时才会触发重新计算
何时会打破缓存
依赖项发生变化主动触发
const a ref(1);
const b computed(() a.value * 2);
a.value 2; // 修改依赖下次访问b时重新计算手动强制刷新特殊情况
// 部分场景可通过赋值触发不推荐
b.value 5; // 如果计算属性可写setter与方法的对比特性computed (带缓存)方法 (无缓存)执行时机依赖变化时每次调用都执行性能高效缓存结果可能重复计算模板使用自动优化需自行优化如 v-once适用场景纯计算、派生状态需要每次执行的逻辑