```
<!DOCTYPE html>
<html lang="zh-CN" ng-strict-di>
<meta charset="utf-8" />
<meta name="renderer" content="webkit" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<meta name="X-Context-Path" content="" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<head>
<meta charset="utf-8" />
<title>
商品规格sku
</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
</head>
<body>
<style>
.goods-spec {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.goods-spec .goods-spec-add {
margin-right: 15px;
}
.goods-container .button-new-tag {
height: 32px;
line-height: 30px;
padding-top: 0;
padding-bottom: 0;
}
.goods-container .input-new-tag {
width: 90px;
margin-right: 10px;
vertical-align: bottom;
}
.goods-container .el-tag {
margin-right: 10px;
}
.goods-container .goods-content {
margin-bottom: 10px;
padding: 14px;
border: 1px solid #ebeef5;
border-radius: 4px;
background-color: #fcfcfc;
}
.goods-content .goods-content-box {
display: flex;
align-items: center;
}
.goods-content-box .goods-content-left {
flex: 1;
}
</style>
<div id="app">
<div style="padding:60px;">
<div class="goods-spec">
<span>商品规格</span>
<el-link type="primary" @click="addPrivateSpec" class="goods-spec-add">添加规格</el-link>
</div>
<div class="goods-spec">
<el-checkbox-group v-model="checkList" >
<div style="height: 30px;">
<el-checkbox v-for="(item,index) in attrN" @change="nv(item,index)" :key="index" :label="item"></el-checkbox>
</div>
<el-checkbox-group v-model="checkList1" v-for="(item,index) in attrV">
<div style="height: 30px;">
<el-checkbox v-show="attrft.includes(index)" @change="nvtwo(item,item1,index,index1)" v-for="(item1,index1) in item" :key="index1" :label="item1"></el-checkbox>
</div>
</el-checkbox-group>
</el-checkbox-group>
</div>
<div class="goods-spec">
</div>
<div class="goods-container" v-for="(attr, index) in privateGoodsItem" :key="index">
<div class="goods-content">
<div class="goods-content-box">
<div class="goods-content-left">
<el-form label-width="80px" style="width:400px">
<el-form-item label="规格名">
<el-input v-model="attr.goods_spec_spectitle" placeholder="请输入规格名"></el-input>
</el-form-item>
<el-form-item label="规格值">
<el-tag v-for="tag in attr.spec" :key="tag.goods_spec_info_title" closable :disable-transitions="false" @close="handleClose(tag, attr)">
{{ tag.goods_spec_info_title }}
</el-tag>
<el-input
class="input-new-tag"
v-if="attr.inputVisible"
v-model="attr.inputValue"
:ref="`saveTagInput${index}`"
size="small"
@keyup.enter.native="handleInputConfirm(attr.inputValue, attr)"
@blur="handleInputConfirm(attr.inputValue, attr)"
>
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput(attr, index)">+ 添加</el-button>
</el-form-item>
</el-form>
</div>
<div class="goods-content-right">
<el-link type="danger" @click="delPrivateSpec(index)">删除规格</el-link>
</div>
</div>
</div>
</div>
<p style="margin:24px 0 10px 0">价格 / 库存</p>
<el-table ref="multipleTable" :data="tableColumnList.tableBodyList" stripe tooltip-effect="dark" style="width: 100%;margin-top:1%;">
<el-table-column :label="item.propName" :property="item.prop" v-for="item in tableColumnList.tableHeaderList" :key="item.prop" align="center">
<template slot-scope="scope">
<span>{{ scope.row[scope.column.property].goods_spec_info_title }}</span>
</template>
</el-table-column>
<el-table-column label="价格(元)">
<template slot-scope="scope">
<el-input v-model.number="scope.row.price"></el-input>
</template>
</el-table-column>
<el-table-column label="库存">
<template slot-scope="scope">
<el-input v-model.number="scope.row.stock"></el-input>
</template>
</el-table-column>
<el-table-column label="库存预警">
<template slot-scope="scope">
<el-input v-model.number="scope.row.low_stock"></el-input>
</template>
</el-table-column>
</el-table>
</div>
</div>
<script>
let yuan = []
// let yuan = [{
// goods_spec_id: 1,
// goods_spec_gid: 1,
// goods_spec_spectitle: "颜色",
// goods_spec_sort: 1,
// goods_spec_status: 1,
// spec: [
// {
// goods_spec_info_id: 1,
// goods_spec_info_gid: 1,
// goods_spec_info_specid: 1,
// goods_spec_info_title: "白色",
// goods_spec_info_src: "",
// goods_spec_info_sort: 0,
// goods_spec_info_status: 1
// },
// {
// goods_spec_info_id: 2,
// goods_spec_info_gid: 1,
// goods_spec_info_specid: 1,
// goods_spec_info_title: "黑色",
// goods_spec_info_src: "",
// goods_spec_info_sort: 0,
// goods_spec_info_status: 1
// }
// ]
// }]
var app = new Vue({
el: '#app',
data: {
newVal1:{},
kv:true,
a:0,
listtwo: [],
listtwob: [],
listspec: [
{
goods_spec_id: 1,
goods_spec_gid: 1,
goods_spec_spectitle: "颜色",
goods_spec_sort: 1,
goods_spec_status: 1,
spec: [
{
goods_spec_info_id: 1,
goods_spec_info_gid: 1,
goods_spec_info_specid: 1,
goods_spec_info_title: "白色",
goods_spec_info_src: "",
goods_spec_info_sort: 0,
goods_spec_info_status: 1
},
{
goods_spec_info_id: 2,
goods_spec_info_gid: 1,
goods_spec_info_specid: 1,
goods_spec_info_title: "黑色",
goods_spec_info_src: "",
goods_spec_info_sort: 0,
goods_spec_info_status: 1
}
]
},
{
goods_spec_id: 2,
goods_spec_gid: 1,
goods_spec_spectitle: "重量",
goods_spec_sort: 2,
goods_spec_status: 1,
spec: [
{
goods_spec_info_id: 3,
goods_spec_info_gid: 1,
goods_spec_info_specid: 2,
goods_spec_info_title: "1kg",
goods_spec_info_src: "",
goods_spec_info_sort: 0,
goods_spec_info_status: 1
},
{
goods_spec_info_id: 4,
goods_spec_info_gid: 1,
goods_spec_info_specid: 2,
goods_spec_info_title: "2kg",
goods_spec_info_src: "",
goods_spec_info_sort: 0,
goods_spec_info_status: 1
},
{
goods_spec_info_id: 17,
goods_spec_info_gid: 0,
goods_spec_info_specid: 2,
goods_spec_info_title: "3kg",
goods_spec_info_src: "",
goods_spec_info_sort: 0,
goods_spec_info_status: 1
},
{
goods_spec_info_id: 22,
goods_spec_info_gid: 0,
goods_spec_info_specid: 2,
goods_spec_info_title: "4kg",
goods_spec_info_src: "",
goods_spec_info_sort: 0,
goods_spec_info_status: 1
}
]
},
{
goods_spec_id: 7,
goods_spec_gid: 0,
goods_spec_spectitle: "材质",
goods_spec_sort: 3,
goods_spec_status: 1,
spec: [
{
goods_spec_info_id: 23,
goods_spec_info_gid: 0,
goods_spec_info_specid: 7,
goods_spec_info_title: "玻璃",
goods_spec_info_src: "",
goods_spec_info_sort: 0,
goods_spec_info_status: 1
},
{
goods_spec_info_id: 24,
goods_spec_info_gid: 0,
goods_spec_info_specid: 7,
goods_spec_info_title: "塑料",
goods_spec_info_src: "",
goods_spec_info_sort: 0,
goods_spec_info_status: 1
},
{
goods_spec_info_id: 25,
goods_spec_info_gid: 0,
goods_spec_info_specid: 7,
goods_spec_info_title: "金属",
goods_spec_info_src: "",
goods_spec_info_sort: 0,
goods_spec_info_status: 1
}
]
}
],
checkList:[],
checkList1:[],
attrN: ["颜色", "重量", "材质"],
attrV: [
[
"白色",
"黑色"
],
[
"1kg",
"2kg",
"3kg",
"4kg"
],
[
"玻璃",
"塑料",
"金属"
]
],
attrft:[],
showarr:{},
tableColumnList: {
tableHeaderList: [],
tableBodyList: []
// inventory: ''
},
privateGoodsItem: [
{
goods_spec_spectitle: '', //规格名
spec: [{
goods_spec_info_title:''
} ],
//规格值数组
inputVisible: false,
inputValue: ''
}
]
},
computed: {
// 计算规格
calculateAttribute() {
console.log('145');
// 初始化
let obj = {}
this.privateGoodsItem.forEach((item) => {
// 判断有没有输入规格名
if (item.goods_spec_spectitle) {
//规格名:规格值 //'颜色':'尺寸'
//console.log(item.spec);
obj[item.goods_spec_spectitle] = item.spec
}
})
//console.log(obj);
return obj
}
},
watch: {
//计算规格值差
checkList1(newVal,oldVal){
console.log('352',this.showarr);
v = this.showarr.goods_spec_spectitle
if(oldVal.length>newVal.length){
let diff = oldVal.filter((val)=> { return newVal.indexOf(val) === -1 })
d = this.newVal1[v]
d.forEach((n,index)=>{
if(n.goods_spec_info_title == diff[0]){
this.newVal1[v].splice(index, 1)
}
})
//this.listspec this.privateGoodsItem
this.listspec.forEach((n,index)=>{
//console.log('363',n);
if(n.goods_spec_spectitle == v){
console.log('365',index);
this.listspec[index].spec.forEach((m,index)=>{
if(m.goods_spec_info_title == diff[0]){
m.a = false
}
})
//w.
//w.spec.splice(index, 1)
//a = index;
}
})
this.privateGoodsItem.forEach((n,index)=>{
//console.log('363',n);
if(n.goods_spec_spectitle == v){
console.log('365',index);
this.privateGoodsItem[index].spec.forEach((m,i)=>{
if(m.goods_spec_info_title == diff[0]){
this.privateGoodsItem[index].spec.splice(i,1)
}
})
//w.
//w.spec.splice(index, 1)
//a = index;
}
})
}
console.log('372',this.listspec);
console.log('368',this.newVal1);
},
//计算规格名差集
checkList(newVal,oldVal){
console.log('351');
//console.log('347',oldVal);
//console.log('348',newVal);
//const a = null;
if(oldVal.length>newVal.length){
let diff = oldVal.filter((val)=> { return newVal.indexOf(val) === -1 })
//console.log(diff);
diff.forEach(item=>{
this.privateGoodsItem.forEach((n,index)=>{
if(n.goods_spec_spectitle == item){
//console.log(index);
this.privateGoodsItem.splice(index, 1)
//a = index;
}
})
})
}
if(oldVal.length<newVal.length){
let diff = newVal.filter((val)=> { return oldVal.indexOf(val) === -1 })
//console.log(diff);
diff.forEach(item=>{
this.privateGoodsItem.forEach((n,index)=>{
if(n.goods_spec_spectitle == item){
// console.log(index);
//this.privateGoodsItem.splice(index, 1)
this.a = index;
}
})
})
}
//console.log('377',this.a);
},
// 监听规格数据
calculateAttribute :{
handler(newVal) {
console.log('161');
// console.log('369',newVal);
// let cloneNewVal = newVal;
// if(this.kv){
// console.log('388',this.privateGoodsItem);
// b = this.privateGoodsItem[this.a].spec
// console.log(b);
// }
// let cloneNewVal = []
// Object.assign(cloneNewVal,newVal)
cloneNewVal = JSON.parse(JSON.stringify(newVal))
Object.assign([],this.newVal1,cloneNewVal)
//console.log('398',this.newVal1);
//console.log('386',cloneNewVal);
let attrName = [] //规格名数组
let attrValue = [] //规格值数组
// for (let key in cloneNewVal) {
// console.log('393');
// attrName.push(key)
// attrValue.push(cloneNewVal[key])
// console.log('402',attrValue);
// if(this.checkList.includes(key) && this.checkList1.length > 0){
// console.log(attrName);
// menuList = this.filterMenu(this.listspec);
// Object.assign(this.privateGoodsItem,menuList)
// b = this.privateGoodsItem[this.a]
// attrValue.push(b.spec)
// console.log('401',attrValue);
// console.log(this.listspec);
// }
// }
for (let key in cloneNewVal) {
attrName.push(key)
attrValue.push(cloneNewVal[key])
}
// 表格内容数据(笛卡尔积算法)
let finalArr = this.cartesianProductOf(...attrValue)
let tableObj = {
tableBodyList: [],
tableHeaderList: []
}
// 表格内容
tableObj.tableBodyList = finalArr.map((item) => {
let obj = {
price: 0,
stock: 0,
low_stock: 0
}
for (let i = 0; i < item.length; i++) {
obj[attrName[i]] = item[i]
}
return obj
})
this.tableColumnList.tableBodyList = tableObj.tableBodyList //表格内容数据
// 表头
let skuTableArr = Object.keys(newVal)
tableObj.tableHeaderList = skuTableArr.map((item) => {
return {
prop: item,
propName: item
}
})
this.tableColumnList.tableHeaderList = tableObj.tableHeaderList // 表头
},
deep:true
},
},
mounted() {
yuan.forEach((item)=>{
item.inputVisible=false,
item.inputValue=''
})
this.listspec.forEach((item)=>{
item.inputVisible=true,
item.inputValue='',
item.a = false
item['spec'].forEach(n=>{
n.a = false
})
})
// console.log(this.listspec);
//this.privateGoodsItem=yuan
},
methods: {
//获取规格
nvtwo(item,item1,index,index1){
// console.log('470',item);
//console.log('471',item1);
//console.log('472',index);
// console.log('473',index1);
a = this.attrN[index]
b = this.newVal1[a]
//this.newVal1[a]=item1
if(b){
// console.log('481',b);
b.push({'goods_spec_info_title':item1})
this.newVal1[a] = b
}else{
// console.log('483',b);
c = []
c.push({'goods_spec_info_title':item1})
this.newVal1[a] = c
//console.log('487',this.newVal1);
}
console.log('479',this.newVal1);
this.listspec.forEach(item=>{
if(item.a == true){
item.spec.forEach(item1=>{
if( this.checkList1.includes(item1.goods_spec_info_title)){
item1.a = true
}
})
}
})
console.log('545',this.listspec);
menuList = this.filterMenu(this.listspec);
console.log('547',menuList);
b = {}
menuList.forEach((item)=>{
if(item.goods_spec_spectitle == this.attrN[index]){
b = item.spec
}
})
// console.log('620',b);
// console.log(619,this.attrN[index])
// obj = {}
//console.log(item1);
// obj[this.attrN[index]]=b
// obj[this.attrN[index]].push(b)
// console.log('622',obj);
// this.newVal1 = obj
Object.assign(this.privateGoodsItem,menuList)
b = this.privateGoodsItem[this.a]
b['inputVisible'] = true
console.log('639',b.spec);
console.log('641',this.a)
this.showInput(b,this.a)
//calculateAttribute()
//value
// item['spec'].filter(item1=>this.checkList1.includes(item1.goods_spec_info_title) == true)
// c = b['spec'].filter(item=>this.checkList1.includes(item.goods_spec_info_title) == true)
// a.filter(item=>{
// a.pop(item)
// // console.log(item.goods_spec_spectitle);
// // if(!this.checkList.includes(item.goods_spec_spectitle)){
// // a.pop(item)
// // }
// })
// console.log(c);
// console.log(this.listtwo);
// console.log(c);
},
nvtwo1(index,index1){
p = this.privateGoodsItem
console.log('nvtwo')
console.log(index)
console.log(index1)
a = this.listspec[index]
b = a.spec[index1]
console.log(a);
console.log(b)
let c = JSON.parse(JSON.stringify(a))
c['spec']=[]
c['spec'].push(b);
console.log(c);
c['inputVisible']=false
c['inputValue']=''
d = p.concat(c)
this.privateGoodsItem = d
console.log(this.privateGoodsItem);
// c.forEach((item)=>{
// item.inputVisible=false,
// item.inputValue=''
// })
// this.privateGoodsItem=c
},
nv(item,index){
// console.log(this.privateGoodsItem.length);
// if(this.privateGoodsItem>0){
// this.privateGoodsItem.forEach(n=>{
// if(!n.goods_spec_spectitle == item){
// n.goods_spec_spectitle
// }
// })
// }else{
// this.privateGoodsItem.unshift({
// goods_spec_spectitle: item,
// spec: [],
// inputVisible: false,
// inputValue: ''
// })
// }
this.listspec.forEach(item=>{
if(this.checkList.includes(item.goods_spec_spectitle) == true){
item.a = true
item.inputVisible = true
}
})
if(this.checkList.length){
const a =[]
this.checkList.forEach(i=>{
t = this.attrN.indexOf(i)
// console.log(t);
a.push(t)
this.attrft = a
// console.log(this.attrft);
if(i == item){
this.privateGoodsItem.unshift({
goods_spec_spectitle: item,
spec: [],
inputVisible: false,
inputValue: ''
})
}
})
}
// if()
},
nv1(item,index){
if(this.privateGoodsItem>0){
}else{
this.privateGoodsItem.push({
goods_spec_spectitle: item,
spec: [ ],
inputVisible: false,
inputValue: ''
})
}
console.log('nv');
//this.checkList
if(this.checkList.length){
const a =[]
this.checkList.forEach(item=>{
t = this.attrN.indexOf(item)
// console.log(t);
a.push(t)
this.attrft = a
// console.log(this.attrft);
})
}
b = this.listspec.filter(item=>this.checkList.includes(item.goods_spec_spectitle) == true)
console.log(b);
this.listtwob = b
console.log(this.listtwob);
this.listtwo = b
this.listspec.forEach(item=>{
if(this.checkList.includes(item.goods_spec_spectitle) == true){
item.a = true
}
})
console.log(this.listspec);
},
//递归函数
filterMenu(menuList) {
return menuList.filter(item => {
return item.a == true;
}).map(item => {
item = Object.assign({}, item)
if(item.spec && item.spec.length > 0) {
item.spec = this.filterMenu(item.spec)
}
return item
})
},
// filterMenu(){
// menuList => {
// return menuList.filter(item => {
// return item.a == true;
// }).map(item => {
// item = Object.assign({}, item)
// if(item.spec && item.spec.length > 0) {
// item.spec = this.filterMenu(item.spec)
// }
// return item
// })
// }
// },
// 添加规格
addPrivateSpec(index) {
console.log('205');
this.privateGoodsItem.push({
goods_spec_spectitle: '',
spec: [],
inputVisible: false,
inputValue: ''
})
console.log('658',this.privateGoodsItem);
},
delPrivateSpec(index) {
this.privateGoodsItem.splice(index, 1)
},
handleInputConfirm(val, attr) {
if (val) {
attr.spec.push({goods_spec_info_title:val})
}
attr.inputVisible = false
attr.inputValue = ''
},
handleClose(tag, item) {
item.spec.splice(item.spec.indexOf(tag), 1)
},
showInput(attr, index) {
this.showarr = attr
console.log(attr);
console.log(index);
attr.inputVisible = true
this.$nextTick((_) => {
this.$refs[`saveTagInput${index}`][0].$refs.input.focus()
})
},
// 笛卡尔积算法
cartesianProductOf(...args) {
return args.reduce(
(total, current) => {
let ret = []
total.forEach((a) => {
current.forEach((b) => {
ret.push(a.concat([b]))
})
})
return ret
},
[[]]
)
}
}
})
</script>
</body>
</html>
```
- webpack-dev-server不是内部或外部命令
- vue+ele添加笑脸表情
- from UglifyJs Unexpected token: punc (()
- vmodel-ref
- jscopy
- watch_or_computed
- checkbox-group
- array_filter
- array many filter
- js array unshift
- vue watch one
- sku
- edit-button
- el-select clearable placeholder
- 必填
- 如何设置一个索引从1开始
- Injection "elForm" not found
- $refs
- resetFields
- table 二级数据
- Table 合并
- switch 开关
- radio group 单选
- 二级菜单
- 访问页面出错后退到上一页
- 编辑器tinymce
- v-for从1开始索引
- 图片绑定路径
- 分栏间隔
- class绑定card底色
- 动态增减表单项
- watch deep
- form 获取值
- table索引方法
- table两个改一个另一个也跟着变解决方法
- table标题改整列
- vue echarts