在原视频中,老师跳过了这个功能,我觉得自己去实现也可以锻炼自己,于是自己补充了编辑功能

  1. 同用户管理,权限管理等之前各个模块的编辑功能不同,因为商品具有很多可编辑的选项,所以选择像添加商品一样,单独放在一个组件中Edit.vue
  2. 不过相比于添加商品,还需要传递一下这个商品的id值
  3. 布局与添加商品一致(下文省略解释布局),只是需要发送请求,将后台返回的数据渲染到组件中

1. 初步设置

  • 设置路由规则
  • 传递商品id到Edit.vue

router/index.js中:

 { path: '/goods/edit/:id', component: Edit }

Edit.vue中:

 data () {return {// 传递过来的 商品idid: this.$route.params.id}}

List.vue中:

 // 点击编辑按钮,跳转到编辑页面editById (id) {this.$router.push('/goods/edit/' + id)}

2. 获取数据

1. 查询商品信息

async getGoodsInfo () {const { data: res } = await this.$http.get('goods/' + this.id)if (res.meta.status !== 200) {return this.$message.error('获取商品信息失败!')}this.editForm = res.datathis.$message.success('获取商品信息成功!')}

2. 获取商品分类数据

// 获取所有商品分类数据async getCateList () {const { data: res } = await this.$http.get('categories')if (res.meta.status !== 200) {return this.$message.error('获取商品分类数据失败!')}this.cateList = res.data}

3. 获取商品参数列表和静态属性

// 当切换tab页签时触发的函数async tabClicked () {// console.log(this.activeIndex)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.$message.error('获取动态参数列表失败!')}console.log(res.data)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.$message.error('获取静态属性列表失败!')}console.log(res.data)this.onlyTableData = res.data}}

3. 关于数据和图片的回显

1. 级联选择器数据回显

在getGoodsInfo ()这个函数中加入以下代码:

// 设置级联选择器绑定值const tempList = res.data.goods_cat.split(',') // 这一步只是转化成了['1','3','6']//每个数组成员都是字符,而不是数字// 这里必须重新赋值为空数组,再赋值,否则v-model不能实现默认值回显this.editForm.goods_cat = []tempList.forEach(item => {// item - 0是把数据类型转换为数字,以与cateList 数据类型一致,否则不能正确回显默认值this.editForm.goods_cat.push(item - 0)})

功能实现:

2. 点击编辑后图片回显

查询文档得知有一个属性file-list:


则进行绑定:

 <el-tab-pane label="商品图片" name="3"><!-- action表示图片要上传到的后台api地址 --><el-upload:action="uploadURL":on-preview="handlePreview":on-remove="handleRemove"list-type="picture":headers="headerObj":file-list="uploadedList":on-success="handleSuccess"><el-button size="small" type="primary">点击上传</el-button></el-upload></el-tab-pane>

最后,在getGoodsInfo ()这个函数中,循环editForm.pics中的每一项,把带有name和url属性的对象push到data节点下的picList

// 将已上传的图片放入列表
this.editForm.pics.forEach(item => {const obj ={name: item.pics_id + '.jpg',url: item.pics_sma_url}this.uploadedList.push(obj)})

查阅了官方文档发现,有name属性,才能够点击到图片名字,从而有预览效果

4. 编辑完成后点击提交按钮

文档里面是不需要传递分类id的,但是通过请求得到的信息“该商品未设置分类”,推测需要传递商品的分类id,并且类型是一个包括每一级分类,且用逗号“,”分割的字符串

// 点击修改商品按钮edit () {this.$refs.editFormRef.validate(async valid => {if (!valid) {return this.$message.error('请填写必要的表单项!')}const form = _.cloneDeep(this.editForm)form.goods_cat = form.goods_cat.join(',')//  console.log(form)const { data: res } = await this.$http.put('goods/' + form.goods_id, form)if (res.meta.status !== 200) {return this.$message.error('修改商品失败!')}this.$message.success('修改商品成功!')this.$router.push('/goods')})}

编辑功能其实还差商品参数和静态属性还没完全弄好,经过了很久的尝试之后,我猜测后台有一些不周全的地方

  1. 如果一个商品是新添加的,那么我根据id查询得到的商品信息的参数/属性是以 空格 为分隔符的字符串
  2. 而如果是数据库中本来就存在的商品,我点击编辑按钮,通过id查询得到的信息的参数/属性 是以 逗号","为分隔符的字符串

加上我对elementui使用不熟练,目前,还无法完全实现这个功能,等日后有时间再进行完善。目前的进度,是能够做到成功修改商品基本信息,商品图片,商品描述三个部分。

Edit.vue完整代码如下:

<template><div><!-- 面包屑导航区域 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item><el-breadcrumb-item>商品管理</el-breadcrumb-item><el-breadcrumb-item>编辑商品</el-breadcrumb-item></el-breadcrumb><!-- 卡片视图区域 --><el-card><!-- 提示区域 --><el-alerttitle="修改商品信息" type="info" center show-icon :closable="false"></el-alert><!-- 步骤条区域 --><el-steps :space="200" :active="activeIndex-0" finish-status="success" align-center><el-step title="基本信息"></el-step><el-step title="商品参数"></el-step><el-step title="商品属性"></el-step><el-step title="商品图片"></el-step><el-step title="商品内容"></el-step><el-step title="完成"></el-step></el-steps><el-form :model="editForm" :rules="editFormRules"ref="editFormRef" label-width="100px"label-position="top"><!-- Tab栏区域 --><el-tabs :tab-position="'left'":before-leave="beforeTabLeave"@tab-click="tabClicked"v-model="activeIndex"><el-tab-pane label="基本信息" name="0"><el-form-item label="商品名称"prop="goods_name"><el-input v-model="editForm.goods_name"></el-input></el-form-item><el-form-item label="商品价格"prop="goods_price"><el-input v-model="editForm.goods_price"type="number"></el-input></el-form-item><el-form-item label="商品重量"prop="goods_weight"><el-input v-model="editForm.goods_weight"type="number"></el-input></el-form-item><el-form-item label="商品数量"prop="goods_number"><el-input v-model="editForm.goods_number"type="number"></el-input></el-form-item><el-form-item label="商品分类" prop="goods_cat"><el-cascader:show-all-levels="true"v-model="editForm.goods_cat":options="cateList"expand-trigger="hover":props="cateProps"@change="handleChange"></el-cascader></el-form-item></el-tab-pane><el-tab-pane label="商品参数" name="1" ><!-- 渲染表单的item项 --><el-form-item v-for="item in manyTableData":key="item.attr_id" :label="item.attr_name"><!-- 复选框组 --><el-checkbox-group v-model="item.attr_vals"><el-checkbox :label="cb" borderv-for="(cb,i) in item.attr_vals":key="i"></el-checkbox></el-checkbox-group></el-form-item></el-tab-pane><el-tab-pane label="商品属性" name="2"><el-form-item :label="item.attr_name"v-for="item in onlyTableData":key="item.attr_id"><el-input v-model="item.attr_vals"></el-input></el-form-item></el-tab-pane><el-tab-pane label="商品图片" name="3"><!-- action表示图片要上传到的后台api地址 --><el-upload:action="uploadURL":on-preview="handlePreview":on-remove="handleRemove"list-type="picture":headers="headerObj":file-list="uploadedList":on-success="handleSuccess"><el-button size="small" type="primary">点击上传</el-button></el-upload></el-tab-pane><el-tab-pane label="商品内容" name="4"><!-- 富文本编辑器组件 --><quill-editor v-model="editForm.goods_introduce"></quill-editor><el-button type="primary" class="btnAdd"@click="edit">修改商品</el-button></el-tab-pane></el-tabs></el-form></el-card><!-- 图片预览 --><el-dialog title="图片预览":visible.sync="previewVisible" width="50%"><img :src="previewPath" alt="" class="previewImg"></el-dialog></div>
</template><script>
import _ from 'lodash'export default {data () {return {// 传递过来的 商品idid: this.$route.params.id,// 激活的步骤activeIndex: '0',// 修改商品的表单数据对象editForm: {goods_name: '',goods_price: 0,goods_weight: 0,goods_number: 0,// 商品所属的分类数组goods_cat: [],// 图片的数组pics: [],// 商品的详情描述goods_introduce: '',attrs: []},editFormRules: {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: 'blur' }]},// 分类列表cateList: [],cateProps: {label: 'cat_name',value: 'cat_id',children: 'children'},// 已经上传了的图片列表uploadedList: [],// 动态参数列表manyTableData: [],// 静态属性列表onlyTableData: [],// 上传图片的url地址uploadURL: 'http://127.0.0.1:8889/api/private/v1/upload',// 图片上传组件的 headers请求头对象headerObj: {Authorization: window.sessionStorage.getItem('token')},previewPath: '',previewVisible: false}},created () {this.getGoodsInfo()this.getCateList()},methods: {// 发送请求,查询商品信息async getGoodsInfo () {const { data: res } = await this.$http.get('goods/' + this.id)if (res.meta.status !== 200) {return this.$message.error('获取商品信息失败!')}this.editForm = res.data// 设置级联选择器绑定值const tempList = res.data.goods_cat.split(',')// 这里必须重新赋值为空数组,再赋值,否则v-model不能实现默认值回显this.editForm.goods_cat = []tempList.forEach(item => {// item - 0是把数据类型转换为数字,以与cateList 数据类型一致,否则不能正确回显默认值this.editForm.goods_cat.push(item - 0)})this.editForm.pics.forEach(item => {const obj ={name: item.pics_id + '.jpg',url: item.pics_sma_url}this.uploadedList.push(obj)})this.$message.success('获取商品信息成功!')},// 获取所有商品分类数据async getCateList () {const { data: res } = await this.$http.get('categories')if (res.meta.status !== 200) {return this.$message.error('获取商品分类数据失败!')}this.cateList = res.data},// 级联选择器选中项发生变化时,触发的函数handleChange () {// console.log(this.editFrom.goods_cat)if (this.editForm.goods_cat.length !== 3) {// 没有选中三级商品分类this.editForm.goods_cat = []}},beforeTabLeave (activeName, oldActiveName) {if (oldActiveName === '0' &&this.editForm.goods_cat.length !== 3) {this.$message.error('请先选择商品分类!')return false}},// 当切换tab页签时触发的函数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.$message.error('获取动态参数列表失败!')}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.$message.error('获取静态属性列表失败!')}this.onlyTableData = res.data}},// 处理图片预览效果handlePreview (file) {// console.log(file)if (file.response) {this.previewPath = file.response.data.url} else {this.previewPath = file.url}this.previewVisible = true},// 处理移除图片的操作handleRemove (file) {if (file.response) {// 如果存在file.response,则是之后上传的const filePath = file.response.data.tmp_pathconst i = this.editForm.pics.findIndex(x =>x.pic === filePath)this.editForm.pics.splice(i, 1)} else {// 则是一开始就有图片const Url = file.urlconst i = this.editForm.pics.findIndex(x =>x.pics_sma_url === Url)this.editForm.pics.splice(i, 1)}},// 监听图片上传成功的事件handleSuccess (response) {// 1. 拼接得到一个图片信息对象const picInfo = { pic: response.data.tmp_path }// 2.将图片信息对象,push到pics数组中this.editForm.pics.push(picInfo)},// 点击修改商品按钮edit () {this.$refs.editFormRef.validate(async valid => {if (!valid) {return this.$message.error('请填写必要的表单项!')}const form = _.cloneDeep(this.editForm)form.goods_cat = form.goods_cat.join(',')// console.log(form)const { data: res } = await this.$http.put('goods/' + form.goods_id, form)console.log(res)if (res.meta.status !== 200) {return this.$message.error('修改商品失败!')}this.$message.success('修改商品成功!')this.$router.push('/goods')})}},computed: {cateId () {if (this.editForm.goods_cat.length === 3) {return this.editForm.goods_cat[2]}return null}}
}
</script><style lang="less" scoped>.el-checkbox {margin:0 10px 0 0 !important}.previewImg {width: 100%;}.btnAdd {margin-top:15px;}
</style>

ps : 在List.vue中要记得向编辑页面传参:

9.1黑马Vue电商后台管理系统商品管理模块完善:编辑商品的功能相关推荐

  1. 10.1 黑马Vue电商后台管理系统之完善订单管理模块--加入修改订单模块

    效果如下: 实现如下: 1.我仍然保留了添加地址这一个对话框,但只是绑定在另一个按钮上面,而点击左侧第一个按钮就会跳转到"修改订单"模块 <template v-slot=& ...

  2. 10.2 黑马Vue电商后台管理系统 完善订单模块--搜索订单(修改后端)

    效果如下: 搜索时列表动态变化,在我专栏下另一篇文章写了,这篇文章不再讲述,这篇文章只讲述如何从后端(打开vue_api_server这个文件夹,而不是vue_shop)修改代码来实现这个功能 我的思 ...

  3. Vue电商后台管理系统(1)

    Vue电商后台管理系统(1) 登录 在components文件夹下创建登录组件,Login.vue,并快速生成template.script和style骨架. 配置路由,进入router文件夹,导入L ...

  4. Vue电商后台管理系统项目开发实战(一)

    前言 当下根据不同的应用场景,电商系统一般都提供了PC端,移动APP,移动Web,微信等多种访问方式.如下图. 不同的客户端共用同一个服务器,数据库,API.本次项目着重设计PC后台管理,供电商后台管 ...

  5. Axure电商后台业务管理系统原型模板/通用版电商后台管理系统/订单管理/营销管理/运营管理/财务管理/统计分析/库存管理/流量统计/运营管理/用户管理/秒杀促销/交易统计/活动管理/广告管理

    Axure电商后台业务管理系统原型模板/通用版电商后台管理系统/订单管理/营销管理/运营管理/财务管理/统计分析/库存管理/流量统计/运营管理/用户管理/秒杀促销/交易统计/活动管理/广告管理 作品名 ...

  6. Vue项目实战之电商后台管理系统(二) 主页模块

    前言 目录 前言 一.主页布局 1.1 整体布局 1.2 头部区域布局 1.3 左侧菜单布局 1.3.1 静态布局 1.3.2 通过axios请求拦截器来进行权限验证 1.3.3 通过axios获取左 ...

  7. 关于黑马-Vue电商后台项目管理(2)

    2.2 后台项目的环境安装配置 安装MySQL数据库 关于数据库文件,黑马教程有提供一个叫phpstudy的软件,可以按照视频流程进行配置,但是之后可能会经常出现在该软件无法启动mysql.因此我们这 ...

  8. vue电商后台管理系统--订单管理篇

    渲染订单table表格 <!-- 订单列表数据 --><el-table :data="orderList" border stripe><el-ta ...

  9. 电商后台管理系统订单列表模块

    一 代码 1 新建 Order.vue 组件 <template><div><!-- 面包屑导航区 --><el-breadcrumb separator-c ...

最新文章

  1. css3媒体查询实现网站响应式布局
  2. git idea 可视化_那些你应该知道的,但是你一定不知道的 Git 骚操作
  3. 使用VMware桥接模式组建局域网测试MSMQ(二)
  4. 非root用户挂载NFS
  5. nofollow标签_如何Nofollow外链
  6. 如何控制油门更准确?
  7. mysql rr 更新失败_RR 级别下 update 操作的是快照读还是当前读?
  8. ECMall2.x模板制作入门系列之2(模板标签/语法)
  9. 八千字长文深度解读,迁移学习在强化学习中的应用及最新进展
  10. navicat produsts注册机出现Generate First a serial
  11. android平板用office,现在可以在 Android 平板上使用你所喜爱的 Office 应用程序了...
  12. 曾经的荣誉,偶然被唤醒
  13. access中本年度的四月一日_《四月一日灵异事件簿》一部打工人的励志故事,哈哈哈~(诙谐,温馨,人性,可爱,悬疑,友情,羁绊)...
  14. 网页开发工具VSCode的使用
  15. 两种方法实现轮播图效果
  16. IKVM.NET的妙手偶得
  17. 【机器学习】机器学习常见符号
  18. SylixOS x86 HPET 定时器驱动
  19. Delphi ...开源!
  20. python编译型语言和解释型语言

热门文章

  1. Ada语言中命令行使用
  2. 用计算机录节目,如何在电脑上录制电视节目?高清稳定的录制方法分享
  3. 高清录屏去噪方法?--QVE屏幕录制
  4. 简单工厂模式代码示例
  5. 张量梯度求导公式总结
  6. 111111112222222333333
  7. 7.3布朗运动-轨道的基本性质
  8. Lambda表达式(λ表达式)
  9. PHP程序员及网站设计师职业要求
  10. 大公司VS小公司,怎样选择更有前途?