# 计算属性的概念

​ 计算属性也是属性(从 data 中的 A 属性得到一个计算属性 B 属性),角色相当于是 data 中属性,从视图的外观上来说两者一样。
​ 有时候某个属性是通过某种计算达到的,计算的过程可能很复杂,所以 vue 中可将这种属性放入到计算属性中。如同 methods 那样。
​ 计算属性也是属性,只不过与 data 里的属性不太一样,它是放在 computed 对象里的,该属性一般由函数执行得到,其函数返回值就是该属性的值。

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
new Vue({
el:"#app",
data:{
//data中的数据-是准备好了的可以直接使用的
//
a:'hello,vue'
},
methods:{
fun(){}
},
//第4个属性:
computed:{
//只获取,不设置
b:function(){
return 新的数据;
}
//以上也可以写成
b:{
get:function(){
return 新的数据
}
}
}
});
//完整版的计算属性的写法
new vue({
...
computed:{
//set和get都有
b:{
//get函数,默认
get(){
return 新的属性;
},
set(newVal){
//设置好后得到新的属性,可以影响其他数据
}
}
})

# 使用 computed 的必要性

首先从视图的外观上来说,是无法区别该数据属性来自于 data 还是 computed。

它的好处有 3 个:

1、计算属性定义在 computed 中,它不是方法,属性的值是函数的返回值;
2、把对处理数据的逻辑抽离在计算属性中,使得模板更加轻量易读;
3、计算属性的值会被缓存,并根据依赖的数据变化会重新计算。

# 计算属性的 set 和 get 模式

计算属性不但可以被动的接收别人的值,还可以设置这个值,并反作用于出去。

计算属性的完整写法:
1、取值
触发 get 函数,默认设置的函数。也就是只给计算属性一个函数,那么默认是该函数在取值时触发,也就是可称之为该函数为 getter 函数
2、赋值(设置值)
触发 set 函数

总结:

如果一个计算属性本身的值也可以更改,那么就不能设置一个函数了,而是要将其拆分为对象,里面一个为 get 函数,一个为 set 函数。get 即显示来自其他数据源的值,set 即点击自身时重新改变本身的值

# 计算属性实例

# 实例 1

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<title>todolist</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
background-color: #f5f5f5;
color: #444
}

a {
text-decoration: none;
color: #333;
}

#app {
width: 640px;
margin: 0 auto
}

#app h1 {
text-align: center;
font-size: 5em;
color: rgba(175, 47, 47, 0.15);
}

.todoapp {
min-height: 200px;
background: #fff;
margin: 30px 0 40px 0;
position: relative;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.1);
padding-bottom: 40px;
}

/*.todoapp:before{content: '';}*/
.header {
position: relative;
}

.new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.003);
box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
width: 100%;
font-size: 24px;
}

:focus {
outline: 0;
}

.toggle-all {
background: none;
position: absolute;
top: 19px;
left: -6px;
width: 60px;
height: 34px;
text-align: center;
border: none;
-webkit-appearance: none;
cursor: pointer;
}

.toggle-all:before {
content: '﹀';
font-size: 22px;
color: #333;
padding: 10px 27px 10px 27px;
}

.todolist li {
padding: 10px;
border-bottom: 1px solid #e6e6e6;
list-style: none;
}

.todolist li input,
.todolist li a {
display: inline-block;
width: 45px;
}

.todolist li input {
height: 25px;
vertical-align: -5px;
}

.todolist li a {
float: right;
display: none;
font-size: 20px
}

.todolist li:hover a {
color: #af5b5e;
display: block;
}

.todolist li span {
font-size: 1.5em;
}

.todolist li:last-child {
border-bottom: none;
}

.footer {
color: #777;
padding: 10px 15px;
height: 40px;
position: absolute;
width: 100%;
bottom: 0;
border-top: 1px solid #e6e6e6;
}

