1.实现效果:
点击将属性转为红色,无库存的商品置灰,可点击的背景为白色;且点中的属性点击之后会恢复白色;
-
重要思路:
假如: 颜色:黑色,大红色,米白色,军绿色
尺寸:XL,L,M
纯度: 90% 60% 70%
第一种情况:如果是直接所有的属性都点击选完了,那么我们可以直接组合成 黑色-M-70% 的字段直接去匹配具体的商品。
第二种情况:在属性不完全的时候,该怎么判断属性是否可被选中???
(1)声明一个匹配数组PK用来保存选中的属性[],例如pk=[颜色:黑色,尺寸:无,纯度:无],---颜色为属性,黑色为属性值。
现在开始遍历所有的属性,来显示其对应的状态:
-----只选中一个属性--黑色-----------
黑色(属性:颜色):取出含黑色的商品组,商品组有值---->和pk中属性不同的值匹配(没有匹配的,黑色可选);
xl(属性:尺寸):取出含有xl的商品组k1---->和pk中属性不同的值匹配(匹配黑色,检测k1中含黑色的商品组成新的商品组k2,如果k2无值不可选,k2有值可选);
---选中了两个属性----黑色 M----
大红色:取出含有大红色商品组k1---->和pk中属性不同的值匹配(匹配M--在k1中找出含有M的商品组成新数组k2,如果k2有值,可选,k2无值不可选);
90%:取出含有90%的商品组k1---->和pk中属性不同的值匹配(匹配黑色在k1中找出含有黑色的商品形成新数组k2,如果k2无值不可选,k2有值,继续在k2中找出含有M的商品形成新数组k3,如果k3中有值可选,没值不可选);
复制代码
3.简要代码 主要技术框架:Vue
(1)应用于显示在页面上的数组:
value:将存放页面中对应选择的值;show=0:初始状态,可选;show=1:选中状态;show=2:不可选状态;
` this.allattr=[
{
"name": "颜色",
"value": null,
"son": [
{
"paramvalue": "黑色",
"show": 0
},
{
"paramvalue": "大红色",
"show": 0
},
{
"paramvalue": "米白色",
"show": 0
},
{
"paramvalue": "军绿色",
"show": 0
}
]
},
{
"name": "尺寸",
"value": null,
"son": [
{
"paramvalue": "XL",
"show": 0
},
{
"paramvalue": "L",
"show": 0
},
{
"paramvalue": "M",
"show": 0
}
]
},
{
"name": "毛料纯度",
"value": null,
"son": [
{
"paramvalue": "90%纯度",
"show": 0
},
{
"paramvalue": "60%纯度",
"show": 0
},
{
"paramvalue": "70%纯度",
"show": 0
}
]
}
]`
复制代码
商品集合:
this.shopattr= [
{
"pdid": 1625,
"productAttrList": [
{
"attribute": "颜色",
"value": "米白色",
},
{
"attribute": "尺寸",
"value": "L",
},
{
"attribute": "毛料纯度",
"value": "90%纯度",
}
],
"attrStr": "颜色: 米白色;尺寸: L;毛料纯度: 90%纯度;"
},
{
"pdid": 1625,
"productAttrList": [
{
"attribute": "颜色",
"value": "黑色",
},
{
"attribute": "尺寸",
"value": "M",
},
{
"attribute": "毛料纯度",
"value": "70%纯度",
}
],
"attrStr": "颜色: 黑色;尺寸: M;毛料纯度: 70%纯度;"
},
{
"pdid": 1625,
"productAttrList": [
{
"attribute": "颜色",
"value": "大红色",
},
{
"attribute": "尺寸",
"value": "XL",
},
{
"attribute": "毛料纯度",
"value": "70%纯度",
}
],
"attrStr": "颜色: 大红色;尺寸: XL;毛料纯度: 70%纯度;"
}
],
复制代码
3.html代码:
<li v-for="(items,index) in allattr" :key="index">
<span>{{items.name}}</span>
<div>
<ul class="attrUI">
<li v-for="(item,sonIndex) in items.son" :key="sonIndex" @click="clickattr(item.paramvalue,index,sonIndex)"
v-bind:class='item.show === 1 ? "checkedLi": item.show === 2 ? "disableLi":"normalLi"'>{{item.paramvalue}}</li>
</ul>
</div>
</li>
复制代码
4.点击事件代码:
// 点击某一个属性
clickattr: function (attrvalue,index,i) {
//0 初始状态 1选中状态 2 不可点击状态
let item = "";
item = this.allattr;
// //样式的改变+加放入值
if ((item[index].son)[i].show !== 2) {
if ((item[index].son)[i].show === 1) {
item[index].value = null;
(item[index].son)[i].show = 0;
} else {
item[index].value = attrvalue;
for (let gg = 0; gg < item[index].son.length; gg++) {
if ((item[index].son)[gg].paramvalue === attrvalue) {
(item[index].son)[gg].show = 1;
} else {
(item[index].son)[gg].show = 0;
}
}
}
//一一遍历。取出每一个属性,获取含有具体属性的数组
for (let a = 0; a < item.length; a++) {
let matchattr = "";
for (let b = 0; b < item[a].son.length; b++) {
if ((item[a].son)[b].show != 1) {
//取出了值,然后进行遍历
let matchGroup = [];//完成的商品列表数组
let sonGroup = [];//含有具体属性的数组
matchGroup = this.shopattr;
matchattr = item[a].name + ":" + (item[a].son)[b].paramvalue + ";";
//得到含有该属性的商品集合
for (let k = 0; k < matchGroup.length; k++) {
if (matchGroup[k].attrStr.indexOf(matchattr) != -1) {
sonGroup.push(matchGroup[k])
}
}
//遍历是否该商品集合中,含有点击事件的集合,有则该属性可选;
let judgeShow = "", start = 0;//judgeShow 通过该值来控制属性的状态; start;是否等于item的长度来判断是都遍历完成
judgeShow = sonGroup;
for (let c = 0; c < item.length; c++) {
let sonmatch = "";
if (item[c].value == null) {
sonmatch = item[c].name + ":";
} else {
sonmatch = item[c].name + ":" + item[c].value + ";";
}
judgeShow = this.checkStr(judgeShow, sonmatch, item[c].name, item[a].name);//判断字符串是否可选的递归方法
if (judgeShow == false) {
(item[a].son)[b].show = 2;
break;
}else{
start++;
}
}
//遍历完成,则该属性可选
if (start == item.length) {
(item[a].son)[b].show = 0;
}
}
}
}
this.allattr = item;
}
//放置点击的属性以后。判断一下是否三个属性全部选择完成
let clicknum = 0;
for (let h = 0; h < item.length; h++) {
if (item[h].value != null) {
clicknum++;
}
}
if (clicknum == item.length) {
let son = "";
for (var i = 0; i < item.length; i++) {
son = son + item[i].name + ":" + item[i].value + ";";
}
// 用得到的son 去查找总的商品列表获取商品的信息
for (var j = 0; j < this.shopattr.length; j++) {
if (son === this.shopattr[j].attrStr) {
this.pdid = this.shopattr[j].pdid;
break;
}
}
}else{
this.pdid = "";
}
},
// //查看该属性是否匹配成功
// 用于循环属性是否成功
checkStr:function(sonGroup,sonmatch,matchname,getname){
if(matchname==getname){
return sonGroup;//如果遍历的属性,和所遍历对象同一个父属性:例如颜色;则默认递归返回
}else{
//遍历是否该商品集合中,含有点击事件的集合,有则该属性可选;
let myGroup=[],haveGroup=[];
myGroup=sonGroup;
let num=0;
for(let w=0;w<myGroup.length;w++){
if(myGroup[w].attrStr.indexOf(sonmatch)!=-1 ){
haveGroup.push(myGroup[w]);
}else{
num++;
}
}
if(num==myGroup.length){
return false;
}else{
return haveGroup;
}
}
},
复制代码