计算属性
3.1 什么是计算属性
在双方绑定过程中如果有过长的数据、表达式或者复杂逻辑业务时,应将所有的计算属性都以函数的形式写在Vue实例的computed选项内,最终返回计算后的结果。举例:
改写前:
<div>{{text.split(',').reverse().join(',')}}</div>
改写后:
<div id="app">
{{reverseText}}
</div>
<script>
var app = new Vue({
el:'#app',
data:{
text:'123,456',
},
computed:{
reverseText:function(){
return this.text.split(',').reverse().join(',');
}
}
})
</script>
3.2 计算属性用法
每个计算属性都包含一个getter和一个setter,getter用来读取数据,setter函数可以在手动修改计算属性时触发,执行一些自定义操作,例如:
<div id="app">
姓名:{{fullName}}
</div>
<script>
var app = new Vue({
el:'#app',
data:{
firstName:'Jack',
lastName:'Green',
},
computed:{
fullName:function(){
//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];
}
}
}
})
</script>
当执行app.fullName = ‘piao piao’时,setter就会被触发。在大多数情况下,我们只会用到默认的getter函数,所以在声明计算属性时,不需要将setter和getter函数都声明。
计算属性有两个使用技巧可以关注,一是计算属性可以依赖其他计算属性;二是计算属性不仅可以依赖当前Vue实例的数据,还可以依赖另一个Vue实例的数据,当其中一个实例的属性值发生变化时,另一个属性会随之变化。
3.3 计算属性缓存
上述的计算属性在methods里定义方法同样也可以实现,那么methods和computed的区别是什么呢?
原因是计算属性时基于它的依赖缓存的。一个计算属性的数据发生变化时,它才会重新取值,所以只要实例中的text值不改变,计算属性也不会更新。例如:
computed:{
now:function(){
return Date.now();
}
}
这里的Date.now()不是响应式依赖,所以计算属性now不会更新。但是methods只要重新渲染就会被调用,函数就会被执行。
使用计算属性还是methods取决于是否需要缓存,当遍历大数组和大量计算时,使用计算属性,除非你不需要缓存。
补充部分
1、computed中的计算属性可以获取通过this获取data中的变量进行计算并返回结果,页面上可直接使用该计算属性值。
2、Vue中计算属性是基于它们的依赖进行缓存的,而方法是不会基于它们的依赖进行缓存的。从而使用计算属性要比方法性能更好。
3、在Vue中使用异步计算属性
Vue中的计算属性非常好。它们允许你执行复杂的操作或数据格式,同时最大限度地执行依赖项计算的性能,只在依赖更改时更新视图。但遗憾的是,它们完全是同步的。值得庆幸的是,有一个插件。使用vue-async-computed包可以通地将一个promise的值绑定到组件属性来创建和使用组件中的异步计算属性。
我们可以在项目的根目录下通过yarn或npm来安装vue-async-computed插件:
# Yarn
$ yarn add vue-async-computed
# NPM
$ npm i vue-async-computed --save
接下来在你的项目中开启这个插件:
// main.js
import Vue from 'vue';
import AsyncComputed from 'vue-async-computed'
import App from 'App.vue';
Vue.use(AsyncComputed);
new Vue({
el: '#app',
render: h => h(App)
});
如果你和我一样,对Vue的构建工具不是很熟悉的话,我建议你使用Vue官方提供的构建工具 Vue CLI。默认情况,它提供了五种模板,你可以根据自己喜欢的方式选择自己需要的模板即可。确认在项目中引用vue-async-computed之后,咱们就可以开始使用这个插件了。使用如何使用这个插件之前,先来简单的了解一些概念。
在Vue中标准计算属性和异步属性之间有一些区别:
异步属性不能有setter
直到promise的resolve为止,除非default被设置,否则该值为null。在大多数情况下,你可以将它们视为返回promise的计算属性。
<!-- MyComponent.vue -->
<template>
<!-- 在一两秒后 myResolvedValue将变成"*Fancy* Resolved Value" -->
<h2>Asynchronous Property {{ myResolvedValue }}</h2>
</template>
<script>
export default {
asyncComputed: {
myResolvedValue () {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('*Fancy* Resolved Value!'), 1000)
})
}
}
}
</script>
使用ES7 / ES2016的async / await,这将变得更简单:
<!-- MyComponent.vue -->
<template>
<!-- 在一两秒后 myResolvedValue将变成"*Fancy* Resolved Value" -->
<h2>Asynchronous Property {{ myResolvedValue }}</h2>
</template>
<script>
function fancinessComesLater () {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('*Fancy* Resolved Value!'), 1000)
})
}
export default {
asyncComputed: {
async myResolvedValue() {
return await fancinessComesLater()
}
}
}
</script>
4、侦听器(Watch)
使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
参考资料:
- https://cn.vuejs.org/v2/guide/computed.html
- https://www.w3cplus.com/vue/vue-computed-intro.html
- http://www.cnblogs.com/gunelark/p/8492468.html