.footer:before {
content: '';
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 50px;
overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2);
}

.clear-completed {
float: right;
position: absolute;
right: 20px;
}

/*事项完成时*/
.completed {
color: #d9d9d9;
text-decoration: line-through;
}
.red{
color: #f00;
}
</style>
<script src="vue.v2.6.12.js"></script>
</head>

<body>
<!-- 外观参考了:http://todomvc.com/examples/vue/
代码By 罗永超 -->
<div id="app">
<h1>todolist</h1>
<section class="todoapp">
<header class="header">
<input autofocus="autofocus" autocomplete="off" placeholder="请在这里输入您的待办事项" v-model="text"
class="new-todo" @keyup.enter="add">
<input type="checkbox" class="toggle-all" v-model="checkall">
</header>
<ul class="todolist">
<li v-for="item,index in list">
<input type="checkbox" v-model="item.check">
<span :class="{completed:item.check==true}">{{item.content}}</span>
<a href="#" @click="del(index)">x</a>
</li>
</ul>
<footer class="footer">
<span class="todo-count"><strong :class="{red:todo>0}">{{todo}}</strong> 个未完成
</span>
<a class="clear-completed" href="#" @click="clear">
清除已完成
</a>
</footer>
</section>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
list: [],
text: ""//输入框文本
},
methods: {
add() {//回车新增待办
if(!this.text){return};//判断非空
this.list.unshift({check:false,content:this.text});//数组中添加对象
this.text = "";//输入框文本清空
},
del(index){//删除单个
this.list.splice(index,1);
},
clear(){//删除全部
this.list=this.list.filter(item=>item.check==false);
}
},
computed: {
checkall: {
get() {},
set(value) {
this.list.forEach(item=>{item.check=value});//全选绑定
}
},
todo(){
return this.list.filter(item=>item.check==false).length;//未完成计数
}
}
})
</script>
</body>

</html>

# 实例 2

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="vue.v2.6.12.js"></script>
<style>
.red{
color: red;
}
ul>li>input{
width: 80px;
text-align: center;
}
ul>li>strong{
display: inline-block;
min-width: 90px;
padding:0 5px;
}
ul>li>strong>span{
float: right;
padding-left: 5px;
font-weight: 400
}
</style>
</head>
<body>
<!-- HTML结构 -->
<div id="app">
<p>户外运动管理系统</p>
<ul>
<li v-for="item in data">
<input v-model="item.stock" min="0" type="number" @input="(item.stock<0||isNaN(item.stock))?item.stock=0:''">
<strong>{{item.name}}<span class="red" v-show="item.stock<=0">缺货</span></strong>
<button @click="(item.stock)++">add</button>
</li>
</ul>
<h4>总库存:<span>{{total}}</span></h4>
</div>
<script>
//数据解释
/*
{
//序号
id:1,
// 商品名称
name:"指南针",
//默认的库存
stock:10,
}
*/
var data=[
{
id:1,
name:"指南针",
stock:10,
},
{
id:2,
name:"夹克",
stock:10,
},
{
id:3,
name:"登山袜",
stock:10,
},
{
id:4,
name:"防晒霜",
stock:10,
},

];
let dataHandler={
get(){
return JSON.parse(localStorage.getItem("my"))|| [];
},
set(d){
localStorage.setItem("my",JSON.stringify(d));
}
};
if(!localStorage.getItem("my")){
// alert(8)
dataHandler.set(data);
}
// vue
let vm=new Vue({
el:"#app",
data:{
data:JSON.parse(localStorage.getItem("my")),
},
computed:{
total(){
let sum=0;//求和初始值
this.data.forEach(item => sum+=+item.stock);//累加
return sum;//返回总库存
}
},
watch:{
data:{
handler(){
dataHandler.set(this.data);
},
deep:true
}
}
});
</script>
</body>
</html>

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

tz 微信支付

微信支付

tz 支付宝

支付宝