一,前言

上一篇介绍了Vue的方法和事件,在Vue实例methods选项中对方法进行定义
这一篇介绍Vue的计算属性,计算属性定义在vue实例compute选项中,
compute计算属性功能上和methods中的方法很相似,
稍后我们会探讨计算属性的使用及计算属性和方法的区别

二,引入计算属性

之前介绍了插值(即双大括号表达式),支持简单的表达式和过滤器可以对值做一些简单运算和文本转换
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的
在模板中放入太多的逻辑会让模板过重且难以维护

例如:

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

过长的表达式中包含了3个操作,模板不再是简单的声明式逻辑,
复杂的逻辑会使代码变得难以理解(可读性差)和维护,且无法复用
所以,对于任何复杂逻辑,都应使用计算属性


三,使用计算属性

对上边的例子使用计算属性进行改写:

<div id="app">
  <!--输出DEF,ABC-->
  {{ reverseText }}
</div>

<script type="text/javascript">
  const vm = new Vue({
    el: '#app',
    data: {
      text: 'ABC,DEF'
    },
    computed: {
      reverseText: function () {
        // this指向当前vue实例
        return this.text.split(',').reverse().join(',')
      }
    }
  })
</script>
使用Vue计算属性对属性应用计算逻辑,
计算属性以函数形式声明在Vue实例的computed选项内,最终返回计算后的结果

四,计算属性在购物车的应用

在电商项目中,计算属性的一个典型使用场景就是购物车页面
通过勾选购物车中的商品或修改商品购买数量计算总价
<div id="app">
  商品总价 : {{ prices }}
</div>

<script type="text/javascript">
  const vm = new Vue({
    el: '#app',
    data: {
      books: [
        {name: 'Vue.js', price:50},
        {name: 'Javascript', price:30},
        {name: 'Css', price:40},
        {name: 'Html', price:60}
      ]
    },
    computed: {
      prices: function () {

        var totlePrice = 0;

        for(var i=0; i<this.books.length; i++){
          totlePrice += this.books[i].price;
        }

        return totlePrice;
      }
    }
  })
</script>
简单使用books模拟购物商品,页面显示计算属性返回的商品总价

运行结果:

页面初始化显示由计算属性计算得到的商品总价

购物车初始化

通过devTools修改第一个商品的价格,由50变化到51,此时会触发计算属性,更新价格显示

购物车修改商品价格

再通过devTools删除第一个商品,此时会触发计算属性,更新价格显示

购物车删除商品

结论:

在计算属性中所依赖的Vue实例数据有任何变化,都触发计算属性重新执行,更新视图显示

五,计算属性中的getter和setter

实际上,每一个计算属性都包含一个getter和setter,默认只使用getter进行数据读取
我们也可以提供setter函数,当手动修改计算属性值时会触发setter方法

引用一个经典的例子进行说明:

<div id="app">
  姓名:<input type="text" v-model="fullName">
</div>

<script type="text/javascript">
  const vm = new Vue({
    el: '#app',
    data: {
      firstName:"Jack",
      lastName:"Green"
    },
    computed: {
      fullName:{
        // getter
        get: function () {
          return this.firstName + " " + this.lastName;
        },
        // setter
        set: function (newVal){
          var name = newVal.split(' ');
          this.firstName = name[0];
          this.lastName = name[1];
        }
      }
    }
  })
</script>

运行结果:

初始化通过计算方法得到fullName显示
setter1

修改fullName值,触发setter方法,重新对firstName和lastName赋值
setter2

对于计算属性,大多数情况下不必将getter和setter都声明,
实际业务中很少使用到setter方法,所以声明计算属性时,直接使用默认写法即可

注意:

计算属性可以依赖其他计算属性,并且计算属性可以依赖当前Vue实例以外的其他Vue实例数据

六,computed VS methods

对比computed和methods,他们之中的方法都可以实现相同的作用

将本篇由computed实现的Demo改写为methods实现:

<div id="app">
  <!--输出DEF,ABC-->
  {{ reverseText() }}
</div>

<script type="text/javascript">
  const vm = new Vue({
    el: '#app',
    data: {
      text: 'ABC,DEF',
    },
    methods:{
      reverseText: function () {
        // this指向当前vue实例
        return this.text.split(',').reverse().join(',')
      }
    }
  })
</script>
这里没有使用计算属性,改用在methods定义的方法实现了相同的效果
computed 和 methods的区别
computed 和 methods虽然都可以实现对数据的计算,但两者有一定的区别:

methods:

使用methods方法可以接受外部传参,使用更加灵活

computed:

计算属性computed的亮点在于:它能够依赖缓存
当计算属性所依赖的数据发生改变时,才会重新触发计算属性方法执行
所以对于较复杂或消耗效率的计算,一定要采用计算属性

使用methods的方法,每次页面刷新都会触发方法的执行
而使用计算属性,只要依赖的数据没有变化,就会直接从缓存中读取结果,不需要重新计算
这种做法可以提升效率更可以带来更好的用户体验

但是,并不是使用computed就一定更好

computed: {
    now: function(){
        return Data.now();
    }
}    
由于Data.now并不是响应式依赖,所以计算属性now不会更新
但是methods不同,只要重新渲染就会执行

所以,使用methods还是计算属性主要取决于是否需要缓存
当对大数组遍历或计算量较大时,应使用计算属性,不需要缓存使用methods


七,结尾

这一篇主要介绍了计算属性的使用,methods的对比及适用场景
计算属性基于缓存,在所依赖的数据发生变化时,会触发执行刷新页面显示

在Vue还通过watch选项提供了一个侦听器,可以自定义对数据的监听事件来响应数据的变化
下一篇介绍Vue选项watch侦听器
Logo

前往低代码交流专区

更多推荐