技术点
vue.js实现v-for生成元素和v-on:click点击为元素添加样式
vue.js中v-for和v-on:click使用初探
实现一组元素中单个元素class变换
在影院详情页面cinema-detail-page中,先遍历生成该影院下属影片列表的所有影片。
将海报图展示如下:
我们需要的响应动作是,点击一个电影海报,将对应div标签的class添加active项,以便用户由对应元素的动态变化确认自己选中了对应电影。
将结果图展示如下:
实现方式:
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
<div class="movie" v-for="(movie_img, index) in cinema.online_moive" v-if="notSameFilm(originalFilm.img,movie_img) && index < 6" :key="index" :data-index="index" :class="{'active': isActive==index}" v-on:click="clickMovie(index)">
<img :src="movie_img" alt="movie_img" />
</div>
<script>
export default {
data() {
return {
isActive: -1,
}
},
methods: {
clickMovie: function(index) {
if (this.isActive != index) {
this.isActive = index;
}
}
}
}
<style>
.movie {
width: 162px;
height: 227px;
border: 4px solid #fff;
box-shadow: 0 1px 3px 0 hsla(0, 0%, 66%, .5);
display: inline-block;
transform-origin: 50%;
transform: scale(.82);
transition: transform, .1s, -webkit-transform .1s;
word-spacing: 0;
white-space: nowrap;
}
.movie img {
width: 100%;
height: 100%;
}
.movie.active {
transform: scale(1);
border-color: #2A5CAA;
}
</style>
实现一组元素中多个元素class变换(各自独立点击触发)
在选座页面chooseSeats中,我们需要点击选择座位并激活相应样式对应的class。
将座位图展示如下:
将结果图展示如下:
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
<div class="seats-wrapper">
<div id="seatWrap">
<div class="seat" v-for="(n,index) in clickList" :key="index" :class="getSeatState(index)" v-on:click="handler(index)">
</div>
</div>
</div>
<script>
</script>
export default {
data() {
return {
clickIndex: 0,
ticketPrice: 28,
totalPrice: 0,
clickList:[
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 2, 2, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
],
seatNum: 0,
isTicketActive: false
}
},
methods: {
handler: function(index) {
if (this.clickList[index] == 0) {
if (this.seatNum < 4) {
this.$set(this.clickList,index,1);
this.seatNum++;
this.isTicketActive = true;
} else {
alert("最多选4个座位!")
}
} else if (this.clickList[index] == 1) {
this.$set(this.clickList,index,0);
this.seatNum--;
if (this.seatNum == 0) {
this.isTicketActive = false;
}
}
this.totalPrice = this.ticketPrice * this.seatNum;
},
getSeatState: function(index) {
if (this.clickList[index] == 0) {
return "seat";
} else if (this.clickList[index] == 1) {
return "seatChoosed";
} else if (this.clickList[index] == 2) {
return "seatSold";
}
}
}
<style>
#seatWrap {
width:440px;
margin:auto;
background:#ccc;
}
.seat, .seatSold, .seatChoosed{
cursor: pointer;
width:23px;
height:19px;
margin:3px 14px 14px 14px;
float:left;
text-align:center;
color:#fff;
}
.seat {
background-image: url("../../assets/img/chooseSeats/selectable_seat.gif");
background-repeat: no-repeat;
}
.seatChoosed {
background-image: url("../../assets/img/chooseSeats/selected_seat.gif");
background-repeat: no-repeat;
}
.seatSold {
background-image: url("../../assets/img/chooseSeats/sold_seat.gif");
background-repeat: no-repeat;
}
</style>
列表渲染注意事项
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
- 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:vm.items.length = newLength
举个例子:
1
2
3
4
5
6
7
8
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:
1
2
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
1
2
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:
1
vm.$set(vm.items, indexOfItem, newValue)
为了解决第二类问题,可以使用 splice:
1
vm.items.splice(newLength)
另外:检测变化的注意事项
受现代 JavaScript 的限制,Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。例如:
1
2
3
4
5
6
7
8
9
10
11
var vm = new Vue({
data:{
a:1
}
})
// `vm.a` 是响应的
vm.b = 2
// `vm.b` 是非响应的
Vue 不允许在已经创建的实例上动态添加新的根级响应式属性 (root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上:
1
Vue.set(vm.someObject, 'b', 2)
还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:
1
this.$set(this.someObject,'b',2)