url: /posts/a222db116daaa6c34801f06a9ef13428/
title: Vue 3计算属性的缓存与依赖追踪原理是什么?可写性与历史值功能该如何正确使用?
date: 2025-11-17T01:54:23+08:00
lastmod: 2025-11-17T01:54:23+08:00
author: cmdragon
summary:
计算属性是Vue 3中用于派生响应式值的核心工具,通过computed()函数创建,接收一个getter函数返回派生值。计算属性具有缓存机制,只有当依赖的响应式数据变化时才会重新计算,否则直接返回缓存值,提升性能。与方法的区别在于,计算属性有缓存,而方法每次调用都会重新执行。计算属性还可以通过添加setter实现双向绑定。最佳实践包括避免在getter中执行副作用操作,以及不修改计算属性的返回值。
categories:
tags:
扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
发现1000+提升效率与开发的AI工具和实用程序:https://tools.cmdragon.cn/
计算属性是Vue 3中用于派生响应式值的核心工具。当你需要根据现有响应式数据生成新值时,计算属性能让代码更简洁、更易维护。
假设我们有一个author对象,包含name和books数组。我们需要在模板中显示“是否有已出版书籍”的结果:
<script setup>
import { reactive, computed } from 'vue'
// 响应式数据:作者信息
const author = reactive({
name: 'John Doe',
books: ['Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide']
})
// 计算属性:根据books长度派生结果
const publishedBooksMessage = computed(() => {
// getter函数:返回派生值
return author.books.length > 0 ? 'Yes' : 'No'
})
</script>
<template>
<p>Has published books:</p>
<span>{
{ publishedBooksMessage }}</span> <!-- 直接使用计算属性 -->
</template>
关键点:
computed()函数创建,接收一个getter函数(返回派生值)。.value(Vue会自动解包)。author.books),当author.books变化时,publishedBooksMessage会自动更新。计算属性的核心优势是缓存——只有当依赖的响应式数据变化时,才会重新计算;否则直接返回缓存值。
计算属性的缓存基于依赖的响应式数据:
getter首次执行时,Vue会记录它访问的所有响应式数据(即“依赖”)。getter才会再次执行,更新缓存值。假设你有一个需要遍历1000条数据的计算属性:
const expensiveComputed = computed(() => {
return largeArray.value.filter(item => item.isActive).length
})
如果用方法实现(function calculateActiveCount() { ... }),每次组件渲染都会重新遍历1000条数据;而计算属性只会在largeArray变化时重新计算,大幅提升性能。
如果计算属性的getter访问了非响应式数据(如Date.now()),缓存永远不会更新:
// 这个计算属性永远不会变!因为Date.now()不是响应式依赖
const now = computed(() => Date.now())
Vue的响应式系统通过依赖收集实现计算属性的自动更新,流程如下(用流程图简化):