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 则会在每次渲染时候都需要计算
<template><div>{{ 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)
适用场景纯计算、派生状态需要每次执行的逻辑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/917249.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917249.shtml
英文地址,请注明出处:http://en.pswp.cn/news/917249.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 23 新特性解析与代码示例

Java 23 新特性解析与代码示例 文章目录Java 23 新特性解析与代码示例1. 引言2. 正式特性2.1. Markdown文档注释 (JEP 467)2.2. 废弃sun.misc.Unsafe的内存访问方法以移除 (JEP 471)2.3. ZGC&#xff1a;默认启用代际模式 (JEP 474)3. 预览特性3.1. 原始类型在模式、instanceof…

spring boot + mybatis + mysql 只有一个实体类的demo

使用MyBatis进行数据库操作&#xff0c;配置简单。主要演示了mybatis可以不用只使用方法名来对应mapper.java和mapper.xml。 目录结构 pom.xml src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── springbootjdbcweb/ │ │ └── …

iRemovalPro完美绕iCloud插卡打电话,A12+支持iOS 18.1.1

iRemovalPro 专业工具全解析与操作指南 &#xff08;支持iOS 14.0 - 16.6.1&#xff0c;A7-A15芯片设备&#xff09; &#x1f449;下载地址见文末 iRemoval Pro iRemoval 专业版是一款来自外国安全研究员的工具&#xff0c;用来帮助一些人因为忘记自己的ID或者密码&#xff0c…

安卓SELinux策略语法

目录前言一、 通用AV规则语法1.1 allow source target:class permissions;1.2 neverallow source target:class permissions;二、type三、attribute四、typeattribute五、alias六、typealias七、init_daemon_domain7.1 init_daemon_domain 宏概述7.2 宏展开与实现7.2.1 展开后规…

vscode cursor配置php的debug,docker里面debug

VSCode PHP调试配置指南 概述 本文介绍如何在VSCode中配置PHP调试环境&#xff0c;包括本地和Docker环境。 前置要求 VSCodePHP 7.0Xdebug扩展PHP Debug VSCode扩展 本地调试配置 1. 安装Xdebug # Ubuntu/Debian sudo apt-get install php-xdebug# MacOS brew install p…

elk部署加日志收集

清华大学镜像源地址&#xff1a;Index of /elasticstack/8.x/yum/8.13.2/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 一、elasticsearch 1.安装 rpm -ivh elastic-agent-8.13.2-x86_64.rpm 2.修改配置 vim /etc/elasticsearch/elasticsearch.yml 修改如下&…

dify 升级1.7.1 插件无法下载依赖

dify 升级1.7.1 插件无法下载依赖 1. 安装通义千问插件&#xff0c;各种报错&#xff1b; 使用下面命令查看docker 镜像日志 docker logs -f --tail100 docker-plugin_daemon-1 2025/08/01 07:42:21 full_duplex.go:59: [INFO]init environment for plugin langgenius/tongyi…

linux中简易云盘系统项目实战:基于 TCP协议的 Socket 通信、json数据交换、MD5文件区别与多用户文件管理实现

&#x1f4cb; 项目介绍 本项目是一个基于Linux环境的简易云盘系统&#xff0c;采用C/S&#xff08;客户端/服务器&#xff09;架构&#xff0c;实现了类似百度网盘的基本功能。系统通过TCP Socket进行网络通信&#xff0c;使用JSON格式进行数据交换&#xff0c;利用SQLite3数据…

linux中posix消息队列的使用记录

在linux中使用posix中的消息队列时遇到了一个问题&#xff0c;就是在发送消息时&#xff0c;如果队列满了&#xff0c;mq_send接口会一直阻塞&#xff0c;经过查找资料后才发现&#xff0c;该接口默认是阻塞的&#xff0c;也就是说&#xff0c;当队列满了以后&#xff0c;接口会…

01 基于sklearn的机械学习-机械学习的分类、sklearn的安装、sklearn数据集及数据集的划分、特征工程(特征提取与无量纲化、特征降维)

文章目录机械学习机械学习分类1. 监督学习2. 半监督学习3. 无监督学习4. 强化学习机械学习的项目开发步骤scikit-learn1 scikit-learn安装2 sklearn数据集1. sklearn 玩具数据集鸢尾花数据集糖尿病数据集葡萄酒数据集2. sklearn现实世界数据集20 新闻组数据集3. 数据集的划分特…

n8n】n8n的基础概念

以下是为初学者整理的 n8n 基本概念总结&#xff0c;帮助快速理解核心功能和使用逻辑&#xff1a;1. 工作流&#xff08;Workflow&#xff09;核心单元&#xff1a;n8n的一切操作基于工作流&#xff0c;代表一个自动化流程。组成&#xff1a;由多个节点&#xff08;Nodes&#…

机器学习基础-matplotlib

一、相关知识点二、plotfrom pylab import mpl # 设置显示中文字体 mpl.rcParams["font.sans-serif"] ["SimHei"] # 设置正常显示符号 mpl.rcParams["axes.unicode_minus"] False #%%#%% import matplotlib.pyplot as plt import random# 画出…

spring-ai-alibaba 学习(十九)——graph之条件边、并行节点、子图节点

前面了解了基础的概念及流程&#xff0c;以及一些参数类下面了解一些特殊的边和节点条件边常见的流程图可能长这个样子&#xff1a;其中菱形的为条件节点&#xff08;或者叫判定节点&#xff09;&#xff0c;但是在spring-ai-alibaba-graph中&#xff0c;并没有条件节点在sprin…

深入浅出设计模式——创建型模式之原型模式 Prototype

文章目录原型模式简介原型模式结构关于克隆方法&#xff1a;浅拷贝/深拷贝原型模式代码实例定义原型类和克隆方法客户端使用代码示例示例一&#xff1a;浅拷贝示例二&#xff1a;深拷贝原型模式总结开闭原则代码仓库原型模式&#xff1a;用原型实例指定创建对象的种类&#xff…

.NET 10 中的新增功能系列文章3—— .NET MAUI 中的新增功能

.NET 10 预览版 6 中的 .NET MAUI.NET 10 预览版 5 中的.NET MAUI.NET 10 预览版 4 中的 .NET MAUI.NET 10 预览版 3 中的 .NET MAUI.NET 10 预览版 2 中的 .NET MAUI.NET 10 预览版 1 中的 .NET MAUI 一、MediaPicker 增强功能&#xff08;预览版6&#xff09; .NET 10 预览…

MT Photos图库部署详解:Docker搭建+贝锐蒲公英异地组网远程访问

如今&#xff0c;私有化部署轻量级图床/图库系统&#xff0c;已经成为越来越多用户的高频需求。而MT Photos&#xff0c;正是一款非常适合在Docker环境下运行的自托管图床/图库系统。MT Photos基于Node.js与Vue构建&#xff0c;界面简洁美观&#xff0c;支持多用户权限管理、多…

解决dbeaver连接不上oceanbase数据库的问题

解决dbeaver连接不上oceanbase数据库的问题 问题&#xff1a; 使用dbeaver连接oceanbase数据库报错如下&#xff1a; ORA-00900: You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near ‘dat…

Kafka——请求是怎么被处理的?

引言在分布式消息系统中&#xff0c;请求处理机制是连接客户端与服务端的"神经中枢"。无论是生产者发送消息、消费者拉取数据&#xff0c;还是集群内部的元数据同步&#xff0c;都依赖于高效的请求处理流程。Apache Kafka作为高性能消息队列的代表&#xff0c;其请求…

区块链技术如何确保智能合约的安全性和可靠性?

智能合约作为区块链上自动执行的可编程协议&#xff0c;其安全性和可靠性直接决定了区块链应用的信任基础。区块链通过底层技术架构、密码学工具和机制设计的多重保障&#xff0c;构建了智能合约的安全防线。以下从技术原理、核心机制和实践保障三个维度展开分析&#xff1a;一…

2020 年 NOI 最后一题题解

问题描述2020 年 NOI 最后一题是一道结合图论、动态规划与状态压缩的综合性算法题&#xff0c;题目围绕 "疫情期间的物资配送" 展开&#xff0c;具体要求如下&#xff1a;给定一个有向图 G (V, E)&#xff0c;其中节点代表城市&#xff0c;边代表连接城市的道路。每个…