Vue 计算属性(computed)的使用和优化

前言

Vue 的计算属性(computed)是 Vue.js 中非常重要的一个概念。它允许你在 Vue 组件中定义一些计算逻辑,这些逻辑会依赖于 Vue 的响应式数据,并且具有缓存机制,只有在依赖数据发生改变时才会重新计算,从而提高了性能。

计算属性的主要作用包括:

  • 数据转换

  • 数据过滤

  • 响应式依赖

  • 缓存机制

  • 简化模板

在本篇文章中,我们将详细探寻如何利用计算属性优化 Vue 组件的数据处理和渲染逻辑,深入了解 Vue 计算属性的精髓。

一. 认识计算属性

1. 什么是计算属性

Vue.js 中的计算属性(computed properties)是 Vue 实例中非常重要的一个特性。它们用于对 Vue 实例的数据进行动态计算,且具有缓存机制,只有在相关依赖发生改变时才会重新计算。这种特性使得计算属性非常适合用于处理模板中的逻辑。

2. 计算属性的定义

计算属性是在 Vue 实例的computed选项中定义的,可以是一个函数或具有getset方法的对象。函数形式的计算属性会在调用时被执行,而对象形式的计算属性则可以提供自定义的getset方法。

computed: {// 函数形式的计算属性reversedMessage: function () {return this.message.split('').reverse().join('');},// 对象形式的计算属性fullName: {get: function () {return this.firstName + ' ' + this.lastName;},set: function (newValue) {var names = newValue.split(' ');this.firstName = names[0];this.lastName = names[names.length - 1];}}
}

3. 计算属性的依赖

计算属性可以依赖于 Vue 实例的响应式数据。当依赖数据发生改变时,相关的计算属性会重新计算。

data: {message: 'Hello'
},
computed: {reversedMessage: function () {return this.message.split('').reverse().join('');}
}

reversedMessage计算属性依赖于message数据,当message发生变化时,reversedMessage会自动更新。

4. 计算属性的缓存

计算属性默认具有缓存机制。只有在相关依赖发生变化时,计算属性才会重新计算。多次访问计算属性时,Vue 会返回之前计算的结果,而不会重新执行计算函数,从而提高性能。

computed: {reversedMessage: function () {return this.message.split('').reverse().join('');}
}

在上面的代码中,reversedMessage会在第一次访问时计算并缓存结果,之后的访问会直接返回缓存的值,除非message发生变化。

通过这些基本概念,计算属性可以帮助你更清晰、高效地处理 Vue 实例中的数据,从而简化模板逻辑,提高代码可读性和可维护性。

二. Getter 和 Setter

Getter 方法和 Setter 方法是计算属性中非常有用的功能,让我们详细了解一下它们的功能:

1. Getter 方法

计算属性的 Getter 方法用于计算并返回一个值。它类似于一个数据属性,但其值是通过计算得出的。Getter 方法在访问计算属性时被调用。

例如,在以下示例中,我们定义了一个计算属性fullName,它通过组合firstNamelastName来生成完整的姓名:

new Vue({data: {firstName: "John",lastName: "Doe",},computed: {fullName: {get: function () {return this.firstName + " " + this.lastName;},},},
});

当你通过this.fullName访问fullName时,Getter 方法会被调用,并返回完整的姓名。

2. Setter 方法

计算属性的 Setter 方法用于监视计算属性被赋值时的变化,并在赋值时执行一些自定义的操作。它允许我们对计算属性进行更精细的控制。

在以下示例中,我们对fullName计算属性添加了一个 Setter 方法,用于解析新值并更新firstNamelastName

new Vue({data: {firstName: "John",lastName: "Doe",},computed: {fullName: {get: function () {return this.firstName + " " + this.lastName;},set: function (newValue) {var names = newValue.split(" ");this.firstName = names[0];this.lastName = names[names.length - 1];},},},
});

当你尝试为fullName赋值时,Setter 方法会被调用,它会解析新值并相应地更新firstNamelastName

使用 Getter 和 Setter 方法,你可以更灵活地处理计算属性,并根据需要执行自定义操作。这使得计算属性成为 Vue.js 中处理动态数据的强大工具。

三. 计算属性的性能优化

在开发中我们会经常的使用到计算属性,为了确保性能,有时需要注意一些优化技巧。以下是一些计算属性的性能优化方法:

1. 合理利用懒计算 - lazy

计算属性的lazy选项可以用来延迟计算属性的求值。默认情况下,计算属性是在获取时立即求值的,但通过设置lazytrue,可以将计算属性的求值延迟到首次访问该属性时才进行计算。这个选项可以提升初始化时的性能。

lazy选项设置为true时,计算属性不会在组件初始化时立即计算。相反,在首次访问计算属性时,它会调用定义的计算函数并将结果缓存起来,以供后续的访问。

