首页 前端知识 带你深度吃透Vue3 中计算属性 computed() 的使用

带你深度吃透Vue3 中计算属性 computed() 的使用

2024-05-20 14:05:33 前端知识 前端哥 340 527 我要收藏

在这里插入图片描述

文章目录

  • 导语:
  • 概念
  • 案例
  • 计算属性缓存机制
  • 计算属性调试
  • computed() 标注类型
  • 扩展
  • 性能优化

在这里插入图片描述

前情摘要:

本文是在基于 Vue3 的:v3.4.21 版本基础上进行整理的。后续官方如有版本更新有关 计算属性 (computed) 的新特性欢迎留言讨论。

导语:

当我们有时候需要将模版中的某一个数据进行一系列处理后从而得到一个新的值,虽然 Vue 的模版中能够支持我们写一些表达式,来达到这样的目的,但是这样会使得我们的模板变得臃肿且不够灵活定制化,所以 Vue 也并不推荐我们在模板中写太多的表达式。因此 Vue 推荐我们使用计算属性(computed)来描述依赖响应式状态的复杂逻辑。

概念

computed ()接受一个 getter 函数,返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 getset 函数的对象来创建一个可写的 ref 对象。

案例

创建一个只读的计算属性 ref:

<script setup lang="ts" name="box">
	import { ref, computed } from 'vue';
	
	const count = ref(1)
	const plusOne = computed(() => {
	    return count.value + 7 * 3 / 5
	})
	console.log(plusOne.value) // 5.2
	plusOne.value++  //错误,只读的
</script>

在这里插入图片描述

computed() 返回值为一个计算属性 ref

在这里插入图片描述

和其它一般的 ref 类似,你可以通过 .value 访问计算结果。计算属性 ref 也会在模板中自动解包,因此在模板表达式中引用时无需添加 .value,并且 Vue 的计算属性会自动追踪响应式依赖

创建一个可写的计算属性 ref:

<script setup lang="ts" name="box">
    import { ref, computed } from 'vue';

    const count = ref(1)
    const plusOne = computed({
        get: () => count.value + 7 * 3 / 5,
        set: (val) => {         //修改计算属性的时候,set函数接收一个参数值为要修改的值,
                                //将修改的值赋值给计算源数据,从而重新计算生成新的属性值。
            console.log(val); //25
            count.value = val - 6
            console.log(count.value);   //19
        }
    })
    plusOne.value = 25
    console.log(plusOne.value) // 23.2

</script>

计算属性默认是只读的。当你尝试修改一个计算属性时,你会收到一个运行时警告。只在某些特殊场景中你可能才需要用到“可写”的属性,你可以通过同时提供 getter 和 setter 来创建

计算属性缓存机制

当我们提供一个函数并返回一个处理后的值,同时创建一个计算属性也返回相同处理逻辑的值,那么它们会得到相同的的结果,倘若我们将同样的函数定义为一个普通方法而不是一个计算属性,两种方式在结果上确实是完全相同的,然而,不同之处在于计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。相比之下,函数方法调用总是会在重渲染发生时再次执行函数,这会导致一个非常消耗性能并且非必要的行为,反之,计算属性,就恰恰不会存在这样的问题。它的每一次更新都是必要性的。


计算属性调试

我们可以向 computed() 传入第二个参数,是一个包含了 onTrackonTrigger 两个回调函数的对象:

  • onTrack :将在响应属性或引用作为依赖项被跟踪时被调用。
  • onTrigger :将在侦听器回调被依赖项的变更触发时被调用。
<script setup lang="ts" name="Box">
	import { ref, computed, } from 'vue'
	
	const count = ref(1)
	const plusOne = computed({
	    get: () => count.value + (7 * 3) / 5,
	    set: (val) => {
	        console.log(val) //25
	        count.value = val - 6
	        console.log(count.value) //19
	    }
	}, {
	    onTrack(e) {
	        console.log('当 count.value 被追踪为依赖时触发');
	        // debugger
	    },
	    onTrigger(e) {
	        console.log('count.value 被更改时触发');
	        // debugger
	    }
	})
	plusOne.value = 25  //  onTrigger 会触发
	console.log(plusOne.value) //  onTrack 会触发

</script>

在这里插入图片描述

查看计算属性调试


computed() 标注类型

  • computed() 默认会自动从其计算函数的返回值上推导出类型
  • 你还可以通过泛型参数显式指定类型:
const double = computed<number>(() => {
  // 若返回值不是 number 类型则会报错
})

扩展

Getter 不应有副作用

计算属性的 getter 应只做计算而没有任何其他的副作用,这一点非常重要,请务必牢记。举例来说,不要改变其他状态、在 getter 中做异步请求或者更改 DOM!一个计算属性的声明中描述的是如何根据其他值派生一个值。因此 getter 的职责应该仅为计算和返回该值

避免直接修改计算属性值

从计算属性返回的值是派生状态。可以把它看作是一个“临时快照”,每当源状态发生变化时,就会创建一个新的快照。直接更改快照是没有意义的,因此计算属性的返回值应该被视为只读的,并且永远不应该被更改。我们应该更新它所依赖的源数据状态以触发新的计算。


性能优化

点击查看计算属性新特性之性能优化

在这里插入图片描述


🚵‍♂️ 博主座右铭:向阳而生,我还在路上!
——————————————————————————————
🚴博主想说:将持续性为社区输出自己的资源,同时也见证自己的进步!
——————————————————————————————
🤼‍♂️ 如果都看到这了,博主希望留下你的足迹!【📂收藏!👍点赞!✍️评论!】
——————————————————————————————

转载请注明出处或者链接地址:https://www.qianduange.cn//article/8953.html
标签
评论
会员中心 联系我 留言建议 回顶部
复制成功!