VUE 计算属性入门介绍

本文将介绍一下Vue中的计算属性。

注意1: 官网已经写的很好了,我只是狗尾续貂一波^^

注意2: 因为是在官网基础上写的,所以本文在“有些角度”应该还是比官网写的更好一点,从头到尾使用相同的例子阐述,更容易理解计算属性与Vue其他特性的区别,所以在查看官网之余也推荐看一下我的版本!

本文目录:

Vue中的普通属性

在讲计算属性之前,先看一下VUE中的普通属性,直接上代码:

var vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello World'
  }
});

使用起来很简单,将普通属性放在两个双括号内即可:

<div id="app">
  {{ message }}
</div>

页面会变成这个样子:

image-20210429080753867

新需求,普通属性的实现和问题

假设我们来了个新需求,需要将message中的信息翻转再显示出来。例如,“Hello World” 需要变成 “World Hello”再显示出来。 代码怎么写呢?

通常做法可以直接在模版中写表达式:

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

页面显示符合需求

image-20210429080647656

虽然上面的方法可以实现信息反转,但是存在一些不足之处:

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。假如如果页面上有多处需要显示翻转后的message,我们到处写message.split('').reverse().join('') 岂不怪哉!

调用方法

为了解决上述问题,我们可以将翻转的逻辑放在一个函数中,然后在模版中调用函数:

<div id="app">
  {{ reversedMessage() }}
</div>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello World'
  },
  methods: {
    reversedMessage: function() {
      return this.message.split(' ').reverse().join(' ');
    }
  }
});

image-20210429080607676

可以看到,模版中调用函数使得模版代码更加简洁易懂。

但调用方法仍有不足:假如方法十分复杂、缓慢、消耗资源,我们到处页面上每每用到该函数都需要计算一遍,十分浪费!

计算属性

Vue可以通过“计算属性”来达到与调用方法同样的效果,但同时具有缓存功能!使用很简单,只需要像定义方法一样在computed中增加计算属性即可。代码例子:

<div id="app">
  {{ reversedMessage }}
</div>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello World'
  },
  computed: {
    reversedMessage: function() {
      return this.message.split(' ').reverse().join(' ');
    }
  }
});

image-20210429080719065

Vue官网的一段话描述了计算属性的缓存功能:

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

请注意,计算属性是一个“属性”而不是方法,所以在模版中我使用了{{ reversedMessage }} 而不是{{ reversedMessage() }}

计算属性 vs. 侦听器

其实,还有一种方法可以实现类似的需求,那就是使用Vue的侦听器(watch):

<div id="app">
  {{ reversedMessage }}
</div>
var vm = new Vue({
  el: '#app',
  data: {
    message: '',
    reversedMessage: ''
  },
  watch: {
    message: function(val) {
      this.reversedMessage = val.split(' ').reverse().join(' ');
    }
  }
});

image-20210429082042315

这里我们手动在Console里设置了message的值,reversedMessage才能显示出来。

所以侦听属性必须需要 原属性发生变化 才能触发 对应的更新函数,而且代码相对于计算属性也显得更不直观。

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。(你可以通过查看官网侦听器的介绍来学习具体的例子)

计算属性的 setter

Vue中计算属性默认只有 getter属性,什么意思呢?

拿上面的 messagereversedMessage 的计算属性代码举例

computed: {
  reversedMessage: function() {
    return this.message.split(' ').reverse().join(' ');
  }
}

// 上面的代码等同于下面的
computed: {
  reversedMessage: {
    get: function() {
    	return this.message.split(' ').reverse().join(' ');
  	}
  }
}

reversedMessage 只可以通过 message的变化而变化,但如果我们想手动改变reversedMessage就做不到了,Vue会报错:

image-20210429084250925

但我们可以手动添加一个setter属性,例如下面的代码:

var vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello World'
  },
  computed: {
    reversedMessage: {
      get: function () {
        return this.message.split(' ').reverse().join(' ');
      },
      set: function (val) {
        this.message = val.split(' ').reverse().join(' ');
      }
    }
  }
});

image-20210429084535544

这样我们就实现了手动改变reversedMessage并且同时改变了message双向同步!

总结

本文介绍了以下几个方面:

  1. Vue 普通属性的用法
  2. 假设了一个翻转信息的需求
  3. 介绍了 在模版直接写表达式实现需求 及 存在的问题
  4. 介绍了 直接调用方法实现需求 及 存在的不足
  5. 介绍了 计算属性实现需求
  6. 介绍了 侦听器实现需求 及 与计算属性的对比
  7. 介绍了 计算属性默认只有getter,但可以自己设置setter

现在你可以把Vue强大的计算属性使用起来了!

Hi!

我是OSFPU,在这里我会写关于 计算机科学编程技术个人思考 相关的文章。 RSS

你可以发送邮件到 osfpu0@qq.com 来联系到我,也欢迎在微博关注我。

希望你能喜欢我的文章 🥰