基于element组件商品sku多规格

article/2025/10/3 7:47:38

 1.sku多规格效果图

商品的sku涉及到很多动态表单,因为分为单规格和多规格。而每次一到写动态表单就让人头疼。所以特此记录一下,方便自己下次再用也帮助他人减少麻烦。闲话少叙,先看效果图。

 上面的部分输入表单可以无视了,主要还是动态商品规格sku的添加。上代码:

2.在vue框架中使用

<template><div class="goodsdetails"><div class="title" style="display: flex;justify-content: space-between;align-items: center;"><el-page-header @back="goBack" :content="title"></el-page-header><el-button type="primary" size="small" @click="submit">保存</el-button></div><a-divider /><el-descriptions title="基础信息"></el-descriptions><el-form :model="ruleForm" :inline="false"   ref="ruleForm" label-width="100px" class="demo-ruleForm"><el-form-item label="封面图:"><Uploadimg :limit="1"  :key="timer"  :filelist="ruleForm.image"  @getfile="filelist"></Uploadimg></el-form-item><el-form-item label="轮播图:"><Uploadimg :limit="3"  :key="timer" :filelist="ruleForm.sliderImage"  @getfile="filelistarr"></Uploadimg></el-form-item><el-form-item label="商品分类:" ><el-cascader ref="myCascader"  style="width:360px" @change="getpositionName" v-model="ruleForm.cateId" :options="options" placeholder="请选择分类" :props="{ emitPath:false,checkStrictly: true,value:'id',label:'name'}"  class="ml-4"></el-cascader></el-form-item><el-form-item label="商品名称:" ><el-input v-model="ruleForm.storeName"></el-input></el-form-item><el-form-item label="商品简介:" ><el-input v-model="ruleForm.storeInfo"></el-input></el-form-item><el-form-item label="详细描述:" ><el-input v-model="ruleForm.description"></el-input></el-form-item><el-form-item label="返现积分:" ><el-input v-model="ruleForm.giveIntegral" type="number" min=0></el-input></el-form-item><el-form-item label="销量:" ><el-input v-model="ruleForm.ficti" type="number" min=0></el-input></el-form-item><el-form-item label="关键词:" ><el-tag :key="tag" v-for="tag in dynamicTags" closable :disable-transitions="false" @close="handleClosekey(tag)">{{tag}}</el-tag><el-inputclass="input-new-tag"v-if="inputVisible"v-model="inputValue"ref="saveTagInput"size="small"@keyup.enter.native="handleInputConfirmkey"@blur="handleInputConfirmkey"></el-input><el-button v-else class="button-new-tag" size="small" @click="showInputkey">+ New Tag</el-button></el-form-item><el-form-item label="排序:" ><el-input v-model="ruleForm.sort" placeholder="数值越大越靠前" type="number" min=0></el-input></el-form-item><el-form-item label="是否多规格:" ><el-switch v-model="ruleForm.specType"></el-switch></el-form-item><el-form-item label="是否积分商品:" ><el-switch v-model="ruleForm.integralType"></el-switch></el-form-item><!-- 规格 --><el-divider></el-divider><div><div class="goods-spec" v-if="ruleForm.specType"><h3>商品规格</h3><el-link type="primary" @click="addPrivateSpec" class="goods-spec-add">添加规格</el-link></div><div v-if="ruleForm.specType" class="goods-container" v-for="(attr, index) in items" :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.value" placeholder="请输入规格名"></el-input></el-form-item><el-form-item label="规格值"><el-tag v-for="tag in attr.detail" :key="tag" closable :disable-transitions="false" @close="handleClose(tag, attr)">{{ tag }}</el-tag><el-inputclass="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] }}</span></template></el-table-column><el-table-column label="商品条码"><template slot-scope="scope"><el-input v-model="scope.row.barCode"></el-input></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.cost"></el-input></template></el-table-column><el-table-column label="原价(元)"><template slot-scope="scope"><el-input v-model.number="scope.row.otPrice"></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="scope.row.volume"></el-input></template></el-table-column><el-table-column label="重量"><template slot-scope="scope"><el-input v-model="scope.row.weight"></el-input></template></el-table-column><el-table-column label="兑换所需积分" v-if="ruleForm.integralType"><template slot-scope="scope"><el-input v-model="scope.row.integral"></el-input></template></el-table-column></el-table></div><!-- <el-button type="primary" style="width: 20%;margin-left: 30%;margin-top: 20px;">保存</el-button> --></el-form></div>
</template><script>import Uploadimg from "@/components/Uploadimg";export default {data(){return{ruleForm: {cateId:'',cateName:'',image:[],sliderImage:[],storeName: '',storeInfo: '',description: '',giveIntegral: '',ficti: '',sort: '',specType: false,integralType:false,},dynamicTags: ['标签一', '标签二'],  //关键词inputVisible: false,inputValue: '',tableColumnList: {tableHeaderList: [],tableBodyList: [{}]// inventory: ''},items: [    //sku属性{value: '', //规格名detail: [], //规格值数组inputVisible: false,inputValue: ''}],options:[],   //商品类列表id:"",   //无则添加有则编辑timer:'',  //刷新子组件title:"",}},mounted(){this.title="添加商品"if(this.$route.query.id){this.id=this.$route.query.id;this.title="商品信息"this.getdetails();}this.getoptions();},computed: {// 计算规格calculateAttribute() {// 初始化let obj = {}this.items.forEach((item) => {// 判断有没有输入规格名if (item.value) {//规格名:规格值     //'颜色':'尺寸'obj[item.value] = item.detail}})return obj}},watch: {// 监听规格数据calculateAttribute(newVal) {if(!this.ruleForm.specType){return;}this.attribute(newVal);//             let cloneNewVal = JSON.parse(JSON.stringify(newVal))//             let attrName = [] //规格名数组//             let attrValue = [] //规格值数组//             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 = {//                barCode: '',   //商品条码//                cost:0,        //成本价//                otPrice:0,     //原价//                price:0,       //现价//                stock: 0,	   //库存//                volume:'',     //体积//                weight:'',     //重量//               }//               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 // 表头},'ruleForm.specType':{deep:true,handler:function(newV,oldV){if(!newV){this.tableColumnList= this.$options.data().tableColumnList;this.items=this.$options.data().items;}}}},methods: {getpositionName(){const info = this.$refs.myCascader.getCheckedNodes()[0];this.ruleForm.cateName=info.label;},getoptions(){	//获取商品分类列表const that = this;this.$api.categorylist({}).then(function (response) {if(response.code==0){that.options=that.removeEmptyChildren(response.data);}else{that.$message({message: response.message,center: true,type: 'warning',});}})},removeEmptyChildren (node) {   //杀生var that=this;node.forEach(item => {if ('children' in item && item.children.length === 0) {delete item.children} else if ('children' in item && item.children.length) {that.removeEmptyChildren(item.children)}})return node;},attribute(newVal){var that=this;this.$api.goodssku(that.items).then(res=>{if(res.code==0){// console.log("属性",res);let cloneNewVal = JSON.parse(JSON.stringify(newVal))let attrName = [] //规格名数组let attrValue = [] //规格值数组for (let key in cloneNewVal) {attrName.push(key)attrValue.push(cloneNewVal[key])}// 表格内容数据(笛卡尔积算法)let finalArr = this.cartesianProductOf(...attrValue)	let tableObj = {tableBodyList: [],tableHeaderList: []}// 表格内容tableObj.tableBodyList = res.data.map((item) => {var detail=item.detail;return Object.assign(item, detail);})this.tableColumnList.tableBodyList = tableObj.tableBodyList //表格内容数据this.tableColumnList.tableBodyList = res.data;// 表头let skuTableArr = Object.keys(newVal)tableObj.tableHeaderList = skuTableArr.map((item) => {return {prop: item,propName: item}})this.tableColumnList.tableHeaderList = tableObj.tableHeaderList // 表头}else{this.$message({message: res.message,center: true,});}}).catch(err=>{console.log("网络错误",err)})},//上传的图片列表filelist(list){console.log("封面图片:",list)this.ruleForm.image=list;},filelistarr(list){console.log("轮播图片:",list)this.ruleForm.sliderImage=list;},goBack(){this.$router.go(-1);},//关键词操作handleClosekey(tag) {this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1);},showInputkey() {this.inputVisible = true;this.$nextTick(_ => {this.$refs.saveTagInput.$refs.input.focus();});},handleInputConfirmkey() {let inputValue = this.inputValue;if (inputValue) {this.dynamicTags.push(inputValue);}this.inputVisible = false;this.inputValue = '';},//获取详情getdetails(){var that=this;this.$api.goodsdetails({id:that.id}).then(res=>{if(res.code==0){console.log("商品:",res);that.ruleForm=res.data;that.ruleForm.image=res.data.image.split(",");that.ruleForm.sliderImage=res.data.sliderImage.split(",");that.dynamicTags=res.data.keyword.split(",");that.items=res.data.items.map(item=>{item.inputValue="";item.inputVisible=false;return item;})setTimeout(()=>{let tablearr=[];for(var i=0; i<res.data.attrs.length;i++){tablearr.push(Object.assign(that.tableColumnList.tableBodyList[i],res.data.attrs[i]));}that.tableColumnList.tableBodyList=tablearr;},500)that.timer = new Date().getTime();}else{this.$message({message: res.message,center: true,});}}).catch(err=>{console.log("网络错误",err)})},submit(){var that=this;var obj;if(this.id){  //编辑obj=JSON.parse(JSON.stringify(that.ruleForm));obj.id=that.id;obj.items=that.items;obj.attrs=that.tableColumnList.tableBodyList;obj.keyword=that.dynamicTags.toString();obj.image=obj.image.toString();obj.sliderImage=obj.sliderImage.toString();this.$api.goodsedit(obj).then(res=>{if(res.code==0){this.$message({type:"success",message: res.message,center: true,});that.$router.push({path:'/product/goods'})}else{this.$message({message: res.message,center: true,});}}).catch(err=>{console.log("网络错误",err)})}else{obj=JSON.parse(JSON.stringify(that.ruleForm));obj.items=that.items;obj.attrs=that.tableColumnList.tableBodyList;obj.keyword=that.dynamicTags.toString();obj.image=obj.image.toString();obj.sliderImage=obj.sliderImage.toString();this.$api.goodsadd(obj).then(res=>{if(res.code==0){this.$message({type:"success",message: res.message,center: true,});that.$router.push({path:'/product/goods'})}else{this.$message({message: res.message,center: true,});}}).catch(err=>{console.log("网络错误",err)})}},/*****规格*****/// 添加规格addPrivateSpec(index) {this.items.push({value: '',detail: [],inputVisible: false,inputValue: ''})},delPrivateSpec(index) {this.items.splice(index, 1)},handleInputConfirm(val, attr) {if (val) {attr.detail.push(val)}attr.inputVisible = falseattr.inputValue = ''},handleClose(tag, item) {item.detail.splice(item.detail.indexOf(tag), 1)},showInput(attr, index) {attr.inputVisible = truethis.$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},[[]])}},components:{Uploadimg:Uploadimg,}};
</script>
<style scoped>.goodsdetails{height: 100%;width: 100%;background: #FFFFFF;padding: 30px;}.goodsdetails .demo-ruleForm{width: 100%;/* display: flex;align-items: center;justify-content: space-between;flex-wrap: wrap; */}.goodsdetails .demo-ruleForm>div{width: 80%;}.goodsdetails .el-tag + .el-tag {margin-left: 10px;}.goodsdetails  .button-new-tag {margin-left: 10px;height: 32px;line-height: 30px;padding-top: 0;padding-bottom: 0;}.goodsdetails  .input-new-tag {width: 90px;margin-left: 10px;vertical-align: bottom;}/* .goodsdetails .uploadimg{display: flex;width: 80vw;} */.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>

这是单个的vue文件,在使用之前,先确保你项目是否使用了element Ui组件。使用时直接复制到页面就行。可能会报错。

报错1:这里我使用了Uploadimg图片上传组件。主要是上传图片到阿里云oss。删掉即可。

报错2:页面加载时请求了接口,调用了方法this.getoptions();主要是拉取商品分类列表数据。注释和删掉即可。

其他的就是逻辑代码了。可以happy~奔放一下看到具体效果。

码字不易,转载请注明出处,谢谢~


http://chatgpt.dhexx.cn/article/I13JEaXA.shtml

相关文章

php商品规格sku,SKU商品规格选择

SKU商品规格选择 在线demo地址 Github代码地址 可选属性实现思路 当用户点击某选项(如"黑色")时,拿到此时所有规格的选项( { color: "黑色" }) 根据商品数据、用户当前选择规格,查找匹配商品。如果找到了,就返回商品标识(商品为数组则返回数组索引 inde…

vue实现后台管理商品sku组合

本人菜鸟一个&#xff0c;但最近要写一个后台管理前端部分&#xff0c;然后在写一个商品sku组合时遇到了点问题&#xff0c;所以在这里记录一下。在网上能找到很多方法&#xff0c;也有很简单的&#xff0c;但我看好像都是有一个问题&#xff0c;就是第一次生成之后&#xff0c…

Geek-SKU 多商品sku组件支持v3、带图sku

如果您正在寻找一款支持v3、v2的多商品sku组件的话&#xff0c;那我想这款组件刚好可以满足各位的业务需求。 先来简单看一眼效果图: 一款轻量化、强大、拓展性强、可使用带图sku、可根据配置主题色自动生成相应的组件主题色的商品多规格sku&#xff0c;仅需要按照指定格式…

尚品汇_第5章_ 商品sku保存

尚品汇_第5章_ 商品sku保存 文章目录 尚品汇_第5章_ 商品sku保存一、业务介绍1.1 数据库表结构1.2 数据准备1.1 平台属性添加1.2 商品spu管理 二、保存skuInfo功能2.1 图片加载功能2.1.1 添加接口实现类2.1.2 添加控制器 2.2 销售属性2.2.1 编写接口以及实现类2.2.2 编写控制器…

js实现商品sku组合

const data [[红色,绿色,金色,青色,白色],[M,L,XL,XXL,XXXL],[男装,女装] ] var sku getSku(data)function getSku(data) {let newArr [];let delimiter "|(_##sku##_)|"; // 分隔符&#xff0c;避免sku中出现相同字符出现数据丢失情况function get(index, arr, …

java实现商品sku_jquery实现商品sku多属性选择功能(商品详情页)

SKUStock Keeping Unit(库存量单位)。即库存进出计量的基本单元&#xff0c;可以是以件&#xff0c;盒&#xff0c;托盘等为单位。 SKU是用来定价和管理库存的&#xff0c;比如一个产品有很多颜色&#xff0c;很多配置&#xff0c;每个颜色和配置的组合都会形成新的产品&#x…

商品sku 和批量编辑 js算法

这一段时间在搞商品后台的系统&#xff0c;其中关于通过商品的销售属性&#xff0c;生成SKU的处理&#xff0c;这里说明一下。 /*** 生成笛卡尔积* returns {*}*/ function descartes(array){if( array.length < 2 ) return array[0] || [];return [].reduce.call(array, fu…

laravel-admin 结合搭配商品sku

本文章基于jade 的基础上&#xff0c;完善部分功能。多谢jade提供sku方案 多个规格名&#xff0c;只显示2个添加规则值&#xff0c;保留已有的信息保存数据库后&#xff0c;json数据会自动排序 (2020-09-21 新增) Form 扩展 – 商品Sku 1.安装&#xff1a; composer requi…

商品SKU系统

如何设计库存&#xff0c;哪些库存呢&#xff1f;分类属性的库存&#xff1a;不同颜色 不同尺码的属性的库存 &#xff0c;这些就体现了商品的SKU&#xff0c;至于什么是SKU&#xff0c;自己去百度一下哈&#xff0c;所以首先我们就要设计商品Sku表以及关系表了 总体思路 1.…

java实现商品sku_商品SKU功能设计与优化

SpringBoot实战电商项目mall(30k+star)地址:github.com/macrozheng/… 摘要 原来的商品SKU设计存在着两个问题,一个是SKU表设计上面比较固化,无法扩展。另一个是当修改了商品信息之后,商品SKU的ID会发生变化,由于购物车表和订单商品表都关联了商品SKU的ID,这样就会导致匹…

sku mysql_商品sku处理

简单来说&#xff0c;一个电商类网站&#xff0c;根据平台的不同&#xff0c;商品的属性自然也就不同。 一般情况来说&#xff0c;一个商品 goods_id 对应多个 sku_id ; 设计表时我们会采取这样的方式&#xff1a; 产品表  ---   产品sku表  ---  产品基本属性表(产品属…

一个商品SKU是怎么生成的

首先说一说什么是SKU。。。。。。。自己百度去。。。 类似京东上面&#xff0c;未来人类S5这个台笔记本&#xff08;没错&#xff0c;我刚入手了&#xff09; 都是S5这个型号&#xff0c;但是因为CPU,显卡&#xff0c;内存&#xff0c;硬盘等不同&#xff0c;价格也不一样。CPU…

商品SKU

前言 最近项目开发涉及商品SKU&#xff0c;商品SKU计算原理就是笛卡尔积&#xff0c;下面对相关内容做一下总结。 一、什么是SKU SKUStock Keeping Unit(库存量单位)&#xff0c;即库存进出计量的单位&#xff0c;可以是以件&#xff0c;盒&#xff0c;托盘等为单位。针对电商而…

深度学习(二)---算法岗面试题

● 神经网络为什么用交叉熵 参考回答&#xff1a; 通过神经网络解决多分类问题时&#xff0c;最常用的一种方式就是在最后一层设置n个输出节点&#xff0c;无论在浅层神经网络还是在CNN中都是如此&#xff0c;比如&#xff0c;在AlexNet中最后的输出层有1000个节点&#xff0c…

深度学习面试题常见问答

目录 有哪些方法可以避免过拟合? 造成过拟合的原因&#xff1a; 解决办法&#xff1a; dropout在训练时和推理时的区别是什么&#xff1f; L1和L2正则化的区别&#xff1f;为什么L1比L2更稀疏&#xff1f; Batch Size大小如何影响收敛速度&#xff1f; BN的原理&#x…

机器学习、深度学习笔试题面试题整理

机器学习、深度学习笔试题 面试题总结 整理看到的内容&#xff0c;以免忘记 里面添加参考的链接&#xff0c;感谢各位大佬 感受野如何计算&#xff1f; 参考链接&#xff1a;https://blog.csdn.net/a841454735/article/details/88558906 感受野指的是一个特定的 CNN 特征&am…

深度学习(三)----算法岗面试题

● 神经网络为啥用交叉熵。 参考回答&#xff1a; 通过神经网络解决多分类问题时&#xff0c;最常用的一种方式就是在最后一层设置n个输出节点&#xff0c;无论在浅层神经网络还是在CNN中都是如此&#xff0c;比如&#xff0c;在AlexNet中最后的输出层有1000个节点&#xff0c;…

深度学习(二)-----算法岗面试题

● 深度学习了解多少&#xff0c;有看过底层代码吗&#xff1f;caffe,tf? ● 除了GMM-HMM&#xff0c;你了解深度学习在语音识别中的应用吗&#xff1f; 参考回答&#xff1a; 讲了我用的过DNN-HMM&#xff0c;以及与GMM-HMM的联系与区别&#xff1b;然后RNNCTC&#xff0c;这…

深度学习面试题-2

1. 下列哪一项属于特征学习算法&#xff08;representation learning algorithm&#xff09;&#xff1f; A K近邻算法 B 随机森林 C 神经网络 D 都不属于 正确答案是&#xff1a;C&#xff0c; 您的选择是&#xff1a;C 解析&#xff1a;神经网络会将数据转化为更适合解决目…

深度学习面试题总结1-20

1.CNN的卷积核是单层还是多层的&#xff1f; 描述网络模型中某层的厚度&#xff0c;通常用名词通道channel数或者特征图feature map数。不过人们更习惯把作为数据输入的前层的厚度称之为通道数&#xff08;比如RGB三色图层称为输入通道数为3&#xff09;&#xff0c;把作为卷积…