學(xué)習(xí)vue,做一個(gè)小demo,第一步需求是點(diǎn)擊相應(yīng)的色塊會(huì)變色餐抢,再次點(diǎn)擊會(huì)還原。當(dāng)時(shí)思想是在 data 中用一個(gè)數(shù)組去記錄每個(gè)色塊的點(diǎn)擊狀態(tài)低匙,在組件上綁定該數(shù)組旷痕,從而動(dòng)態(tài)改變 class ,但是實(shí)際上 class 并沒(méi)有動(dòng)態(tài)改變努咐。
效果圖.png
代碼如下:
six-in-nine-vue.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="GBK">
<meta name="viewport" content="width=device-width,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
<title>six-in-nine-vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<link rel="stylesheet" href="./six-in-nine-vue.css">
</head>
<body>
<div class="wrap" id="js-wrap">
<div class="w-line" v-for="(line, line_idx) in num_list">
<div class="w-l-item"
:class="{'default-color': !clicked_list[line_idx * 3 + item_idx], 'clicked-color': clicked_list[line_idx * 3 + item_idx]}"
v-for="(item, item_idx) in line"
@click="clickBtn(line_idx * 3 + item_idx)">
<div class="item-wrap">
{{item}}
<!--{{ clicked_list[line_idx * 3 + item_idx] }}-->
</div>
</div>
</div>
</div>
</body>
</html>
<script src="six-in-nine-vue.js"></script>
six-in-nine-vue.css
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
.wrap {
padding: 5px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
height: 100%;
display: flex;
flex-direction: column;
}
.w-line {
flex-grow: 1;
background-color: #f6f6f6;
display: flex;
}
.w-l-item {
flex-grow: 1;
margin: 5px;
display: flex;
justify-content: center;
align-items: center;
}
.item-wrap {
color: #fff;
font-size: 50px;
}
.default-color {
background-color: #2db4f8;
}
.clicked-color {
background-color: #2771D4;
}
six-in-nine-vue.js
new Vue({
el: "#js-wrap",
data: {
num_list: [
["點(diǎn)我", "點(diǎn)我", "點(diǎn)我"],
["點(diǎn)我", "點(diǎn)我", "點(diǎn)我"],
["點(diǎn)我", "點(diǎn)我", "點(diǎn)我"]
],
clicked_list:[false,false,false,false,false,false,false,false,false]
},
methods: {
clickBtn: function (idx) {
this.clicked_list[idx] = !this.clicked_list[idx];
}
}
});
這里不能用數(shù)組的動(dòng)態(tài)綁定苦蒿,個(gè)人理解:數(shù)組 clicked_list[line_idx * 3 + item_idx]
這個(gè)實(shí)際上是一個(gè)指針,當(dāng)我們改變 data 中該數(shù)組的值時(shí)渗稍,指針指向并沒(méi)有改變佩迟,所以組件沒(méi)有更新組件狀態(tài)。有著這個(gè)思路竿屹,我將該數(shù)據(jù)改成了對(duì)象报强,這次成功了:
css修改.png
這里的完整 js 代碼:
six-in-nine-vue.js
new Vue({
el: "#js-wrap",
data: {
num_list: [
["點(diǎn)我", "點(diǎn)我", "點(diǎn)我"],
["點(diǎn)我", "點(diǎn)我", "點(diǎn)我"],
["點(diǎn)我", "點(diǎn)我", "點(diǎn)我"]
],
clicked_list: {
0: false,
1: false,
2: false,
3: false,
4: false,
5: false,
6: false,
7: false,
8: false
}
},
methods: {
clickBtn: function (idx) {
this.clicked_list[idx] = !this.clicked_list[idx];
}
}
});
這里是該 demo 的改進(jìn)(可以不看):
改進(jìn)點(diǎn):
- 原 demo 可復(fù)用性差,用了一個(gè)二維數(shù)組存儲(chǔ)數(shù)據(jù)拱燃,不符合實(shí)際情況(后端應(yīng)該通常只給一個(gè)一維數(shù)組);
- 原 demo 為了使用 flex 布局秉溉,將頁(yè)面進(jìn)行了雙重嵌套,結(jié)構(gòu)復(fù)雜;而且如果后端返回小于九個(gè)的元素召嘶,則布局改變父晶;
增加功能限制:限制最大點(diǎn)擊變色數(shù)為6個(gè)
因此加以改進(jìn):
six-in-nine-vue-batter.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="GBK">
<meta name="viewport" content="width=device-width,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
<title>six-in-nine-vue</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<link rel="stylesheet" href="six-in-nine-vue-better.css">
</head>
<body>
<div class="wrap" id="js-wrap">
<div class="w-item"
:class="[isClicked(item_idx) ? 'clicked-color' : 'default-color']"
v-for="(item, item_idx) in num_list"
@click="clickItem(item_idx)">
<div class="item-center">
{{item}}
</div>
</div>
</div>
</body>
</html>
<script src="six-in-nine-vue-batter.js"></script>
six-in-nine-vue-batter.css
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
.wrap {
box-sizing: border-box;
height: 100%;
}
.w-item{
margin-top: 10px;
margin-left: 10px;
width: calc((100% - (10px * 4)) / 3);
height: calc((100% - (10px * 4)) / 3);
float: left;
background-color: #3F89EC;
display: flex;
justify-content: center;
align-items: center;
}
.item-center{
font-size: 50px;
color: #fff;
}
.default-color{
background-color: #3F89EC;
}
.clicked-color{
background-color: #2771D4;
}
six-in-nine-vue-batter.js
new Vue({
el: "#js-wrap",
data: {
num_list: [0, 1, 2, 3, 4, 5, 6, 7],
clicked_list: [],
max_clicked: 6
},
methods: {
clickItem: function (idx) {
var c_clicked_list = this.clicked_list;
//如果點(diǎn)擊塊數(shù)大于或等于最大點(diǎn)擊塊數(shù) && 點(diǎn)擊的色塊未變色: 直接返回
if (c_clicked_list.length >= this.max_clicked && (c_clicked_list.indexOf(idx) == -1)){
return
}
var listIdx = c_clicked_list.indexOf(idx);
if (listIdx > -1) {
this.clicked_list.splice(listIdx, 1);
} else {
this.clicked_list.push(idx);
}
},
isClicked: function (idx) {
return this.clicked_list.indexOf(idx) + 1;
}
}
});
效果圖:
最終效果.png