Vue中计算属性computed

Vue中计算属性computed

什么是计算属性

在Vue中,computed属性用于计算某个属性的值,以响应式地更新视图。computed属性是基于它们的依赖进行缓存的,也就是说只有依赖发生变化时,computed属性才会重新计算。

computed属性通常是一个函数,在Vue实例中定义为一个对象的属性。以下是computed属性的用法示例:

javascript 复制代码
new Vue({
  data: {
    number1: 10,
    number2: 5
  },
  computed: {
    // 计算number1加number2的结果
    sum: function() {
      return this.number1 + this.number2;
    },
    // 计算number1减number2的结果
    difference: function() {
      return this.number1 - this.number2;
    }
  }
});

在上述示例中,我们定义了两个computed属性sum和difference,分别计算number1加number2和number1减number2的结果。在模板中使用这两个computed属性时,可以直接通过属性名来获取它们的计算结果:

html 复制代码
<div>
  Sum: {{ sum }}
</div>
<div>
  Difference: {{ difference }}
</div>

在模板中,{{ sum }}和{{ difference }}会根据number1和number2的值实时更新,并显示最新的计算结果。

需要注意的是,computed属性的值是只读的,不应该尝试在computed属性中修改它们的依赖值。如果想要修改数据,应该使用methods方法,或者添加set方法:

计算属性的 Setter

计算属性默认只有 getter,不过也可以去设置一个 setter,像下面一样:

vue 复制代码
computed: {
  fullName: {
    // getter
    get() {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set(newValue) {
      const names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

当我们运行 this.fullName = '张 三' 时,setter 会被调用,this.firstNamethis.lastName 也会相应地被更新。

为什么要用computed计算属性

在Vue中,我们可以轻松的实现数据到DOM映射,使用模板内的表达式也很方便,但如果在模板内写入太多的逻辑的话就会让模板难以维护。

vue 复制代码
<template>
  <div :title="msg">
    {{ msg }}
    {{ msg.length }}  <!-- 这里简单计算了msg的长度不用计算属性也能达到目的 -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      msg: 'Hello World',
    }
  },
}
</script>

但当我们有一个列表,我们通过数量来显示不同的状态信息,请看下面的例子:

vue 复制代码
<template>
  <div class="status">
    {{ List.length > 0 ? '有货' : '无货'}}
  </div>
</template>

<script>
export default {
  data() {
    return {
      List: [{
        type: '西瓜',
      }],
    }
  },
}
</script>

此时,模板已经不再是简单的了,我们必须得看一下模板内的表达式才能知道它的状态是取决于List.length。那么如果在模板中有多个地方需要同样状态,我们就必须写多份同样的代码,这样模板就会变得更加的糟糕了。

所以,当我们需要处理一些响应式数据的复杂逻辑时,我们就应该去使用计算属性computed。看下面的例子:

vue 复制代码
<template>
  <div class="status">
    {{ Status }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      List: [{
        type: '西瓜',
      }],
    }
  },
  computed: {
    Status() {
      return this.List.length > 0 ? '有货' : '无货'
    },
  },
}
</script>

这里我们声明了一个计算属性Status

如果我们去更改List数组的值,那么将会看到Status也会相应的进行修改。

我们可以像绑定普通属性一样将计算属性绑定到模板中。Vue在内部知道Status依赖于List,所以当List发生变化时,所有依赖Status的绑定也都会更新。最巧妙的是我们已经通过声明的方式创建了这个依赖方式,而且计算属性的getter函数没有副作用,使得更加容易测试。

computed(计算属性) VS methods(方法)

上面的代码我们也可以通过方法的形式来实现它,例如:

html 复制代码
<template>
  <div class="status">
    {{ getStatus() }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      tList: [{
        type: '西瓜',
      }],
    }
  },
  methods: {
    getStatus() {
      return this.List.length > 0 ? '有货' : '无货'
    },
  },
}
</script>

我们将相同的逻辑定义为一个函数,而不是计算属性。可以看到两种方式实现的结果是完全相同的。那么有什么不同呢?

不同的地方是:

计算属性是基于响应依赖关系缓存的,计算属性只有在响应式依赖发生改变时才会重新求值,也就是说如果productList永远不发生改变的话,那么每次访问上面的productStatus计算属性都会返回之前计算好的结果,而不必再次去执行函数进行运算。也就是说计算属性会有缓存数据的功能。

比如下面的代码的计算属性将永远不会更新,因为 Date.now () 不是响应式依赖:

js 复制代码
computed: {
  now() {
    return Date.now()
  }
}

相比计算属性,使用方法的方式,每当触发重新渲染的时候,方法就总会再次被执行。如果模板中有N个方法调用,那么将调用N次。

那么计算属性的缓存有什么优势呢?

假设我们有一个对性能要求较大的计算属性 list,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 list。如果没有缓存,我们将不可避免的多次执行 list 的 getter!

这样的设计会在性能上有所提高。

相关推荐
理想不理想v5 分钟前
vue经典前端面试题
前端·javascript·vue.js
不收藏找不到我6 分钟前
浏览器交互事件汇总
前端·交互
小阮的学习笔记19 分钟前
Vue3中使用LogicFlow实现简单流程图
javascript·vue.js·流程图
YBN娜20 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=20 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
杨荧22 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
minDuck24 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。1 小时前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui