基于 Laravel 的 Vue.js 中文学习教程 —— 计算属性

在模板中绑定表达式非常方便,但这仅限于一些简单的操作,因为模板的主要作用是用于描述视图的结构,将过多逻辑放到模板中会让其变得臃肿且不易维护,这就是为什么Vue.js限制一次只能绑定一个表达式,对于那些需要多个表达式的逻辑,需要使用计算属性

基本示例

HTML代码:

<div id="example">
    a=@{{ a }}, b=@{{ b }}
</div>

JS代码:

var vm = new Vue({
    el: '#example',
    data: {
        a: 1
    },
    computed: {
        // a computed getter
        b: function () {
            // `this` points to the vm instance
            return this.a + 1
        }
    }
})

这样,显示结果为:

计算属性基本示例

这里我们声明了一个计算属性b。我们提供的这个函数还可以用作 vm.b 属性值获取方法:

console.log(vm.b) // -> 2
vm.a = 2
console.log(vm.b) // -> 3

你可以自己在浏览器控制台(console)中演示上面的例子,你会发现, vm.b 的值总是依赖于 vm.a

Vue计算属性基本示例

你可以像普通属性一样在模板中绑定数据到计算属性。Vue知道 vm.b 依赖于 vm.a ,所以当 vm.a 改变时, vm.b 会改变,绑定到 vm.b 的数据也会相应改变。此外,更妙的是我们声明式地创建了依赖关系,计算 getter 方法是干净无副作用的,这也更容易理解和测试。

计算属性 vs $watch

Vue.js还提供一个API方法 $watch 用于观察Vue实例上的数据更改。当你有一些数据需要基于另一些数据进行修改的时候,使用 $watch 会很方便 —— 尤其是之前使用过 AngularJS ,但是,更好的方法是使用计算属性而不是命令式的  $watch 回调。看看下面这个例子:

HTML代码:

<div id="demo">@{{fullName}}</div>

JS代码:

var vm = new Vue({
    el: '#demo',
    data: {
        firstName: 'Laravel',
        lastName: '学院',
        fullName: 'Laravel 学院'
    }
})

vm.$watch('firstName', function (val) {
    this.fullName = val + ' ' + this.lastName
})

vm.$watch('lastName', function (val) {
    this.fullName = this.firstName + ' ' + val
})

上面的代码是命令式的、重复的。比较一下通过计算属性实现的版本:

var vm = new Vue({
    el: '#demo',
    data: {
        firstName: 'Laravel',
        lastName: '学院'
    },
    computed: {
        fullName: function () {
            return this.firstName + ' ' + this.lastName
        }
    }
})

更好更清爽,不是吗?

计算setter

计算属性默认是getter,但是如果需要你也可以提供setter功能:

// ...
computed: {
    fullName: {
        // getter
        get: function () {
            return this.firstName + ' ' + this.lastName
        },
        // setter
        set: function (newValue) {
            var names = newValue.split(' ')
            this.firstName = names[0]
            this.lastName = names[names.length - 1]
        }
    }
}
// ...

现在,如果你调用 vm.fullName = 'Laravel Academy' ,setter会被触发, vm.firstNamevm.lastName 的值也会相应更新。

关于计算属性更新原理我们在后续章节还会深入探讨。

学院君

学院君 has written 550 articles

资深PHP工程师,Laravel学院院长