vue.js之v-for循环中动态改变每个item的样式
1.需求
-
支持单击选中,再次单击取消选中
-
当未选中任何条件按钮时则自动选择全部
-
点击A则选中第一行全部,点击C代表选中第二行全部
-
选择全部时(默认选择全部),自动取消其他选择
-
2.思路
-
定义数据的结构,将产品分类,A,C,elseProduct
-
"全部"按钮,以及每个产品中应有是否选中的flag,以及点击事件
-
"A","C"按钮只需点击事件
-
最后产出的"条件"数据
data() {
return {
//产品 “全部”是否被选中
productSelected: true,
//产品集合
productMap: new Map(),
//A类产品
A: [
{
name: 'apple',
value: '苹果',
selected: false
},
{
name: 'banana',
value: '香蕉',
selected: false
},
{
name: 'orange',
value: '橘子',
selected: false
},
{
name: 'watermelon',
value: '西瓜',
selected: false
}],
//C类产品
C: [
{
name: 'milk',
value: '牛奶',
selected: false
},
{
name: 'Bread',
value: '面包',
selected: false
},
{
name: 'salt',
value: '盐',
selected: false
},
{
name: 'wheat',
value: '小麦',
selected: false
},
{
name: 'rice',
value: '大米',
selected: false
},
{
name: 'soy',
value: '酱油',
selected: false
}],
//其他类产品
elseProduct: [
{
name: 'else',
value: '其他',
selected: false
}],
}
3.实践
- 编写template
<template>
<div id="leftBar">
<div class="part">
<div>产品:</div>
<div style="width: 87%;">
<!--"全部"是否选择,选择则展示class -->
<button id="product" :class="this.productSelected?'productStyle':'item'" @click="selectProduct()">全部</button>
<button id="aProduct" class="productStyleHighLight" @click="selectAProducts()">A</button>
<button id="cProduct" class="productStyleHighLight" @click="selectCProducts()">C</button>
<br>
<input type="button" class="item" v-for="(aProduct,index) in A" :value="aProduct.value"
:key="aProduct.name" @click="selectAProduct(index)" :class="aProduct.selected?'productStyle':''">
<br>
<input type="button" class="item" v-for="(cProduct,index) in C" @click="selectCProduct(index)"
:value="cProduct.value" :key="cProduct.name" :class="cProduct.selected?'productStyle':''">
<br>
<input type="button" class="item" v-for="(eProduct,index) in elseProduct" @click="selectEProduct(index)"
:value="eProduct.value" :key="eProduct.name" :class="eProduct.selected?'productStyle':''">
</div>
</div>
</div>
</template>
- "全部"点击事件
- 点击全部,则取消其他所有按钮的选中状态
- 将所有产品放入productMap中
//点击全部产品
selectProduct: function () {
this.productSelected = true;
//取消产品的选中
this.A.forEach(function (r) {
r.selected = false;
});
this.C.forEach(function (c) {
c.selected = false;
});
this.elseProduct.forEach(function (e) {
e.selected = false;
});
//整合数据
this.mergeCondition();
}
- "A"以及"C"点击事件
- 将全部取消选中(注意是全部的按钮,不是"全部"这一个按钮"),并将A类产品全部选中
- 将productMap清空,并放入A类产品
//点击A
selectAProducts: function () {
this.productSelected = false;
//清理数据,包括productMap中的数据,以及将所有产品的选中状态取消
this.clearProductMap();
var productMap2 = this.productMap;
this.A.forEach(function (a) {
a.selected = true;
productMap2.set(a.name, a.value)
});
// this.productMap = productMap2;
//整合数据
this.mergeCondition();
},
//点击C
selectCProducts: function () {
this.productSelected = false;
//清理数据,包括productMap中的数据,以及将所有产品的选中状态取消
this.clearProductMap();
var productMap2 = this.productMap;
this.C.forEach(function (c) {
c.selected = true;
productMap2.set( c.name, c.value)
});
this.productMap = productMap2;
//整合数据
this.mergeCondition();
}
- A类,C类,elseProduct类的某个产品被点击时
- 若已被选中则取消,否则选中
//A类产品被点击时
selectAProduct: function (index) {
this.A[index].selected = !this.A[index].selected;
if (this.A[index].selected) {
//点击时,若刚开始是全部状态,则删除全部数据,只添加点击的那个
if (this.productSelected) {
this.productMap.clear();
}
this.productMap.set(this.A[index].name, this.A[index].value);
//有其他产品选中,取消"全部"的选中效果
this.productSelected = false;
} else {
this.productMap.delete(this.A[index].name);
}
//整合数据
this.mergeCondition();
},
//C类产品被点击时
selectCProduct: function (index) {
this.C[index].selected = !this.C[index].selected;
//若是选中状态
if (this.C[index].selected) {
//点击时,若刚开始是全部状态,则删除全部数据,只添加点击的那个
if (this.productSelected) {
this.productMap.clear();
}
this.productMap.set(this.C[index].name, this.C[index].value)
this.productSelected = false;
//全部的那一个按钮选中
} else {
this.productMap.delete(this.C[index].name);
}
//整合数据
this.mergeCondition();
},
//else类产品被点击时
selectEProduct: function (index) {
this.elseProduct[index].selected = !this.elseProduct[index].selected;
if (this.elseProduct[index].selected) {
//点击时,若刚开始是全部状态,则删除全部数据,只添加点击的那个
if (this.productSelected) {
this.productMap.clear();
}
this.productMap.set(this.elseProduct[index].name, this.elseProduct[index].value);
this.productSelected = false;
}
else {
// this.productSelected=false;
this.productMap.delete(this.elseProduct[index].name);
}
//整合数据
this.mergeCondition();
}
- clearProductMap 清除数据方法
//清除数据
clearProductMap: function () {
// if(this.productSelected){
//清空productMap数据
this.productMap.clear();
// }
//取消选中
this.A.forEach(function (r) {
r.selected = false;
});
this.C.forEach(function (c) {
c.selected = false;
});
this.elseProduct.forEach(function (e) {
e.selected = false;
});
}
- mergeCondition 整合数据方法
mergeCondition: function () {
//如果有的为空,则将“全部”置为true
if (this.productMap.size === 0) {
this.productSelected = true;
}
//防止不点击的时候没有数据
//如果"产品"被选中,则将所有产品放入map
if (this.productSelected) {
var productMap2 = this.productMap;
this.R.forEach(function (rProduct) {
productMap2.set(rProduct.name, rProduct.value)
});
this.C.forEach(function (cProduct) {
productMap2.set(cProduct.name, cProduct.value)
});
this.elseProduct.forEach(function (eProduct) {
productMap2.set(eProduct.name, eProduct.value);
});//否则就将在前面组装好的map发给后台
//发送请求
console.log(this.productMap)
}
4.总结
- 对于改变循环中每个item的样式,要会使用index,以及在相应的数据里加上class的flag