vue.js 是一套构建用户界面的渐进式框架. 与其他重量级框架不同的是, vue 采用自底向上增量开发的设计. 本文为大家介绍了 vue 中的计算属性, 希望对大家有一定的帮助.
一, 什么是计算属性
模板内的表达式非常便利, 但是设计它们的初衷是用于简单运算的. 在模板中放入太多的逻辑会让模板过重且难以维护. 例如:
- <div id="example">
- {{ message.split('').reverse().join('') }}
- </div>
这里的表达式包含 3 个操作, 并不是很清晰, 所以遇到复杂逻辑时应该使用 Vue 特带的计算属性 computed 来进行处理.
二, 计算属性的用法
在一个计算属性里可以完成各种复杂的逻辑, 包括运算, 函数调用等, 只要最终返回一个结果就可以.
我们把上面的例子用计算属性的方式重写一下
- <div id="example">
- <p>Original message: "{{ message }}"</p>
- <p>Computed reversed message: "{{ reversedMessage }}"</p>
- // 我们把复杂处理放在了计算属性里面了
- </div>
- var vm = new Vue({
- el: '#example',
- data: {
- message: 'Hello'
- },
- computed: {
- reversedMessage: function () {
- // `this` 指向 vm 实例
- return this.message.split('').reverse().join('')
- }
- }
- });
结果:
- Original message: "Hello"
- Computed reversed message: "olleH"
除了上例简单的用法, 计算属性还可以依赖多个 Vue 实例的数据, 只要其中任一数据变化, 计算属性就会重新执行, 视图也会更新.
- <body>
- <div id="app">
- <button @click="add()"> 补充货物 1</button>
- <div > 总价为:{{price}}</div>
- </div>
- </body>
- var App = new Vue({
- el: '#app',
- data: {
- package1: {
- count: 5,
- price: 5
- },
- package2: {
- count: 10,
- price: 10
- }
- },
- computed: {
- price: function(){
- return this.package1.count*this.package1.price
- +this.package2.count*this.package2.price
- // 总价随着货物或价格的改变会重新计算
- }
- },
- methods: { // 对象的方法
- add: function(){
- this.package1.count++
- }
- }
- });
计算属性还有两个很实用的小技巧容易被忽略: 一是计算属性可以依赖其他计算属性; 二是计算属性不仅可以依赖当前 Vue 实例的数据, 还可以依赖其他实例的数据, 例如:
- <div id="app1"></div>
- <div id="app2">{{ reverseText}}</div>
- var app1 = new Vue({
- el: '#app1',
- data: {
- text: 'computed'
- }
- });
- var app2 = new Vue({
- el: '#app2',
- computed: {
- reverseText: function(){
- return app1.text.split('').reverse().join('');
- // 使用 app1 的数据进行计算
- }
- }
- });
每一个计算属性都包含一个 getter 和一个 setter , 我们上面的两个示例都是计算属性的默认用法, 只是利用了 getter 来读取.
在你需要时, 也可以提供一个 setter 函数, 当手动修改计算属性的值就像修改一个普通数据那样时, 就会触发 setter 函数, 执行一些自定义的操作, 例如:
- var vm = new Vue({
- el: '#demo',
- data: {
- firstName: 'Foo',
- lastName: 'Bar'
- },
- 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 = 'John Doe' 时, setter 会被调用,
- //vm.firstName 和 vm.lastName 也会相应地被更新.
绝大多数情况下, 我们只会用默认的 getter 方法来读取一个计算属性, 在业务中很少用到 setter, 所以在声明一个计算属性时, 可以直接使用默认的写法, 不必将 getter 和 setter 都声明.
三, 计算属性缓存
上面的例子, 除了使用计算属性外, 我们也可以通过在表达式中调用方法来达到同样的效果, 如:
- <div>{{reverseTitle()}}</div>
- // 在组件中
- methods: {
- reverseTitle: function () {
- return this.title.split('').reverse().join('')
- }
- }
我们可以将同一函数定义为一个方法而不是一个计算属性, 两种方式的最终结果确实是完全相同的. 只是一个使用 reverseTitle() 取值, 一个使用 reverseTitle 取值.
然而, 不同的是计算属性是基于它们的依赖进行缓存的. 计算属性只有在它的相关依赖发生改变时才会重新求值.
这就意味着只要 title 还没有发生改变, 多次访问 reverseTitle 计算属性会立即返回之前的计算结果, 而不必再次执行函数.
举个小例子:
- <div>{{reverseTitle}}</div>
- <div>{{reverseTitle1()}}</div>
- <button @click="add()"> 补充货物 1</button>
- <div > 总价为:{{price}}</div>
- computed: {
- reverseTitle: function(){
- return this.title.split('').reverse().join('')
- // 而使用计算属性, 只要 title 没变, 页面渲染是不会重新进这里来计算的, 而是使用了缓存.
- },
- price: function(){
- return this.package1.count*this.package1.price+
- this.package2.count*this.package2.price
- }
- },
- methods: { // 对象的方法
- add: function(){
- this.package1.count++
- },
- reverseTitle1: function(){
- return this.title.split('').reverse().join('')
- // 点击补充货物, 也会进这个方法, 再次计算. 不是刷新, 而是只要页面渲染, 就会进方法里重新计算.
- }
- },
相比之下, 每当触发重新渲染时, 调用方法将总会再次执行函数.
我们为什么需要缓存? 假设我们有一个性能开销比较大的的计算属性 A, 它需要遍历一个巨大的数组并做大量的计算. 然后我们可能有其他的计算属性依赖于 A .
如果没有缓存, 我们将不可避免的多次执行 A 的 getter! 如果你不希望有缓存, 请用方法来替代.
本文转自: https://www.cnblogs.com/chaixiaozhi/p/8688820.html
来源: http://www.css88.com/web/vue-js/16162.html