建议熟读此翻译文章,能够更好理解vue的相应属性原理: vue的响应式原理 (opens new window)
# 实践:
开发中经常会遇到多选、单选等功能,例如购物车、选择商品规格等地方。
实现上述功能最常规的做法是给数组中的每个对象添加一个属性值来作为是否选中的判断,而该属性仅客户端使用,所以服务端返回的数据中是没有这个字段的,在此要实现多选、单选功能有两种做法:
- 在数据赋值到data之前处理好数据,这样可直接使用vue的相应原理来工作:
<template>
<ul>
<li v-for="(shop,index) in shopCarts">
<i @click='at(shop, index)' class="rt" :class="{ lf: shop.checked}"></i>
<h3 class="clamp">{{shop.goodsName}}</h3>
</li>
</ul>
</template>
<script>
import { mapActions } from 'vuex'
export default{
data(){
return {
shopCarts:[]
}
},
created () {
var self = this;
this.getCart().then(function(res){
var shopCarts = res.data.shopCarts;
shopCarts.forEach(function(item){
item.checked = false;
});
self.shopCarts = shopCarts;
});
},
methods:{
...mapActions([
'getCart'
]),
at(item, index){
this.shopCarts[index].checked = !item.checked;
}
}
}
</script>
<style scoped>
.rt{
background-image:url(../../libs/img/rt.png);
}
.lf{
background-image:url(../../libs/img/lf.png);
}
</style>
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
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
- 不需处理数据,在点击的时候使用 Vue.nextTick(callback) 。回调函数在 DOM 更新完成后就会调用$set方法,可同样实现:
<template>
<ul>
<li v-for="(shop,index) in shopCarts">
<i @click='at(shop, index)' class="rt" :class="{ lf: shop.checked}"></i>
<h3 class="clamp">{{shop.goodsName}}</h3>
</li>
</ul>
</template>
<script>
import { mapActions } from 'vuex'
export default{
data(){
return {
shopCarts:[]
}
},
created () {
var self = this;
this.getCart().then(function(res){
self.shopCarts = res.data.shopCarts;
});
},
methods:{
...mapActions([
'getCart'
]),
at(item, index){
var that = this;
this.$nextTick(function () {
that.$set(item,'checked',!item.checked);
});
}
}
}
</script>
<style scoped>
.rt{
background-image:url(../../libs/img/rt.png);
}
.lf{
background-image:url(../../libs/img/lf.png);
}
</style>
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
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