威海网站建设是什么,查企业免费的网站,wordpress信息,安康网站制作代码下载
商品分类页
新商品分类组件 goods/Cate.vue#xff0c;在router.js中导入子级路由组件 Cate.vue#xff0c;并设置路由规则。
绘制商品分类基本结构
在Cate.vue组件中添加面包屑导航以及卡片视图中的添加分类按钮#xff1a;
templatediv…代码下载
商品分类页
新商品分类组件 goods/Cate.vue在router.js中导入子级路由组件 Cate.vue并设置路由规则。
绘制商品分类基本结构
在Cate.vue组件中添加面包屑导航以及卡片视图中的添加分类按钮
templatediv!-- 面包屑导航 --el-breadcrumb separator-classel-icon-arrow-rightel-breadcrumb-item :to{ path: /home/welcome }首页/el-breadcrumb-itemel-breadcrumb-item商品管理/el-breadcrumb-itemel-breadcrumb-item商品分类/el-breadcrumb-item/el-breadcrumb!-- 卡片 --el-card!-- 添加 --el-button typeprimary clickshowAddCateDialog添加分类/el-button!-- 分类列表 --tree-table classtree-table :datacatelist :columnscolumns :selection-type false :expand-typefalse :show-indextrue :index-text# border :show-row-hoverfalsetemplate slotisOk slot-scopescopei classel-icon-error stylecolor: red; v-ifscope.row.cat_deleted/ii classel-icon-success stylecolor: lightgreen; v-else/i/templatetemplate slotorder slot-scopescopeel-tag v-ifscope.row.cat_level 0一级/el-tagel-tag typesuccess v-else-ifscope.row.cat_level 1二级/el-tagel-tag typewarning v-else三级/el-tag/templatetemplate slotopt slot-scopescopeel-button typeprimary iconel-icon-edit sizemini编辑/el-buttonel-button typedanger iconel-icon-delete sizemini clickremoveCateById(scope.row.cat_id)删除/el-button/template/tree-table!-- 分页 --el-paginationsize-changehandleSizeChangecurrent-changehandleCurrentChange:current-pagequeryInfo.pagenum:page-sizes[2, 3, 5, 10]:page-sizequeryInfo.pagesizelayouttotal, sizes, prev, pager, next, jumper:totaltotal/el-pagination/el-card!-- 添加分类对话框 --el-dialog title添加商品分类 :visible.syncaddCateDialogVisible width50% closeaddCateDialogClosedel-form :modeladdCateForm :rulesaddCateFormRules refaddCateFormRef label-width100pxel-form-item label分类名称 propcat_nameel-input v-modeladdCateForm.cat_name/el-input/el-form-itemel-form-item label父级分类el-cascader v-modelselectedKeys :optionsparentCateList :propscascaderProps changeparentCateChange clearable/el-cascader/el-form-item/el-formspan slotfooter classdialog-footerel-button clickaddCateDialogVisible false取 消/el-buttonel-button typeprimary clickaddCate确 定/el-button/span/el-dialog/div
/template主要功能实现
script
export default {data() {return {catelist: [], queryInfo: {type: 3,pagenum: 1,pagesize: 5},total: 0,columns: [{label: 分类名称,prop: cat_name},{label: 是否有效,// 列类型可选值有 template(自定义列模板)type: template,// 列类型为 template(自定义列模板) 时对应的作用域插槽它可以获取到 row, rowIndex, column, columnIndex名称template: isOk},{label: 排序,type: template,template: order},{label: 操作,type: template,template: opt}],addCateDialogVisible: false,addCateForm: {cat_pid: 0,cat_name: ,cat_level: 0},// 添加商品分类表单验证addCateFormRules: {cat_name: [{ required: true, message: 请输入分类名称, trigger: blur }]},parentCateList: [],cascaderProps: {expandTrigger: hover,checkStrictly: true,value: cat_id,label: cat_name,children: children},selectedKeys: []}},created() {this.getCateList()},methods: {async getCateList() {const { data: res } await this.$http.get(categories, { params: this.queryInfo })if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.catelist res.data.resultthis.total res.data.totalthis.$msg.success(商品分类获取成功)},handleSizeChange(size) {console.log(size: , size);this.queryInfo.pagesize sizeconst maxN parseInt(this.total / this.queryInfo.pagesize ) (this.total % this.queryInfo.pagesize 0 ? 1 : 0)this.queryInfo.pagenum this.queryInfo.pagenum maxN ? maxN : this.queryInfo.pagenumthis.getCateList()},handleCurrentChange(page) {console.log(page: , page);this.queryInfo.pagenum pagethis.getCateList()},// 展示添加商品分类对话框async showAddCateDialog() {// 获取父级分类const { data: res } await this.$http.get(categories, { params: { type: 2 } })if (res.meta.status ! 200) return this.$msg.error(res.meta.error)this.parentCateList res.datathis.addCateDialogVisible true},// 关闭添加商品分类对话框addCateDialogClosed() {this.$refs.addCateFormRef.resetFields()this.addCateForm.cat_pid 0this.addCateForm.cat_level 0this.addCateForm.cat_name this.selectedKeys []},// 添加商品分类async addCate() {// 验证表单this.$refs.addFormRef.validate(async valid {if (!valid) return this.$msg.error(请填写正确的分类名称)const { data: res } await this.$http.post(categories, this.addCateForm)if (res.meta.status ! 201) return this.$msg.error(res.meta.msg)this.$msg.success(添加商品分类成功)this.getCateList()// 关闭对话框重置数据this.addCateDialogVisible false})},parentCateChange(v) {console.log(change: , v);// 处理父分类id和分类级别if (this.selectedKeys.length 0) {this.addCateForm.cat_pid this.selectedKeys[this.selectedKeys.length - 1]this.addCateForm.cat_level this.selectedKeys.length} else {this.addCateForm.cat_pid 0this.addCateForm.cat_level 0}},async removeCateById(uid) {const confirm await this.$confirm(此操作将永久删除该分类, 是否继续?, 提示, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning}).catch(e e);// 如果用户确认删除则返回值为字符串 confirm如果用户取消了删除则返回值为字符串 cancelconsole.log(confirm: , confirm);if (confirm ! confirm) returnconst { data: res } await this.$http.delete(categories/ uid)if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(删除商品分类成功)if (this.queryInfo.pagenum 1 this.catelist.length 1) this.queryInfo.pagenum - 1this.getCateList()}}
}
/script1、请求分类数据请求分类数据并将数据保存在data中
2、使用插件展示数据使用第三方插件 vue-table-with-tree-grid 展示分类数据
在vue 控制台中点击依赖-安装依赖-运行依赖-输入vue-table-with-tree-gird-点击安装打开main.js导入vue-table-with-tree-grid import TreeTable from vue-table-with-tree-grid并全局注册组件 Vue.component(tree-table, TreeTable)
3、自定义数据列使用vue-table-with-tree-grid定义模板列并添加自定义列
4、完成分页功能
5、完成添加分类添加级联菜单显示父级分类。先导入Cascader组件并注册然后添加使用级联菜单组件
参数管理页
只允许给三级分类内容设置参数参数分为动态参数和静态参数属性。
添加 goods/Params.vue 子组件并在router.js中引入该组件并设置路由规则。
绘制参数管理基本结构
完成Params.vue组件的基本布局其中警告提示信息使用了el-alert在element.js引入该组件并注册
templatediv!-- 面包屑导航 --el-breadcrumb separator-classel-icon-arrow-rightel-breadcrumb-item :to{ path: /home/welcome }首页/el-breadcrumb-itemel-breadcrumb-item商品管理/el-breadcrumb-itemel-breadcrumb-item参数列表/el-breadcrumb-item/el-breadcrumb!-- 卡片 --el-cardel-alert title注意只允许为第三级分类设置相关参数 typewarning show-icon :closablefalse/el-alert!-- 商品分类 --div classcat_optspan请选择商品分类/spanel-cascader v-modelselectedCateKeys :optionscateList :propscateProps changehandleChange clearable/el-cascader/divel-tabs v-modelactiveName tab-clickhandleTabClickel-tab-pane label动态参数 namemanyel-button typeprimary sizemini :disabledselectedCateKeys.length!3 clickaddDialogVisible true添加参数/el-button!-- 动态参数列表 --el-table :datamanyTableData stylewidth: 100% border stripeel-table-column typeexpandtemplate slot-scopescopeel-tag v-for(v, i) in scope.row.attr_vals :keyi closable closehandleClose(scope.row, i){{v}}/el-tagel-input classinput-new-tag v-ifscope.row.inputVisible v-modelscope.row.inputValue refsaveTagInput sizesmall keyup.enter.nativehandleInputConfirm(scope.row) blurhandleInputConfirm(scope.row)/el-inputel-button v-else classbutton-new-tag sizesmall clickshowInput(scope.row) New Tag/el-button/template/el-table-columnel-table-column typeindex label#/el-table-columnel-table-column propattr_name label属性名称/el-table-columnel-table-column label操作template slot-scopescopeel-button typeprimary iconel-icon-edit sizemini clickshowEditDialog(scope.row.attr_id)编辑/el-buttonel-button typedanger iconel-icon-delete sizemini clickremoveParams(scope.row.attr_id)删除/el-button/template/el-table-column/el-table/el-tab-paneel-tab-pane label静态属性 nameonlyel-button typeprimary sizemini :disabledselectedCateKeys.length!3 clickaddDialogVisible true添加属性/el-button!-- 静态属性列表 --el-table :dataonlyTableData stylewidth: 100% border stripeel-table-column typeexpandtemplate slot-scopescopeel-tag v-for(v, i) in scope.row.attr_vals :keyi closable closehandleClose(scope.row, i){{v}}/el-tagel-input classinput-new-tag v-ifscope.row.inputVisible v-modelscope.row.inputValue refsaveTagInput sizesmall keyup.enter.nativehandleInputConfirm(scope.row) blurhandleInputConfirm(scope.row)/el-inputel-button v-else classbutton-new-tag sizesmall clickshowInput(scope.row) New Tag/el-button/template/el-table-columnel-table-column typeindex label#/el-table-columnel-table-column propattr_name label属性名称/el-table-columnel-table-column label操作template slot-scopescopeel-button typeprimary iconel-icon-edit sizemini clickshowEditDialog(scope.row.attr_id)编辑/el-buttonel-button typedanger iconel-icon-delete sizemini clickremoveParams(scope.row.attr_id)删除/el-button/template/el-table-column/el-table/el-tab-pane/el-tabs/el-card!-- 添加参数对话框 --el-dialog :title添加 titleText :visible.syncaddDialogVisible width50% closeaddDialogClosedel-form :modeladdForm :rulesaddFormRules refaddFormRef label-width100pxel-form-item :labeltitleText propattr_nameel-input v-modeladdForm.attr_name/el-input/el-form-item/el-formspan slotfooter classdialog-footerel-button clickaddDialogVisible false取 消/el-buttonel-button typeprimary clickaddParams确 定/el-button/span/el-dialog!-- 编辑参数对话框 --el-dialog :title编辑 titleText :visible.synceditDialogVisible width50% closeeditDialogClosedel-form :modeleditForm :ruleseditFormRules refeditFormRef label-width100pxel-form-item :labeltitleText propattr_nameel-input v-modeleditForm.attr_name/el-input/el-form-item/el-formspan slotfooter classdialog-footerel-button clickeditDialogVisible false取 消/el-buttonel-button typeprimary clickeditParams确 定/el-button/span/el-dialog/div
/template主要功能实现
script
export default {data() {return {cateList: [],selectedCateKeys: [],cateProps: {expandTrigger: hover,value: cat_id,label: cat_name,children: children},// 被激活的标签页名activeName: many,// 动态参数数据manyTableData: [],// 静态属性数据onlyTableData: [],// 是否展示添加参数对话框addDialogVisible: false,// 添加参数对话框数据addForm: {attr_name: },// 添加参数对话框验证规则addFormRules: {attr_name: [{ required: true, message: 请输入参数名称, trigger: blur }]},// 是否展示编辑参数对话框editDialogVisible: false,// 编辑参数对话框数据editForm: {attr_name: },// 编辑参数对话框验证规则editFormRules: {attr_name: [{ required: true, message: 请输入参数名称, trigger: blur }]}}},created() {this.getCateList()},methods: {// 获取分类数据async getCateList() {const { data: res } await this.$http.get(categories, { params: { type: 3 } })if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(获取商品分类成功)this.cateList res.data},// 获取参数列表数据async getParamsData() {const { data: res } await this.$http.get(categories/${this.cateId}/attributes, { params: { sel: this.activeName } })if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(获取参数列表成功)// 将 attr_vals 转换为数组res.data.forEach(item {item.attr_vals item.attr_vals ? item.attr_vals.split( ) : []item.inputVisible falseitem.inputValue });if (this.activeName many) this.manyTableData res.datathis.onlyTableData res.data},// 分类改变handleChange() {if (this.selectedCateKeys.length ! 3) {this.selectedCateKeys []this.manyTableData []this.onlyTableData []return}console.log(change: , this.selectedCateKeys);this.getParamsData()},// 点击标签页handleTabClick() {if (this.selectedCateKeys.length 3) this.getParamsData()},// 关闭添加参数对话框addDialogClosed() {this.$refs.addFormRef.resetFields()},// 添加商品参数addParams() {// 验证表单this.$refs.addFormRef.validate(async valid {if (!valid) return this.$msg.error(请填写正确的参数名称)const { data: res } await this.$http.post(categories/${this.cateId}/attributes, { attr_name: this.addForm.attr_name,attr_sel: this.activeName})if (res.meta.status ! 201) return this.$msg.error(res.meta.msg)this.$msg.success(添加${this.titleText}成功)this.addDialogVisible falsethis.getParamsData()})},// 展示编辑参数对话框async showEditDialog(attrId) {const { data: res } await this.$http.get(categories/${this.cateId}/attributes/${attrId}, { params: { attr_sel: this.activeName } })if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(获取${this.titleText}成功)this.editForm res.datathis.editDialogVisible true},// 关闭编辑参数对话框editDialogClosed() {this.$refs.editFormRef.resetFields()},// 编辑商品参数editParams() {// 验证表单this.$refs.editFormRef.validate(async valid {if (!valid) return this.$msg.error(请填写正确的参数名称)const { data: res } await this.$http.put(categories/${this.cateId}/attributes/${this.editForm.attr_id}, { attr_name: this.editForm.attr_name,attr_sel: this.activeName})if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(添加${this.titleText}成功)this.editDialogVisible falsethis.getParamsData()})},// 删除商品参数async removeParams(attrId) {const confirm await this.$confirm(此操作将永久删除该${this.titleText}, 是否继续?, 提示, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning}).catch(e e);// 如果用户确认删除则返回值为字符串 confirm如果用户取消了删除则返回值为字符串 cancelconsole.log(confirm: , confirm);if (confirm ! confirm) returnconst { data: res } await this.$http.delete(categories/${this.cateId}/attributes/${attrId})if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(删除${this.titleText}成功)this.getParamsData()},// 保存参数可选项async saveAttrVals(row, attrVals, isAdd) {const { data: res } await this.$http.put(categories/${this.cateId}/attributes/${row.attr_id}, { attr_name: row.attr_name,attr_sel: this.activeName,attr_vals: attrVals})if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(${isAdd ? 添加 : 删除}${this.titleText}可选项成功)this.getParamsData()},// 删除参数可选项handleClose(row, i) {// 删除元素const attrVals [...row.attr_vals.slice(0, i), ...row.attr_vals.slice(i 1)].join( )console.log(attrVals: , attrVals, \ni: , i);this.saveAttrVals(row, attrVals, false)},// 展示添加参数可选项输入框showInput(row) {row.inputVisible true// 让文本框自动获得焦点// $nextTick 方法的作用就是当页面上元素被重新渲染之后才会指定回调函数中的代码this.$nextTick(_ {this.$refs.saveTagInput.$refs.input.focus();});},// handleInputConfirm(row) {if (row.inputValue.trim().length 0) {row.inputVisible falserow.inputValue return}// 添加元素const attrVals row.attr_vals.concat(row.inputValue.trim()).join( )console.log(attrVals: , attrVals);this.saveAttrVals(row, attrVals, true)}},// 计算属性computed: {// 选中的分类idcateId() {if (this.selectedCateKeys.length 3) return this.selectedCateKeys[2]return null},// 动态计算标题的文本titleText() {if (this.activeName many) {return 动态参数}return 静态属性}}
}
/script1、完成级联选择框完成商品分类级联选择框
2、展示参数展示动态参数数据以及静态属性数据
3、添加参数完成添加参数或属性
4、编辑参数完成编辑参数或属性
5、删除参数删除参数或属性
6、动态参数和静态属性管理
展示动态参数可选项动态参数可选项展示及操作在获取动态参数的方法中进行处理。添加/删除动态参数可选项展示静态属性可选项静态属性可选项展示及操作在获取动态参数的方法中进行处理。添加/删除静态属性可选项
注意当用户在级联选择框中选中了非三级分类时需要清空表格中数据
商品列表页
添加 goods/List.vue 子组件并在router.js中引入该组件并设置路由规则
绘制商品列表页基本结构
略详情参考如下代码
templatediv!-- 面包屑导航 --el-breadcrumb separator-classel-icon-arrow-rightel-breadcrumb-item :to{ path: /home/welcome }首页/el-breadcrumb-itemel-breadcrumb-item商品管理/el-breadcrumb-itemel-breadcrumb-item商品列表/el-breadcrumb-item/el-breadcrumb!-- 卡片 --el-card!-- 搜索与添加 --el-row :gutter20el-col :span8el-input placeholder请输入内容 v-model.trimqueryInfo.query clearable cleargetGoodsListel-button slotappend iconel-icon-search clickqueryGoodsList :disabledqueryInfo.query ? false : true/el-button/el-input/el-colel-col :span4el-button typeprimary clickgoAddPage添加商品/el-button/el-col/el-row!-- 用户列表 --el-table :datagoodsList stylewidth: 100% border stripeel-table-column typeindex label#/el-table-columnel-table-column propgoods_name label商品名称/el-table-columnel-table-column propgoods_price label商品价格元 width95/el-table-columnel-table-column propgoods_weight label商品重量 width70/el-table-columnel-table-column propadd_time label创建时间 width140template slot-scopescope{{scope.row.add_time | dateFormatter}}/template/el-table-columnel-table-column label操作 width130template slot-scopescopeel-button typeprimary iconel-icon-edit sizemini/el-buttonel-button typedanger iconel-icon-delete sizemini clickremoveById(scope.row.goods_id)/el-button/template/el-table-column/el-table!-- 分页 --el-paginationsize-changehandleSizeChangecurrent-changehandleCurrentChange:current-pagequeryInfo.pagenum:page-sizes[2, 3, 5, 10] :page-sizequeryInfo.pagesizelayouttotal, sizes, prev, pager, next, jumper:totaltotal background/el-paginationpre{{goodsList}}/pre/el-card/div
/template主要功能实现
script
export default {data() {return {// 获取商品列表接口参数queryInfo: {query: , // 搜索内容pagenum: 1, // 页面pagesize: 10 // 每页显示条数},// 商品列表数据goodsList: [],// 商品列表总条数total: 0}},created() {this.getGoodsList()},methods: {// 获取商品列表数据async getGoodsList() {const { data: res } await this.$http.get(goods, { params: this.queryInfo })if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.goodsList res.data.goodsthis.total res.data.totalthis.$msg.success(获取商品列表成功)},// 查询商品queryGoodsList() {this.queryInfo.pagenum 1this.getGoodsList()},// pagesize 改变handleSizeChange(size) {console.log(size: , size);this.queryInfo.pagesize sizeconst maxN parseInt(this.total / this.queryInfo.pagesize ) (this.total % this.queryInfo.pagesize 0 ? 1 : 0)this.queryInfo.pagenum this.queryInfo.pagenum maxN ? maxN : this.queryInfo.pagenumthis.getGoodsList()},// 页码值 改变handleCurrentChange(num) {console.log(num: , num);this.queryInfo.pagenum numthis.getGoodsList()},// 删除商品async removeById(gid) {const confirm await this.$confirm(此操作将永久删除该商品, 是否继续?, 提示, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning}).catch(e e);// 如果用户确认删除则返回值为字符串 confirm如果用户取消了删除则返回值为字符串 cancelconsole.log(confirm: , confirm);if (confirm ! confirm) returnconst { data: res } this.$http.delete(goods/ gid)if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(删除商品成功)this.getGoodsList()},// 添加商品goAddPage() {console.log(goAddPage);this.$router.push(/home/addGoods)}}
}
/script1、数据展示添加数据表格展示数据以及分页功能的实现,搜索功能的实现。在main.js中添加过滤器
Vue.filter(dateFormatter, (ov) {const date new Date(ov)const y date.getFullYear()const m (date.getMonth() 1 ).padStart(2, 0)const d (date.getDate() ).padStart(2, 0)const hh (date.getHours() ).padStart(2, 0)const mm (date.getHours() ).padStart(2, 0)const ss (date.getHours() ).padStart(2, 0)return ${y}-${m}-${d} ${hh}:${mm}:${ss}
})2、实现删除商品
3、添加商品添加编程式导航在List.vue中添加编程式导航并创建添加商品路由组件及规则
添加商品页
添加 goods/Add.vue 子组件并在router.js中引入该组件并设置路由规则。
绘制添加商品页基本结构
布局过程中需要使用Steps组件在element.js中引入并注册该组件并在global.css中给组件设置全局样式其他略……
templatediv!-- 面包屑导航 --el-breadcrumb separator-classel-icon-arrow-rightel-breadcrumb-item :to{ path: /home/welcome }首页/el-breadcrumb-itemel-breadcrumb-item商品管理/el-breadcrumb-itemel-breadcrumb-item添加商品/el-breadcrumb-item/el-breadcrumb!-- 卡片 --el-card!-- 警告 --el-alerttitle添加商品信息typeinfocentershow-icon :closablefalse/el-alert!-- 步骤条 --el-steps :space200 :activeactiveIndex * 1 align-center finish-statussuccessel-step title基本信息/el-stepel-step title商品参数/el-stepel-step title商品属性/el-stepel-step title商品图片/el-stepel-step title商品内容/el-stepel-step title完成/el-step/el-steps!-- 标签栏 --el-form :modeladdForm :rulesaddFormRules refaddFormRef label-width70px label-positiontopel-tabs v-modelactiveIndex tab-positionleft :before-leavebeforeTabLeave tab-clicktabClickedel-tab-pane label基本信息 name0el-form-item label商品名称 propgoods_nameel-input v-modeladdForm.goods_name/el-input/el-form-itemel-form-item label商品价格 propgoods_priceel-input v-modeladdForm.goods_price typenumber/el-input/el-form-itemel-form-item label商品重量 propgoods_weightel-input v-modeladdForm.goods_weight typenumber/el-input/el-form-itemel-form-item label商品数量 propgoods_numberel-input v-modeladdForm.goods_number typenumber/el-input/el-form-itemel-form-item label商品分类 propgoods_catel-cascader v-modeladdForm.goods_cat :optionscateList :propscateProps changehandleChange clearable/el-cascader/el-form-item/el-tab-paneel-tab-pane label商品参数 name1el-form-item v-for(v, i) in manyTableData :keyi :labelv.attr_nameel-checkbox-group v-modelv.attr_valsel-checkbox v-for(item, index) in v.attr_vals :keyindex :labelitem border/el-checkbox/el-checkbox-group/el-form-itempre{{manyTableData}}/pre/el-tab-paneel-tab-pane label商品属性 name2el-form-item v-for(v, i) in onlyTableData :keyi :labelv.attr_nameel-input v-modelv.attr_vals/el-input/el-form-itempre{{onlyTableData}}/pre/el-tab-paneel-tab-pane label商品图片 name3el-upload actionhttp://127.0.0.1:8888/api/private/v1/upload:on-previewhandlePreview:on-removehandleRemove :headersheaderObj :on-successhandleSuccesslist-typepictureel-button sizesmall typeprimary点击上传/el-button/el-upload/el-tab-paneel-tab-pane label商品内容 name4quill-editor v-modeladdForm.goods_introduce bluronEditorBlur/quill-editorel-button classbtnAdd typeprimary clickadd添加商品/el-button/el-tab-pane/el-tabs/el-form!-- 预览对话框 --el-dialogtitle图片预览:visible.syncpreviewVisiblewidth50%img classpreviewImg :srcpreviewPath alt/el-dialog/el-card/div
/template主要功能实现
script
import _ from lodash;export default {data() {return {activeIndex: 0,addForm: {goods_name: ,goods_price: ,goods_weight: ,goods_number: ,goods_cat: [],// 商品图片pics: [],// 描述goods_introduce: ,// 参数attrs: []},addFormRules: {goods_name: [{ required: true, message: 请输入商品名称, trigger: blur }], goods_price: [{ required: true, message: 请输入商品价格, trigger: blur }], goods_weight: [{ required: true, message: 请输入商品重量, trigger: blur }], goods_number: [{ required: true, message: 请输入商品数量, trigger: blur }],goods_cat: [{ required: true, message: 请选择商品分类, trigger: change }]},// 商品分类cateList: [],cateProps: {expandTrigger: hover,value: cat_id,label: cat_name,children: children},// 动态参数列表manyTableData: [],// 静态属性列表onlyTableData: [],// 请求头headerObj: { Authorization: window.sessionStorage.getItem(token) },// 是否展示预览图previewVisible: false,// 预览图片路径previewPath: }},created() {this.getCateList()},methods: {// 获取分类数据async getCateList() {const { data: res } await this.$http.get(categories, { params: { type: 3 } })if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(获取商品分类成功)this.cateList res.data},// 选择分类handleChange(v) {if (this.addForm.goods_cat.length ! 3) {this.addForm.goods_cat []return}console.log(handleChange value: , v);},// 标签页钩子函数beforeTabLeave(ai, oai) {console.log(ai: , ai, , oai: , oai);if (oai 0 this.addForm.goods_cat.length ! 3) {this.$msg.error(请选择商品分类)return false}},// 点击标签栏async tabClicked() {if (this.activeIndex 1) {const { data: res } await this.$http.get(categories/${this.cateId}/attributes, { params: { sel: many } })if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(获取动态参数成功)res.data.forEach(item {item.attr_vals item.attr_vals.length 0 ? item.attr_vals.split( ) : []});this.manyTableData res.data} else if (this.activeIndex 2) {const { data: res } await this.$http.get(categories/${this.cateId}/attributes, { params: { sel: only } })if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(获取动态参数成功)this.onlyTableData res.data}},// 点击预览图片handlePreview(file) {console.log(handlePreview: , file);this.previewPath file.response.data.urlthis.previewVisible true},// 点击删除图片handleRemove(file, fileList) {// console.log(handleRemove:\nfile: , file, \nfileList: , fileList);const index this.addForm.pics.findIndex(v v.pic file.response.data.tmp_path)if (index ! -1) this.addForm.pics.splice(index, 1)console.log(addForm: , this.addForm);},// 上传文件成功handleSuccess(response, file, fileList) {// console.log(handleSuccess:\nresponse: , response, \nfile: , file, \nfileList: , fileList);this.addForm.pics.push({ pic: response.data.tmp_path })console.log(addForm: , this.addForm);},// 富文本编辑器失去焦点onEditorBlur() {console.log(content: , this.addForm.goods_introduce);},// 添加商品add() {this.$refs.addFormRef.validate(async valid {if (!valid) return this.$msg.error(请填写必要的表单项)// lodash 深拷贝const addForm _.cloneDeep(this.addForm)// 处理分类数据addForm.goods_cat addForm.goods_cat.join(,)// 处理动态参数this.manyTableData.forEach(item {const newInfo {attr_id: item.attr_id,attr_value: item.attr_vals.join( )}addForm.attrs.push(newInfo)});// 处理静态属性this.onlyTableData.forEach(item {const newInfo {attr_id: item.attr_id,attr_value: item.attr_vals}addForm.attrs.push(newInfo)});console.log(addForm: , addForm);// 发起请求const { data: res } await this.$http.post(goods, addForm)if (res.meta.status ! 201) this.$msg.error(res.meta.msg)this.$msg.success(添加商品成功)this.$router.push(/home/goods)})}},computed: {cateId() {if (this.addForm.goods_cat.length 3) return this.addForm.goods_cat[2]return null}}
}
/script1、添加tab栏切换验证也就是说不输入某些内容无法切换到别的tab栏
2、展示信息展示商品参数信息、商品属性信息在商品参数信息展示中使用的el-checkbox,el-checkbox-group组件打开element.js引入组件并注册组件
3、完成图片上传使用upload组件完成图片上传在element.js中引入upload组件并注册。因为upload组件进行图片上传的时候并不是使用axios发送请求所以需要手动为上传图片的请求添加token即为upload组件添加headers属性
4、使用富文本插件想要使用富文本插件vue-quill-editor就必须先从依赖安装该插件引入并注册vue-quill-editor
5、添加商品完成添加商品的操作在添加商品之前为了避免goods_cat数组转换字符串之后导致级联选择器报错需要打开vue控制条点击依赖安装lodash把addForm进行深拷贝
订单列表页
创建订单列表路由组件并添加路由规则。
绘制订单列表页基本结构
略详情参考如下代码
templatediv!-- 面包屑导航 --el-breadcrumb separator-classel-icon-arrow-rightel-breadcrumb-item :to{ path: /home/welcome }首页/el-breadcrumb-itemel-breadcrumb-item订单管理/el-breadcrumb-itemel-breadcrumb-item订单列表/el-breadcrumb-item/el-breadcrumb!-- 卡片 --el-card!-- 搜索与添加 --el-row :gutter20el-col :span8el-input placeholder请输入内容 v-model.trimqueryInfo.query clearable cleargetOrderListel-button slotappend iconel-icon-search clickqueryOrderList :disabledqueryInfo.query ? false : true/el-button/el-input/el-col/el-row!-- 用户列表 --el-table :dataorderList stylewidth: 100% border stripeel-table-column typeindex label#/el-table-columnel-table-column proporder_number label订单编号/el-table-columnel-table-column proporder_price label订单价格/el-table-columnel-table-column proporder_pay label是否付款template slot-scopescopeel-tag typedanger v-ifscope.row.pay_status 0未付款/el-tagel-tag typesuccess v-else已付款/el-tag/template/el-table-columnel-table-column propis_send label是否发货/el-table-columnel-table-column propcreate_time label下单时间template slot-scopescope{{scope.row.create_time | dateFormatter}}/template/el-table-columnel-table-column label操作template slot-scopescopeel-button typeprimary iconel-icon-edit sizemini clickaddressVisible true/el-buttonel-button typesuccess iconel-icon-location sizemini clickshowProgressBox(scope.row.order_number)/el-button/template/el-table-column/el-table!-- 分页 --el-paginationsize-changehandleSizeChangecurrent-changehandleCurrentChange:current-pagequeryInfo.pagenum:page-sizes[2, 3, 5, 10] :page-sizequeryInfo.pagesizelayouttotal, sizes, prev, pager, next, jumper:totaltotal background/el-paginationpre{{orderList}}/pre/el-card!-- 修改地址对话框 --el-dialog title添加商品分类 :visible.syncaddressVisible width50% closeaddressDialogClosedel-form :modeladdressForm :rulesaddressFormRules refaddressFormRef label-width120pxel-form-item label省市区/县 propaddress1el-cascader v-modeladdressForm.address1 :optionscityData clearable/el-cascader/el-form-itemel-form-item label详细地址 propaddress2el-input v-modeladdressForm.address2/el-input/el-form-item/el-formspan slotfooter classdialog-footerel-button clickaddressVisible false取 消/el-buttonel-button typeprimary clickaddressConfirm确 定/el-button/span/el-dialog!-- 物流进度对话框 --el-dialog title物流进度 :visible.syncprogressVisible width50%el-timelineel-timeline-itemv-for(activity, index) in progressInfo:keyindex:colorindex 0 ? #00ff00 : :timestampactivity.time{{activity.context}}/el-timeline-item/el-timeline/el-dialog/div
/template主要功能实现
script
import cityData from ./citydata.jsexport default {data() {return {queryInfo: {query: ,pagenum: 1,pagesize: 10},total: 0,// 订单列表orderList: [],// 省市区/县数据cityData,// 级联选择器属性cascaderProps: {expandTrigger: hover},// 修改地址对话框addressVisible: false,addressForm: {address1: [],address2: },addressFormRules: {address1: [{ required: true, message: 请选择省市区县, trigger: change }],address2: [{ required: true, message: 请填写详细地址, trigger: blur }]},// 物流进度对话框progressVisible: false,// 物流进度数据progressInfo: []}},created() {this.getOrderList()},methods: {// 获取订单列表async getOrderList() {const { data: res } await this.$http.get(orders, { params: this.queryInfo })if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(获取订单列表成功)this.orderList res.data.goodsthis.total res.data.total},// 查询订单列表queryOrderList() {this.queryInfo.pagenum 1this.getOrderList()},// pagesize 改变handleSizeChange(size) {console.log(size: , size);this.queryInfo.pagesize sizeconst maxN parseInt(this.total / this.queryInfo.pagesize ) (this.total % this.queryInfo.pagesize 0 ? 1 : 0)this.queryInfo.pagenum this.queryInfo.pagenum maxN ? maxN : this.queryInfo.pagenumthis.getOrderList()},// 页码值 改变handleCurrentChange(num) {console.log(num: , num);this.queryInfo.pagenum numthis.getOrderList()},// 关闭修改地址对话框addressDialogClosed() {// console.log(addressForm: , this.addressForm);this.$refs.addressFormRef.resetFields()},// 修改地址addressConfirm() {// console.log(addressForm: , this.addressForm);this.addressVisible false},// 展示物流进度对话框async showProgressBox(orderNumber) {// const { data: res } await this.$http.get(kuaidi/ orderNumber)// if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)// this.$msg.success(获取物流进度成功)// this.progressInfo res.dataconst data [{time: 2018-05-10 09:39:00,ftime: 2018-05-10 09:39:00,context: 已签收,感谢使用顺丰,期待再次为您服务,location: },{time: 2018-05-10 08:23:00,ftime: 2018-05-10 08:23:00,context: [北京市]北京海淀育新小区营业点派件员 顺丰速运 95338正在为您派件,location: },{time: 2018-05-10 07:32:00,ftime: 2018-05-10 07:32:00,context: 快件到达 [北京海淀育新小区营业点],location: },{time: 2018-05-10 02:03:00,ftime: 2018-05-10 02:03:00,context: 快件在[北京顺义集散中心]已装车,准备发往 [北京海淀育新小区营业点],location: },{time: 2018-05-09 23:05:00,ftime: 2018-05-09 23:05:00,context: 快件到达 [北京顺义集散中心],location: },{time: 2018-05-09 21:21:00,ftime: 2018-05-09 21:21:00,context: 快件在[北京宝胜营业点]已装车,准备发往 [北京顺义集散中心],location: },{time: 2018-05-09 13:07:00,ftime: 2018-05-09 13:07:00,context: 顺丰速运 已收取快件,location: },{time: 2018-05-09 12:25:03,ftime: 2018-05-09 12:25:03,context: 卖家发货,location: },{time: 2018-05-09 12:22:24,ftime: 2018-05-09 12:22:24,context: 您的订单将由HLA北京海淀区清河中街店门店安排发货。,location: },{time: 2018-05-08 21:36:04,ftime: 2018-05-08 21:36:04,context: 商品已经下单,location: }]this.progressInfo JSON.parse(data)this.progressVisible true}}
}
/script1、实现数据展示及分页
2、制作省市区/县联动制作 citydata.js 数据文件放到到components/order文件夹中然后导入citydata.js文件
3、制作物流进度对话框因为使用的是element-ui中提供的Timeline组件所以需要导入并注册组件
数据统计页
创建数据统计路由组件并添加路由规则。
导入ECharts并使用具体实现如下
templatediv!-- 面包屑导航 --el-breadcrumb separator-classel-icon-arrow-rightel-breadcrumb-item :to{ path: /home/welcome }首页/el-breadcrumb-itemel-breadcrumb-item数据统计/el-breadcrumb-itemel-breadcrumb-item数据报表/el-breadcrumb-item/el-breadcrumb!-- 卡片 --el-carddiv idmain stylewidth: 750px; height:400px;/div/el-card/div
/templatescript
// 只会导出export default mutations这个默认的对象返回
// import echarts from echarts// 将 若干export导出的内容组合成一个对象返回
import * as echarts from echartsimport _ from lodashexport default {data() {return {options: {title: {text: 用户来源},tooltip: {trigger: axis,axisPointer: {type: cross,label: {backgroundColor: #E9EEF3}}},grid: {left: 3%,right: 4%,bottom: 3%,containLabel: true},xAxis: [{boundaryGap: false}],yAxis: [{type: value}]}}},async mounted() {const { data: res } await this.$http.get(reports/type/1)if (res.meta.status ! 200) return this.$msg.error(res.meta.msg)this.$msg.success(获取折线图数据成功)// 初始化var myChart echarts.init(document.getElementById(main))// 设置配置项myChart.setOption(_.merge(this.options, res.data))}
}
/script