Vue 中 Computed 的使用及其执行时机

Computed 计算属性

  • computed 在 Vue 中为计算属性,通常,在一个 Computed 中,传入一个函数,该函数可以根据其他响应式变量进行计算,然后 return
    一个响应式的变量,当其依赖的响应式变量发生变化时,该 computed 会重新计算并返回。
  • 官方文档:https://cn.vuejs.org/guide/essentials/computed.html

基本使用

  • 下方例子中,用户输入 firstName 或 lastName 都会引起 fullName 的重新拼接

选项式 API


<template>
  <div>
    {
  { fullName }}
    <input v-model="firstName"/>
    <input v-model="lastName"/>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        firstName: '',
        lastName: ''
      }
    },
    computed: {
      fullName() {
        return this.firstName + this.lastName
      }
    }
  }
</script>

组合式 Api


<template>
  <div>
    {
  { fullName }}
    <input v-model="firstName"/>
    <input v-model="lastName"/>
  </div>
</template>

<script setup>

  import {computed, ref} from "vue";

  const firstName = ref('')
  const lastName = ref('')

  const fullName = computed(() => firstName.value + lastName.value)

</script>

可变计算属性

  • 一般来说,上述的用法,computed 计算出来的结果是不可变的,那么 computed 的另外一种用法则支持其发生修改
  • 这种用法在 Vue2 中的组件上使用 v-model 时很好用,一般来说,子组件是不能更改 props 的值的,那么在 vue2 中如果在组件上使用
    v-model 来双向绑定一个属性,通常子组件中使用 value 来接收这个值(Vue3 默认使用 modelValue 来接收),通过触发 input
    事件来修改这个值(vue3 默认触发 update:modelValue
    事件来修改),使得该组件允许双向绑定一个属性。在子组件内部,该值始终是单向数据流,其获取与修改均在父组件中完成,子组件无法直接修改其值,只能通过触发事件来修改父组件的值,此时,使用 computed 的 get 和 set 就可以优化这个操作

<template>
  <div>
    <input v-model="name"/>
  </div>
</template>

<script>

  export default {
    props: {value: {type: String, default: ''}},
    computed: {
      name: {
        get() {
          return this.value
        },
        set(newValue) {
          this.$emit('input', newValue)
        }
      }
    }
  }

</script>
  • 上方示例中,子组件可以直接修改 name 来触发父组件的更新,也可以通过读取 name 来获取父组件传递下来的值
  • 另外一个案例在与后端的交互中,请求参数中要传入一个时间范围,使用 startTime 和 endTime 来接收,而 elementPlus
    的时间选择器绑定的是一个数组,此时就可以使用 computed 的 get 和 set 来进行映射

<template>
  <div>
    <el-date-picker v-model="timeRange"></el-date-picker>
  </div>
</template>

<script setup>

  import {computed, reactive} from "vue";

  const param = reactive({startTime: '', endTime: ''})

  const timeRange = computed({
    get: () => [param.startTime, param.endTime],
    set: nv => {
      if (!nv) return
      if (nv[0]) param.startTime = nv[0]
      if (nv[1]) param.endTime = nv[1]
    }
  })

</script>
  • 使用上述方法,就可以优化 el-date-picker 的使用

Computed 的缓存机制与执行时机问题

  • 很多前端开发者都熟读并背诵:‘Computed 计算属性会在其依赖发生变化的时候重新进行计算,并且将结果缓存起来,如果结果不变,那么不会重复执行’
  • 对于这段话的理解,很多开发者可能有误,很多人可能存在的误区:
  1. 计算属性是在其依赖的响应式对象发生变化时重新计算的
  2. 计算属性的缓存是基于计算结果的
  • 官网的解释: 计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。这意味着只要 author.books 不改变,无论多少次访问 publishedBooksMessage 都会立即返回先前的计算结果,而不用重复执行 getter 函数。
  • 官网的解释中可以得知,计算属性的缓存是基于其依赖的响应式变量,而非结果,可以做如下实验:使用一个计算属性计算 count1 和 count2 的值,2 + 3 = 5,如果 computed 的缓存是基于结果的,那么当 count1 和 count2 变成 1 + 4 = 5 时,计算属性应该不会执行,因为结果都是 5

<body>
<div id="app">
    <div>{
  { count1 }} + {
  { count2 }} = {
  { computedCount }}</div>
    <button @click="countUpdate">更新 count</button>
</div>
</body>
<script>
    const {
     createApp, computed
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值