05-Vue计算属性

282 阅读2分钟

1.介绍

Vue.js 的模板表达式非常方便,但它最合适的使用场景是简单的布尔操作或字符串拼接。如果涉及更复杂的逻辑,会让模板过重且难以维护。例如:

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

你必须看一段时间才能意识到,这是一个反转字符串的例子, 模板变的很复杂起来,也不容易看懂理解,当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。所以这个时候应该使用计算属性。

所以,对于任何复杂逻辑,都应当使用计算属性

2. 基础例子

<div id="app">
  {{ message }}
</div>
<script>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello'
  },
  // 专门用于定义计算属性的
  computed: {
    message: function () { 
        //  `this` 指向 vm 实例
        let res = this.message.split('').reverse().join('');
        return res;
    }
  }
})
</script>

结果: olleH

虽然在定义计算属性的时候是通过一个函数返回的数据, 但是在使用计算属性的时候不能在计算属性名称后面加上(), 因为它是一个 属性 不是一个函数(方法)

3. 计算属性 vs 方法

通过计算属性我们能拿到处理后的数据, 但是通过函数(方法)我们也能拿到处理后的数据

那么计算属性和函数有什么区别呢?
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。
简单的说

  • 计算属性将计算的结果缓存起来, 只要数据没有发生变化, 就不会重新求值
  • 函数不会将计算的结果缓存起来, 每一次访问都会重新求值

例如:

<div id="app">
    <p>{{msg1()}}</p>
    <p>{{msg1()}}</p>
    <p>{{msg1()}}</p>

    <p>{{msg2}}</p>
    <p>{{msg2}}</p>
    <p>{{msg2}}</p>
</div>
<script>
    let vue = new Vue({
        el: '#app',
        // 专门用于存储监听事件回调函数
        methods: {
            msg1() {
                console.log("msg1函数被执行了");
                let res = 'abcdef'.split('').reverse().join('');
                return res;
            }
        },
        // 专门用于定义计算属性的
        computed: {
            msg2: function () {
                console.log("msg2计算属性被执行了");
                let res = 'abcdef'.split('').reverse().join('');
                return res;
            }
        }
    });
</script>

这里的msg1会被执行3次, 而msg2只会执行1次。

所以: 计算属性比较适合用于计算不会频繁发生变化的的数据