延迟计算属性的使用场景包括:

  1. 计算代价较高的属性: 如果计算属性的计算逻辑很复杂或需要耗费大量的计算资源,那么可以将其设置为延迟计算属性。这样,在组件初始化时不会执行这些代价较高的计算,只有在需要访问该属性时才会进行计算,避免不必要的性能损耗。

  2. 依赖其他计算属性的计算属性: 如果有一个计算属性依赖了其他计算属性,而这些依赖的计算属性是在首次访问时才进行计算的,那么可以将这个计算属性设置为延迟计算属性。这样,在首次访问该计算属性时,它会自动等待依赖计算属性的值可用后再进行计算。

要设置计算属性的lazy选项,需要在计算属性中使用对象语法,并将lazy设置为true

computed: {lazyComputed: {get() {// 延迟计算的逻辑},// ...lazy: true}
}

需要注意的是,lazy选项只对 Vue2 有效,Vue3 中已移除该选项。在大多数情况下,默认的立即计算行为是足够的,只有在特定性能优化的场景中,才需要考虑使用延迟计算属性。

通过合理地使用lazy选项,可以避免不必要的计算,提高应用程序的性能。但也要注意,过度使用延迟计算属性可能会导致代码变得复杂,因此应根据实际需求进行选择和权衡。

2. 合理设置缓存行为 - cache

计算属性的cache选项用于控制计算属性的缓存行为。默认情况下,计算属性是具有缓存的,即在计算属性的依赖项不发生变化时,多次访问该计算属性将返回缓存的结果,而不会重新计算。这样可以避免不必要的计算,提高性能。

通过设置cache选项为false,可以禁用计算属性的缓存行为,这意味着每次访问该计算属性时都会重新计算,无论其依赖项是否发生变化。

禁用计算属性缓存的使用场景包括:

  1. 计算属性的值可能频繁变更: 如果计算属性的值可能频繁地发生变化,即使其依赖项没有变化,你可能需要禁用缓存。这样可以确保每次访问计算属性时都能获取到最新的计算结果。

  2. 计算属性的值依赖于外部实例状态: 如果计算属性的值依赖于外部实例状态(例如全局状态管理器或其他组件的状态),那么在这些状态发生变化时,你可能需要禁用缓存。这样可以确保计算属性能响应外部状态的变化。

要禁用计算属性的缓存,需要在计算属性中使用对象语法,并将cache选项设置为false

computed: {uncachedComputed: {get() {// 计算逻辑},// ...cache: false}
}

需要注意的是,禁用计算属性的缓存行为可能会导致不必要的性能开销,特别是在计算逻辑复杂或计算频率较高的情况下。因此,只在必要时禁用缓存,并确保评估其性能影响。

在Vue3中,计算属性的缓存行为有了一些改变,默认情况下,计算属性不再具有缓存。如果需要保留缓存行为,可以将cache选项设置为true

通过合理地使用和管理计算属性的缓存,可以提高应用程序的性能和响应性。但也要注意,在某些特定情况下,禁用缓存或开启缓存可能更适合,需要根据实际需求进行选择和权衡。

3. 避免过度计算

尽量避免在计算属性中进行过于复杂或耗时的计算,以减轻性能负担。如果需要复杂计算,考虑将其分解为更小的计算属性或使用方法。

如果计算属性中的依赖项较多或算逻辑较复杂,可能会影响性能。在这种情况下,可以考虑使用计算属性的getter和setter方法进行优化,或者使用watch来监听多个数据的变化。

四. 实际项目中的应用

在实际的项目开发中,我们有很多的应用场景需要用到计算属性,比如:

  • 数据过滤

  • 表单验证

  • 数据计算结果

  • 数据格式化

  • ...

等等,应用场景很多,在这里不多做赘述。以下面一个计算价格的场景为例,我们来看一下实际场景下是如何使用的。

例如:当需要计算商品的总价时,可以使用计算属性来实现,下面我们详细说明计算属性的应用:

<!DOCTYPE html>
<html><head><title>商品总价计算</title><script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script></head><body><div id="app"><h2>商品列表</h2><ul><li v-for="product in products" :key="product.id">{{ product.name }} - ¥{{ product.price }}</li></ul><h2>商品总价:¥{{ totalPrice }}</h2></div><script>new Vue({el: "#app",data: {products: [{ id: 1, name: "手机", price: 2999 },{ id: 2, name: "平板", price: 1999 },{ id: 3, name: "耳机", price: 399 },{ id: 4, name: "电视", price: 4999 },{ id: 5, name: "笔记本", price: 5999 },],},computed: {totalPrice: function () {return this.products.reduce(function (total, product) {return total + product.price;}, 0);},},});</script></body>
</html>

在上面的代码中,我们定义了一个 Vue 实例,并使用data选项定义了一个products数组,其中包含了一些商品信息,包括商品的 ID、名称和价格。

接着,在computed选项中定义了一个名为totalPrice的计算属性。这个计算属性使用reduce方法对products数组中的价格进行累加,从而得到商品的总价。最后,在模板中使用插值语法{{ totalPrice }}将计算结果显示出来。

运行上面的代码,你将看到页面上列出了商品列表,并实时计算并显示了商品的总价。如下图所示:

image.png

image.png

通过上面的示例,我们可以看到计算属性的应用方式。它能够轻松地在 Vue 实例的响应式数据上进行复杂的计算,而且只有在相关依赖发生变化时才会重新计算。同时提高了代码的可读性、可维护性和性能。

五. 最佳实践

下面是总结的一些 Vue 计算属性的最佳实践,它们可以帮助你更好地应用和管理计算属性:

  1. 保持计算属性简洁: 计算属性应该保简洁,只包含必要的逻辑。避免在计算属性中执行复杂的计算或涉及过多的业务逻辑。如果需要复杂的逻辑,可以考虑使用方法。

  2. 避免计算属性中的副作用: 计算属性应该是纯的,不应该有副作用。副作用包括修改数据、触发异步操作、调用接口等。如果需要有副作用的操作,应该放在生命周期钩子函数或观察者中。

  3. 合理使用计算属性和方法: 计算属性适合处理依赖关系和复杂的数据转换。方法适用于执行具有副作用的操作或根据需要传递参数。根据需求合理使用计算属性和方法,可以使代码更加清晰和易读。

  4. 注重性能优化: 参考文章中的第三部分 “计算属性的性能优化”

通过合理使用和管理计算属性,你可以优化应用程序的性能,更好地处理数据逻辑和依赖关系。

总结

在Vue中,计算属性是一个非常重要的特性,它允许我们在模板中使用简洁而优雅的方式来处理数据的计算和变换。通过计算属性,我们可以将复杂的逻辑封装起来,并在需要时进行复用。

通过这篇文章,我们了解到,除了缓存,Vue 还提供了lazy选项和cache选项来进一步控制计算属性的行为。通过使用lazy选项,我们可以延迟计算属性的求值,只有在首次访问该属性时才进行计算。而通过使用cache选项,我们可以禁用计算属性的缓存,每次访问都会重新计算。

综上所述,计算属性是 Vue 提供的一个非常强大和灵活的特性,它可以帮助我们简化数据处理的逻辑,并提高应用程序的性能。合理地使用计算属性,可以使我们的代码更加清晰、易于维护,并提供更好的用户体验。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯—STM32G431RBT6(ADC数模转换,从原理到应用)

一、什么是ADC&#xff1f; ADC&#xff08;Analog-to-Digital Converter&#xff09;即模数转换器。它是一种将模拟信号转换为数字信号的电子器件。在电子系统中&#xff0c;ADC 起着至关重要的作用&#xff0c;它能将连续变化的模拟量&#xff08;如电压、电流等&#xff09;…

ps学习。

有大量的图要扣&#xff0c;淘宝5-15块扣一个&#xff0c;尽管蛮便宜的&#xff0c;但是架不住量大啊&#xff0c;还是好好ps&#xff0c;也能省一大笔钱。 填充 在这里有个油漆桶&#xff0c;一开始也叫渐变色&#xff0c;堆放在一起了&#xff0c;我觉得这不是个好设计。。…

pycharm 使用 translation 插件通过openai进行翻译

pycharm 使用 translation 插件通过openai进行翻译 1. 安装插件2. 配置插件3. 翻译 1. 安装插件 2. 配置插件 3. 翻译 调用 openai 时使用的提示词如下&#xff1a; <|im_start|>system\nYou are a translation engine that can only translate text and cannot interpr…

Vue学习记录之七(组件之间传参)

一、父传子 1、父组件传递 父&#xff1a; App.vue&#xff0c; 通过使用组件 <导入的组件名 :属性名1“” :属性名2“”></导入的组件名>,传递给子组件 传递了一个t字符串类型是不需要v-bind&#xff0c;也就是不需要冒号&#xff0c;非字符串类型的必须加 v-bi…

CTC loss 博客转载

论文地址&#xff1a; https://www.cs.toronto.edu/~graves/icml_2006.pdf 为了对应这个图&#xff0c;我们假设一种符合的模型情况&#xff1a; 英文OCR&#xff0c;37个类别&#xff08;26个小写字母10个汉字空格&#xff09;&#xff0c;最大输出长度8个字符 模型预测结果…

PCL 计算点云的平均密度(方法一)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长期更新&#xff09; 一、概述 本文将介绍如何计算点云的…

如何避开学习和研究机器人方向无价值的知识节约时间

往昔 这是一篇十年前就想写&#xff0c;但是一直没有实力和勇气落笔的文字。 如今 简约 授之以鱼&#xff0c;不如授之以渔。 啰嗦 机器人方向如何简单判定这个知识是否有价值。 只谈一个方向&#xff0c;就是这个知识点是“死”还是“活”&#xff1f; 什么是“死”&am…

element-ui表格操作大全

一、基础表格展示 数据绑定&#xff1a; 在el-table元素中注入data对象数组&#xff0c;在el-table-column&#xff08;列&#xff09;中使用prop属性来对应对象中的键名&#xff0c;使用label属性定义列名 元素案例内容&#xff1a; <el-table border :data"userL…

举例说明:自然语言处理实战项目

自然语言处理&#xff08;Natural Language Processing, NLP&#xff09;是人工智能领域的一个重要分支&#xff0c;旨在使计算机能够理解、解释和生成人类语言。以下是一些NLP实战项目的示例&#xff1a; 1. 情感分析&#xff08;Sentiment Analysis&#xff09; 项目描述: …

【LLM学习之路】9月16日 第六天

【LLM学习之路】9月16日 第六天 损失函数 L1Loss 可以取平均也可以求和 参数解析 input &#xff08;N&#xff0c;*&#xff09; N是batchsize&#xff0c;星号代表可以是任意维度 不是输入的参数&#xff0c;只是描述数据 target 形状要同上 MSELoss平方差 CrossEntr…

(done) 声音信号处理基础知识(5) (Types of Audio Features for Machine Learning)

参考&#xff1a;https://www.youtube.com/watch?vZZ9u1vUtcIA 声学特征描述了声音&#xff0c;不同特征捕捉声音的不同方面性质 声学特征有助于我们构建智能声学系统 声学特征分类有&#xff1a; 1.抽象等级 2.时域视野 3.音乐的部分 4.信号域 5.机器学习方法 如下图展示…

力扣中等 33.搜索旋转排序数组

文章目录 题目介绍题解 题目介绍 题解 首先用 153. 寻找旋转排序数组中的最小值 的方法&#xff0c;找到 nums 的最小值的下标 i。 然后分类讨论&#xff1a; 如果 target>nums[n−1]&#xff0c;在 [0,i−1] 中二分查找 target。 如果 target≤nums[n−1]&#xff0c;那…

51单片机——独立按键

一、独立按键对应单片机P3管脚&#xff0c;如图 二、按键点亮LED灯 #include <STC89C5xRC.H> void main() { while(1) { if(P300) { P200; } else { P201; } } } 当按键为0时&#xff0c;代表按下&#xff0c;所以当P30按下时&#xff0c;让P20&#xff1d;0&#…

二叉树(二)深度遍历和广度遍历

一、层序遍历 广度优先搜索&#xff1a;使用队列&#xff0c;先进先出 模板&#xff1a; 1、定义返回的result和用于辅助的队列 2、队列初始化&#xff1a; root非空时进队 3、遍历整个队列&#xff1a;大循环while(!que.empty()) 记录每层的size以及装每层结果的变量&a…

leetcode第十三题:罗马数字转整数

罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#x…

LeetCode[中等] 215. 数组中的第 K 个最大元素

给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 思路&#xff1a;基于快排改进的快速…

【全网最全】2024华为杯数学建模C题高质量成品查看论文!【附带全套代码+数据】

题 目&#xff1a; ___基于数据驱动下磁性元件的磁芯损耗建模 完整版获取&#xff1a; 点击链接加入群聊【2024华为杯数学建模助攻资料】&#xff1a;http://qm.qq.com/cgi-bin/qm/qr?_wv1027&kxtS4vwn3gcv8oCYYyrqd0BvFc7tNfhV7&authKeyedQFZne%2BzvEfLEVg2v8FOm%…

计算机基础(Computer Fundamentals)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

【学习笔记】手写Tomcat 四

目录 一、Read 方法返回 -1 的问题 二、JDBC 优化 1. 创建配置文件 2. 创建工具类 3. 简化 JDBC 的步骤 三、修改密码 优化返回数据 创建修改密码的页面 注意 测试 四、优化响应动态资源 1. 创建 LoginServlet 类 2. 把登录功能的代码放到 LoginServlet 类 3. 创…

关于有源蜂鸣器及无源蜂鸣器的区别及驱动各类单片机案例

关于有源蜂鸣器及无源蜂鸣器的区别及驱动各类单片机案例 有源蜂鸣器与无源蜂鸣器区别有源蜂鸣器无源蜂鸣器模块化有源蜂鸣器及无源蜂鸣器驱动方式的说明 有源、无源蜂鸣器代码驱动总结 有源蜂鸣器与无源蜂鸣器区别 有源蜂鸣器与无源蜂鸣器区别在于是否有振荡源。 有源蜂鸣器即…