首页 技术 正文
技术 2022年11月10日
0 收藏 745 点赞 4,152 浏览 6364 个字

由于公司开发了一个电商项目,涉及到前台商品属性的展示,所以百度上找了一下!找到了 周琪力写的一个算法例子,因为作者只有jQuery 实现demo, 自己仿照 demo 实现了一个 vue 的!

周琪力原文: http://mp.weixin.qq.com/s?__biz=MzIwNjQwMzUwMQ==&mid=2247484853&idx=1&sn=bed59c1d83c3aeb4bf7881be8dbdd917&chksm=97236777a054ee61fc3cef07eb4b164fa28e26917ce0a409d876964ad3c2ee3f90a000e29beb#rd

原文的demo实现:http://codepen.io/keelii/pen/RoOzgb

效果图: 
前端如何展示商品属性:SKU多维属性状态判断算法的应用-Vue 实现

附上代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue 实现商品属性的计算显示</title>
<style>
body {
font-size: 12px;
}
dt {
width: 100px;
text-align: right;
}
dl {
clear: both;
overflow:hidden;
}
dl.hl {
background:#ddd;
}
dt, dd {
float:left;
height: 40px;
line-height: 40px;
margin-left: 10px;
}
button {
font-size: 14px;
font-weight: bold;
width: 100px;
height: 30px;
margin: 0 10px;
} .disabled {
color:#999;
border: 1px dashed #666;
}
.active {
color: red;
} .top-but {
margin: 10px;
} #skuId {
height: 24px;
font-size: 14px;
line-height: 24px;
}
</style>
</head>
<body>
<textarea id="values" style="width:600px;height:100px">
[
{ "颜色": "红", "尺码": "大", "型号": "A", "skuId": "3158055" },
{ "颜色": "白", "尺码": "大", "型号": "A", "skuId": "3158054" },
{ "颜色": "白", "尺码": "中", "型号": "B", "skuId": "3133859" },
{ "颜色": "蓝", "尺码": "小", "型号": "C", "skuId": "3516833" }
]
</textarea>
<div id="app">
<label>
默认选中 :
<input type="text" name="skuId" id="skuId" v-bind:value="skuId">
</label>
<button @click="getTextareaData" class="top-but"> 重新加载数据 </button> 当前属性ID:{{ skuId }}
<dl v-for="item, key in list.result" class="content" v-bind:class="{hl: highKeys[key]}">
<dt> {{key}} : </dt>
<dd>
<button
class="item"
v-for="value in item"
@click="handleActive(key, value)"
v-bind:class="{active: value.active, disabled: !value.active && value.disabled}"
> {{ value.name }} </button>
</dd>
</dl>
已经选择:{{ message }}
</div>
</body>
<script src="https://unpkg.com/vue "></script>
<script>
let vue = new Vue({
el: "#app",
data(){
return {
data: [],
skuId: "",
skuName: "skuId",
// 属性名称信息
keys: [],
// 数据集合{list.result list.items}
list: {},
// 分隔符
spliter: '\u2299',
result: {},
message: "",
highKeys: {},
};
},
methods: {
powerset(arr) {
let ps = [[]];
for (let i = 0; i < arr.length; i++) {
for (let j = 0, len = ps.length; j < len; j++) {
ps.push(ps[j].concat(arr[i]));
}
} return ps;
}, /**
* 初始化数据
* @return
*/
initData() {
this.result = {};
this.keys = this.getAllKeys();
for (let i = 0; i < this.keys.length; i ++) {
this.highKeys[this.keys[i]] = false;
} this.list = this.combineAttr(this.data, this.keys);
this.initSeleted(this.skuId);
this.buildResult(this.list.items)
this.updateStatus(this.getSelectedItem());
this.showResult();
}, /**
* 获取输入表单中的数据进行初始化
* @return
*/
getTextareaData() {
let data = document.getElementById('values').value;
let skuId = document.getElementById("skuId").value; try {
this.data = JSON.parse(data);
let isHas = false;
for (let i = 0; i < this.data.length; i ++) {
if (skuId == this.data[i][this.skuName]) {
isHas = true;
break
}
} this.skuId = isHas ? skuId : this.data[0][this.skuName];
this.initData();
} catch (e) {
this.data = [];
}
}, /**
* 正常属性点击
*/
handleNormalClick(key, value) {
for (let i in this.list.result[key]) {
if (i != value.name) {
this.list.result[key][i].active = false;
} else {
this.list.result[key][i].active = true;
}
}
}, /**
* 无效属性点击
*/
handleDisableClick(key, value) {
this.list.result[key][value.name]["disabled"] = false;
// 清空高亮行的已选属性状态(因为更新的时候默认会跳过已选状态)
for (let i in this.list.result) {
if (i != key) {
for (let x in this.list.result[i]) {
this.list.result[i][x].active = false;
}
}
} this.updateStatus(this.getSelectedItem());
}, /**
* 高亮行
*/
highAttributes: function() {
for (let key in this.list.result) {
this.highKeys[key] = true;
for (let attr in this.list.result[key]) {
if (this.list.result[key][attr].active === true) {
this.highKeys[key] = false;
break;
}
}
}
}, /**
* 点击事件处理
* @param key 点击的行
* @param value 点击的按钮的数据
*/
handleActive: function(key, value) {
if (value.active == true) {
return false;
} this.handleNormalClick(key, value);
if (value.disabled === true) {
this.handleDisableClick(key, value);
} this.updateStatus(this.getSelectedItem());
this.highAttributes();
this.showResult();
}, /**
* 计算属性
* @param {[type]} data [description]
* @param {[type]} keys [description]
* @return {[type]} [description]
*/
combineAttr(data, keys) {
let allKeys = []
let result = {} for (let i = 0; i < data.length; i++) {
let item = data[i]
let values = [] for (let j = 0; j < keys.length; j++) {
let key = keys[j]
if (!result[key]) {
result[key] = {};
} if (!result[key][item[key]]) {
result[key][item[key]] = {"name": item[key], "active": false, "disabled": true};
} values.push(item[key]);
} allKeys.push({
path: values.join(this.spliter),
sku: item['skuId']
});
} return {
result: result,
items: allKeys
}
}, /**
* 获取所有属性
* @return {[type]} [description]
*/
getAllKeys() {
let arrKeys = [];
for (let attribute in this.data[0]) {
if (!this.data[0].hasOwnProperty(attribute)) {
continue;
} if (attribute !== this.skuName) {
arrKeys.push(attribute);
}
} return arrKeys;
}, getAttruites(arr) {
let result = []
for (let i = 0; i < arr.length; i++) {
result.push(arr[i].path)
} return result
}, /**
* 生成所有子集是否可选、库存状态 map
*/
buildResult(items) {
let allKeys = this.getAttruites(items) for (let i = 0; i < allKeys.length; i++) {
let curr = allKeys[i];
let sku = items[i].sku;
let values = curr.split(this.spliter);
let allSets = this.powerset(values); // 每个组合的子集
for (let j = 0; j < allSets.length; j++) {
let set = allSets[j]
let key = set.join(this.spliter) if (this.result[key]) {
this.result[key].skus.push(sku)
} else {
this.result[key] = {
skus: [sku]
}
}
}
}
}, /**
* 获取选中的信息
* @return Array
*/
getSelectedItem() {
let result = [];
for (let attr in this.list.result) {
let attributeName = '';
for (let attribute in this.list.result[attr]) {
if (this.list.result[attr][attribute].active === true) {
attributeName = attribute;
}
} result.push(attributeName);
} return result
}, /**
* 更新所有属性状态
*/
updateStatus(selected) {
for (let i = 0; i < this.keys.length; i++) {
let key = this.keys[i],
data = this.list.result[key],
hasActive = !!selected[i],
copy = selected.slice(); for (let j in data) {
let item = data[j]["name"];
if (selected[i] == item) {
continue
} copy[i] = item
let curr = this.trimSpliter(copy.join(this.spliter), this.spliter);
this.list.result[key][j]["disabled"] = this.result[curr] ? false : true;
}
}
}, trimSpliter(str, spliter) {
// ⊙abc⊙ => abc
// ⊙a⊙⊙b⊙c⊙ => a⊙b⊙c
let reLeft = new RegExp('^' + spliter + '+', 'g');
let reRight = new RegExp(spliter + '+$', 'g');
let reSpliter = new RegExp(spliter + '+', 'g');
return str.replace(reLeft, '')
.replace(reRight, '')
.replace(reSpliter, spliter)
}, /**
* 初始化选中
* @param mixed|Int|String skuId 需要选中的skuId
* @return {[type]} [description]
*/
initSeleted(skuId) {
for (let i in this.data) {
if (this.data[i][this.skuName] == skuId) {
for (let x in this.data[i]) {
if (x !== this.skuName) {
this.list.result[x][this.data[i][x]].active = true;
}
}
break;
}
}
}, /**
* 显示选中的信息
* @return
*/
showResult() {
let result = this.getSelectedItem()
let s = []
for (let i = 0; i < result.length; i++) {
let item = result[i];
if (!!item) {
s.push(item)
}
} if (s.length == this.keys.length) {
let curr = this.result[s.join(this.spliter)]
if (curr) {
s = s.concat(curr.skus)
this.skuId = curr.skus[0];
} this.message = s.join('\u3000-\u3000');
}
}
}, created() {
this.getTextareaData();
}
})
</script>
</html>
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,494
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,495
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,133
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,297