Appearance
计算属性(computed)
什么是计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>vue</title>
</head>
<body>
<div id="app">
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello'
}
});
</script>
</div>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

这里的表达式包含3个操作,并不是很清晰,所以遇到复杂逻辑时应该使用Vue特带的计算属性computed来进行处理。
计算属性的用法
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>vue</title>
</head>
<body>
<div id="app">
<div id="example">
{{getMessage}}
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello'
},
computed: { // 放在computed中最后也会放在vm上,不能和methods与data重名
getMessage() {
return this.message.split('').reverse().join('')
}
}
});
</script>
</div>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
计算属性使用技巧
计算属性可以依赖其他计算属性 计算属性不仅可以依赖当前Vue 实例的数据,还可以依赖其他实例的数据
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>vue</title>
</head>
<body>
<div id="app1"></div>
<div id="app2">
{{getMessage}}
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
var vm= new Vue({
el: '#app1',
data: {
message: 'World'
}
});
var vm2 = new Vue({
el: '#app2',
data: {
message: 'Hello'
},
computed: {
getMessage() {
return `${this.message} ${vm.message}`
}
}
});
</script>
</div>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
getter和setter
每一个计算属性都包含一个getter 和一个setter ,我们上面的两个示例都是计算属性的默认用法, 只是利用了getter 来读取。 在你需要时,也可以提供一个setter 函数, 当手动修改计算属性的值就像修改一个普通数据那样时,就会触发setter 函数,执行一些自定义的操作
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>vue</title>
</head>
<body>
<div id="app">
<input type="text" v-model="getMessage"> <--模拟修改--!>
{{getMessage}}
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
var vm= new Vue({
el: '#app',
data: {
hi:'Hello',
message: 'World'
},
computed:{
getMessage:{ //get,set方法
// getter
get(){
return this.hi + ' ' + this.message
},
// setter
set(newValue){
console.log('====================================');
console.log(newValue);
console.log('====================================');
var names = newValue.split(' ');
this.hi = names[0];
this.message = names[names.length - 1];
}
}
}
});
</script>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
绝大多数情况下,我们只会用默认的getter 方法来读取一个计算属性,在业务中很少用到setter,所以在声明一个计算属性时,可以直接使用默认的写法,不必将getter 和setter 都声明。
质疑什么不直接用methods
通过上面的代码,可以看到使用计算属性,让界面变得更加的简洁。
使用计算属性还有一个好处:
其实细心的话就会发现,调用methods里的方法也能实现和计算属性一样的效果,既然使用methods就可以实现,那为什么还需要计算属性呢?原因就是计算属性是基于他的依赖缓存的(所依赖的还是data中的数据)。一个计算属性所依赖的数据发生变化时,他才会重新取值
也就是说:只要相关依赖没有改变,对此访问计算属性得到的是之前缓 存的结果,不会多次执行。
下面我们测试一下:
html
<p>
<!-- 总人数:{{users.length+"个"}} -->
总人数:{{total}} 总人数:{{total}}
</p>
1
2
3
4
2
3
4
在上面的代码中,我们使用total了两次。
下面在看一下关于计算属性中的代码修改:
javascript
computed: {
total() {
console.log("aaa");
// 计算属性是有缓存性:如果值没有发生变化,则页面不会重新渲染
return this.users.length + "个";
},
},
1
2
3
4
5
6
7
2
3
4
5
6
7
这里,我们通过console输出字符串aaa,但是在控制台上只是输出了一次,因为,第二次使用total的时候,发现值没有变化,所以直接从缓存中获取了对应的值。并没有重新进行计算,这样带来的好处就是,性能得到了提升。
下面,我们换成methods函数的形式来看一下:
html
<p>
<!-- 总人数:{{users.length+"个"}} -->
总人数:{{total}} 总人数:{{total}} 总人数:{{getTotal()}}
总人数:{{getTotal()}}
</p>
1
2
3
4
5
2
3
4
5
在上面的代码中,调用了两次getTotal方法。
getTotal方法的实现如下:
javascript
methods: {
getTotal: function () {
console.log("methods");
return this.users.length + "个";
},
},
1
2
3
4
5
6
2
3
4
5
6
实现的方式是差不多的,但是这里却执行了两次。(注意:由于本案例中给每一个li标签添加了*@mousemove*,所以只要鼠标移动到列表上,就会导致页面重新渲染,这时会不断的调用getTotal方法。)
所以通过上面案例的演示,可以明确的看出计算属性是有缓存的,也就是所依赖的data属性中的数据没有变化,那么是不会重新计算的。所以提升了对应的性能。
所以说,在进行大量耗时计算的时候,建议使用计算属性来完成。
如下代码:
javascript
data: {
selectItem: "",
num: 100
}
1
2
3
4
2
3
4
在data中定义了num 属性,并且初始值为100、
下面在计算属性中进行求和的运算,代码实现如下:
javascript
computed: {
total() {
console.log("aaa");
// 计算属性是有缓存性:如果值没有发生变化,则页面不会重新渲染
// return this.users.length + "个";
let count = 0;
for (let i = 0; i <= this.num; i++) {
count += i;
}
return count;
},
},
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
通过演示,可以发现计算属性只是在第一次调用的时候,执行了一次,后续由于所依赖的数据num没有发生变化,所以即时调用多次,也并没有重新进行计算,而是获取上次计算的结果,所以说在进行大量耗时计算的时候,通过计算属性可以提升性能。