• HM后台(五)


    一,商品管理的商品列表页面搭建

     1.1,商品列表组件路由配置

    import List from '@/views/Goods/List'
     {
        path: '/home',
        component: Home,
        // 重定向
        redirect: '/welcome',
        children: [
          { path: '/welcome', component: Welcome },
          { path: '/users', component: User },
          { path: '/rights', component: Rights },
          { path: '/roles', component: Roles },
          { path: '/categories', component: Cate },
          { path: '/params', component: Params },
          { path: '/goods', component: List },
        ]
      }

    1.2,页面渲染时,发送请求,获取商品列表数据

    请求参数

    请求参数定义

      data() {
        return {
          // 查询参数对象
          queryInfo: {
            query: '',
            pagenum: 1,
            pagesize: 10
          },
          // 商品列表
          goodslist: [],
          // 总数据条数
          total: 0
        }
     mounted() {
        this.getGoodsList()
      },
    
      methods: {
        async getGoodsList() {
          const { data: res } = await this.$http.get('goods', {
            params: this.queryInfo
          })
    
          if (res.meta.status !== 200) {
            return this.$message.error('获取商品列表失败!')
          }
    
          this.$message.success('获取商品列表成功!')
          console.log(res.data)
          this.goodslist = res.data.goods
          this.total = res.data.total
        }
      }

    数据页面填充

    <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 style="margin-top:20px">
          <!-- 搜索框 -->
          <el-row :gutter="20">
            <el-col :span="8">
              <el-input
                placeholder="请输入内容"
                v-model="queryInfo.query"
                clearable
              >
                <el-button slot="append" icon="el-icon-search"></el-button>
              </el-input>
            </el-col>
            <el-col :span="4">
              <el-button type="primary">添加商品</el-button>
            </el-col>
          </el-row>
    
          <!-- 商品表格 -->
          <el-table :data="goodslist" border stripe style="margin:20px 0">
            <el-table-column type="index"></el-table-column>
            <el-table-column label="商品名称" prop="goods_name"></el-table-column>
            <el-table-column label="商品价格(元)" prop="goods_price" width="95px"></el-table-column>
            <el-table-column label="商品重量" prop="goods_weight" width="70px"></el-table-column>
            <el-table-column label="创建时间" prop="add_time" width="140px"></el-table-column>
            <el-table-column label="操作" width="130px">
              <template slot-scope="{row, $index}">
                <el-button type="primary" icon="el-icon-edit" size="mini"></el-button>
                <el-button type="danger" icon="el-icon-delete" size="mini" ></el-button>
              </template>
            </el-table-column>
          </el-table>
          
        </el-card>
      </div>
    </template>

    1.3,此时我们看到创建时间是个时间戳,我们需要将他过滤成标准的日期时间,需要用到vue的filter过滤器

    在main.js中全局注册过滤器,originVal接收传过来的时间戳参数(row.add_time),过滤器的名称dateFormat

    // 时间过滤器
    Vue.filter('dateFormat', function(originVal) {
      const dt = new Date(originVal)
      const y = dt.getFullYear()
      const m = dt.getMonth() + 1
      const d = dt.getDate()
      const hh = dt.getHours()
      const mm = dt.getMinutes()
      const ss = dt.getSeconds()
      return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
    })

    然后在表格日期列,用插值法填充

     <!-- 商品表格 -->
          <el-table :data="goodslist" border stripe style="margin:20px 0">
            <el-table-column type="index"></el-table-column>
            <el-table-column label="商品名称" prop="goods_name"></el-table-column>
            <el-table-column label="商品价格(元)" prop="goods_price" width="95px"></el-table-column>
            <el-table-column label="商品重量" prop="goods_weight" width="70px"></el-table-column>
            <el-table-column label="创建时间"  width="140px">
              <template slot-scope="{row, $index}">
                {{row.add_time | dateFormat}}
               
              </template>
            </el-table-column>

    1.4,分页器页面搭建

    <!-- 分页区域 -->
          <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" 
          :current-page="queryInfo.pagenum" :page-sizes="[5, 10, 15, 20]" 
          :page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total" background>
          </el-pagination>
      handleSizeChange(newSize) {
          this.queryInfo.pagesize = newSize
          this.getGoodsList()
        },
        handleCurrentChange(newPage) {
          this.queryInfo.pagenum = newPage
          this.getGoodsList()
        },

    1.5,搜索框搜索关键字,重新发送请求,获取商品数据,点击清空按钮,重新发送请求,获取数据

    <!-- 搜索框 -->
          <el-row :gutter="20">
            <el-col :span="8">
              <el-input
                placeholder="请输入内容"
                v-model="queryInfo.query"
                clearable
                @clear="getGoodsList"
              >
                <el-button slot="append" icon="el-icon-search" @click="getGoodsList"></el-button>
              </el-input>
            </el-col>

    1.5,点击删除按钮,删除该商品

    <el-table-column label="操作" width="130px">
              <template slot-scope="{row, $index}">
                <el-button type="primary" icon="el-icon-edit" size="mini"></el-button>
                <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeById(row.goods_id)" ></el-button>
              </template>
            </el-table-column>
    // 点击删除按钮
        async removeById(id) {
          const confirmResult = await this.$confirm(
            '此操作将永久删除该商品, 是否继续?',
            '提示',
            {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }
          ).catch(err => err)
    
          if (confirmResult !== 'confirm') {
            return this.$message.info('已经取消删除!')
          }
    
          const { data: res } = await this.$http.delete(`goods/${id}`)
    
          if (res.meta.status !== 200) {
            return this.$message.error('删除失败!')
          }
    
          this.$message.success('删除成功!')
          // 重新发送请求,获取新数据
          this.getGoodsList()
        },

    1.6.点击添加商品按钮,跳转到add组件,配置下路由对象

    <!-- 搜索框 -->
          <el-row :gutter="20">
            <el-col :span="8">
              <el-input
                placeholder="请输入内容"
                v-model="queryInfo.query"
                clearable
                @clear="getGoodsList"
              >
                <el-button slot="append" icon="el-icon-search" @click="getGoodsList"></el-button>
              </el-input>
            </el-col>
            <el-col :span="4">
              <el-button type="primary"  @click="goAddpage">添加商品</el-button>
            </el-col>
          </el-row>
     // 点击添加商品按钮,跳转到add组件
         goAddpage() {
          this.$router.push('/goods/add')
        }

    路由配置

    import Add from '@/views/Goods/Add'
      {
        path: '/home',
        component: Home,
        // 重定向
        redirect: '/welcome',
        children: [
          { path: '/welcome', component: Welcome },
          { path: '/users', component: User },
          { path: '/rights', component: Rights },
          { path: '/roles', component: Roles },
          { path: '/categories', component: Cate },
          { path: '/params', component: Params },
          { path: '/goods', component: List },
          { path: '/goods/add', component: Add },
        ]
      }

    二,add添加商品组件页面搭建

     active是nunber类型

        <!-- 面包屑导航区域 -->
        <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 style="margin: 20px 0">
          <el-alert title="添加商品信息" type="info" show-icon> </el-alert>
    
          <!-- 进度条 -->
          <el-steps :space="200" :active="0" finish-status="success" align-center style="margin: 15px 0">
            <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-card>

    2.1,左边选项卡页面

     

    我们需要实现一个功能,数据联动效果,当点击左边选项卡第三项,顶部的进度条就在第三个,如何实现这个效果呢

    el-tabs中的v-model记录的是el-tab-pane的name值(string), 

    而在el-teps中的active记录的是el-step的激活的值(number),0,1,2,3

    此时只需要将v-modle中的值和active的值关联起来即可实现联动效果了

     在data中动态定义一个属性

    data() {
        return {
          activeIndex:'0'
        }
      <!-- tabs栏区域 -->
          <el-tabs tab-position="left" v-model="activeIndex" style="height: 200px;">
            <el-tab-pane label="基本信息"  name="0">基本信息</el-tab-pane>
            <el-tab-pane label="商品参数"  name="1">商品参数</el-tab-pane>
            <el-tab-pane label="商品属性"  name="2">商品属性</el-tab-pane>
            <el-tab-pane label="商品图片"  name="3">商品图片</el-tab-pane>
            <el-tab-pane label="商品内容"  name="4">商品内容</el-tab-pane>
          </el-tabs>

    我们然后在el-steps改造下,将字符串变成number类型

    <!-- 进度条 -->
          <el-steps :space="200" :active="activeIndex - 0" finish-status="success" align-center style="margin: 15px 0">
            <el-step title="基本信息"></el-step>
            <el-step title="商品参数"></el-step>

    2.2,在左边的选项卡的基本信息项,是一个form验证表单,只能将el-form包裹着el-teps, 然后将el-tab-pane包裹着el-form-item

     addForm的属性不能乱填,需要根据接口的参数来定

    <!-- tabs栏区域 -->
          <el-form
            :model="addForm"
            :rules="addFormRules"
            ref="addFormRef"
            label-width="100px"
            label-position="top"
          >
            <el-tabs
              tab-position="left"
              v-model="activeIndex"
            
            >
              <el-tab-pane label="基本信息" name="0">
                <el-form-item label="商品名称" prop="goods_name">
                  <el-input v-model="addForm.goods_name"></el-input>
                </el-form-item>
                <el-form-item label="商品价格" prop="goods_price">
                  <el-input v-model="addForm.goods_price" type="number"></el-input>
                </el-form-item>
                <el-form-item label="商品重量" prop="goods_weight">
                  <el-input v-model="addForm.goods_weight" type="number"></el-input>
                </el-form-item>
                <el-form-item label="商品数量" prop="goods_number">
                  <el-input v-model="addForm.goods_number" type="number"></el-input>
                </el-form-item>
                <el-form-item label="商品分类" prop="goods_cat">
                
                </el-form-item>
              </el-tab-pane>
              <el-tab-pane label="商品参数" name="1">商品参数</el-tab-pane>
              <el-tab-pane label="商品属性" name="2">商品属性</el-tab-pane>
              <el-tab-pane label="商品图片" name="3">商品图片</el-tab-pane>
              <el-tab-pane label="商品内容" name="4">商品内容</el-tab-pane>
            </el-tabs>
          </el-form>

    在data中定义属性

     data() {
        return {
          activeIndex: '0',
          // 添加商品的表单数据对象
          addForm: {
            goods_name: '',
            goods_price: 0,
            goods_weight: 0,
            goods_number: 0,
            
          },
          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: 'blur' }
            ]
          }

    2.3,在表单中的商品分类搭建级联选择器组

    页面渲染时,发送请求,获取商品分类的数据

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

    返回的数据

    {
        "data": [
            {
                "cat_id": 1,
               "cat_name": "大家电",
                "cat_pid": 0,
                "cat_level": 0,
                "cat_deleted": false,
                "children": [
                    {
                        "cat_id": 3,
                        "cat_name": "电视",
                        "cat_pid": 1,
                        "cat_level": 1,
                        "cat_deleted": false,
                        "children": [
                            {
                                "cat_id": 6,
                                "cat_name": "曲面电视",
                                "cat_pid": 3,
                                "cat_level": 2,
                                "cat_deleted": false
                            },
                            {
                                "cat_id": 7,
                                "cat_name": "海信",
                                "cat_pid": 3,
                                "cat_level": 2,
                                "cat_deleted": false
                            }
                        ]
                    }
                ]
            }
        ],
        "meta": {
            "msg": "获取成功",
            "status": 200
        }
    }

    有了数据源,就搭建级联选择器组件了

     v-model是选中的父级的id值,数组类型,获取的是cateList中的valueID值

        <el-form-item label="商品分类" prop="goods_cat">
                  <el-cascader  :options="catelist" :props="cateProps" v-model="addForm.goods_cat" @change="handleChange">
                  </el-cascader>
                </el-form-item>
              </el-tab-pane>

    在data中定义

    // 添加商品的表单数据对象
          addForm: {
            goods_name: '',
            goods_price: 0,
            goods_weight: 0,
            goods_number: 0,
            // 商品所属的分类数组
            goods_cat: []
          },
    
    // 商品分类列表
          catelist: [],
          // cascader属性配置
          cateProps: {
            label: 'cat_name',
            value: 'cat_id',
            children: 'children',
            expandTrigger:'hover',
            checkStrictly:true
          },

    级联选择器只有三层,我们需要只选中第三级就可显示即可

    // 级联选择器选中项变化,会触发这个函数
        handleChange() {
          console.log(this.addForm.goods_cat)
          if (this.addForm.goods_cat.length !== 3) {
            this.addForm.goods_cat = []
          }
        },

    2.4,在基本信息tab中,只有商品分类项的三级分类选中了,才可以切换tab

    el-tabs定义定义该属性,属性值时函数类型

     

     <!-- tabs栏区域 -->
          <el-form
            :model="addForm"
            :rules="addFormRules"
            ref="addFormRef"
            label-width="100px"
            label-position="top"
          >
            <el-tabs
              tab-position="left"
              v-model="activeIndex"
              :before-leave="beforeTabLeave"
            >
      // tabs切换触发
        beforeTabLeave(activeName, oldActiveName) {
          // console.log('即将离开的标签页名字是:'+oldActiveName)
          // console.log('即将进入的标签页名字是:'+activeName)
          // return false
    
          if (oldActiveName === '0' && this.addForm.goods_cat.length !== '3') {
            this.$message.success('请选择商品分类')
            return false
          }
        }

     2.5,在商品参数中,form中嵌套了checkbox多选框,当切换到商品参数tab,发送请求,获取动态参数数据

     三级分类id计算出来,作为请求参数

      computed: {
        cateId() {
          if (this.addForm.goods_cat.length === 3) {
            return this.addForm.goods_cat[2]
          } else {
            return null
          }
        }
      },
    <el-tabs
              tab-position="left"
              v-model="activeIndex"
              :before-leave="beforeTabLeave"
              @tab-click="tabClicked"
            >
    // tab被选中时触发
        async  tabClicked() {
          // console.log(this.activeIndex)
          // 发送请求,获取动态参数数据
          const {data :res} = await  this.$http.get(`categories/${this.cateId}/attributes`,{params:{sel:'many'}})
          if(res.meta.status !==200){
            this.$message.error('获取参数数据失败')
          }
    
          this.manyTableData = res.data
          console.log(res.data)
        }

    返回的数据

    {
        "data": [
            {
                "attr_id": 1,
                "attr_name": "cpu",
                "cat_id": 22,
                "attr_sel": "only",
                "attr_write": "manual",
                "attr_vals": "ffff"
            }
        ],
        "meta": {
            "msg": "获取成功",
            "status": 200
        }
    }

    用数据渲染商品参数的页面

    此时返回的attr_vals参数值属性是字符串格式,我们需要把它改造成数组形式,用于checkbox的遍历,在返回数据需要整理下

    // tab被选中时触发
        async tabClicked() {
          // console.log(this.activeIndex)
          // 发送请求,获取动态参数数据
          const { data: res } = await this.$http.get(
            `categories/${this.cateId}/attributes`,
            {
              params: { sel: 'many' }
            }
          )
          if (res.meta.status !== 200) {
            this.$message.error('获取参数数据失败')
          }
          // 将attr_vals的字符串改造成数组
          res.data.forEach(item => {
            item.attr_vals =  item.attr_vals.length === 0 ? [] : item.attr_vals.split(',')
          })
          this.manyTableData = res.data
          console.log(res.data)
        }

     <el-tab-pane label="商品参数" name="1">
                <el-form-item
                  :label="item.attr_name"
                  v-for="(item, index) in manyTableData"
                  :key="item.attr_id"
                >
                  <el-checkbox-group v-model="item.attr_vals">
                    <el-checkbox :label="i" v-for="(i, index1) in item.attr_vals" :key="index1" border></el-checkbox>
                  
                  </el-checkbox-group>
                </el-form-item>
              </el-tab-pane>

    此时,复选框的间距不是一般齐的,我们需要优化下

    .el-checkbox {
      margin: 0 10px 0 0 !important;
    }

    2.6,商品属性的页面搭建

     // 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) {
              this.$message.error('获取参数数据失败')
            }
            // 将attr_vals的字符串改造成数组
            res.data.forEach(item => {
              item.attr_vals =
                item.attr_vals.length === 0 ? [] : item.attr_vals.split(',')
            })
            this.manyTableData = res.data
            // console.log(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
          }
        }
     <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>

    2.7,商品图片页面搭建

     

     在data中定义后台要上传图片的地址

    // 上传图片的URL地址
          uploadURL: 'http://127.0.0.1:8888/api/private/v1/upload',
     <el-tab-pane label="商品图片" name="3">
                <!-- action 表示图片要上传到的后台API地址 -->
                <el-upload :action="uploadURL" :on-preview="handlePreview" :on-remove="handleRemove" list-type="picture" >
                  <el-button size="small" type="primary">点击上传</el-button>
                </el-upload>
              </el-tab-pane>

    此时点击上传图片的按钮,虽然图片在页面上展示了,但是我们查看上传图片的请求,无效的token,后台上传图片的接口没有携带token

    这个是我们发送平时请求需要添加的请求拦截器

    // 配置请求拦截器,添加token
    axios.interceptors.request.use(config => {
      // console.log(config)
      config.headers.Authorization = window.sessionStorage.getItem('token')
      return config
    })

     upload有个header属性,可以携带

      <!-- action 表示图片要上传到的后台API地址 -->
                <el-upload :action="uploadURL" :on-preview="handlePreview" :on-remove="handleRemove" list-type="picture" :headers="headerObj">
                  <el-button size="small" type="primary">点击上传</el-button>
                </el-upload>
              </el-tab-pane>
    

    在data中定义

     // 图片上传组件的headers请求头对象
          headerObj: {
            Authorization: window.sessionStorage.getItem('token')
          },

     2.8, 上传图片成功时,我们添加商品请求参数有个pics需要收集(临时图片路劲),我们可以调用element的上传图片成功的函数去获取临时图片路劲

     

     <!-- action 表示图片要上传到的后台API地址 -->
                <el-upload
                  :action="uploadURL"
                  :on-preview="handlePreview"
                  :on-remove="handleRemove"
                  list-type="picture"
                  :headers="headerObj"
                  :on-success="handleSuccess"
                >
                  <el-button size="small" type="primary">点击上传</el-button>
                </el-upload>
    // 图片上传成功触发
        handleSuccess(response) {
          // console.log(response)
          // 需要把临时路径加载添加商品请求的参数中addForm的pics属性
          const changePics = { pic: response.data.tmp_path }
          this.addForm.pics.push(changePics)
          console.log(this.addForm.pics)
        }

    response的数据

     在data中定义收集添加商品的请求参数

    // 添加商品的表单数据对象
          addForm: {
            goods_name: '',
            goods_price: 0,
            goods_weight: 0,
            goods_number: 0,
            // 商品所属的分类数组
            goods_cat: [],
            // 图片临时路劲数组
            pics: []
          },

    2.9,点击图片右上角叉号按钮,在this.addForm.pics移除图片的临时路劲

    file返回的数据

    // 删除图片的函数tmp_path
        handleRemove(file) {
          // console.log(file)
          //移除图片的临时地址
          const filePath = file.response.data.tmp_path
          // 在addForm.pics中找到这个地址,然后清除掉
          this.addForm.pics = this.addForm.pics.filter(item => {
            return item.pic !== filePath
          })
    
          console.log(this.addForm.pics)
        },
    2.10,图片的预览效果

     url地址是服务器存储图片的地址,我们需要将他保存在data中,然后触发dialog弹框,里头包裹img即可

     // 点击已上传的图片,预览
        handlePreview(file) {
          console.log(file)
          this.previewPath = file.response.data.url
          this.previewVisible = true
        },
    <!-- 图片预览 -->
        <el-dialog title="图片预览" :visible.sync="previewVisible" width="50%">
          <img :src="previewPath" alt="" class="previewImg" />
        </el-dialog>

    data中定义

    previewPath: '',
    previewVisible: false
    .previewImg{
      100%
    }

    3.0,在商品内容中搭建富文本编辑器页面

     

    安装第三方插件vue-quill-editor,npm install vue-quill-editor --save

    在main.js全局注册

    // 导入富文本编辑器
    import VueQuillEditor from 'vue-quill-editor'
    // require styles 导入富文本编辑器对应的样式
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'
    
    // 将富文本编辑器,注册为全局可用的组件
    Vue.use(VueQuillEditor)
     <el-tab-pane label="商品内容" name="4">
                <!-- 富文本编辑器组件 -->
                <quill-editor v-model="addForm.goods_introduce" ></quill-editor>
                <!-- 添加商品的按钮 -->
                <el-button type="primary" style="margin-top:15px">添加商品</el-button>
              </el-tab-pane>

    v-model绑定的数据在添加商品请求参数添加

       // 添加商品的表单数据对象
          addForm: {
            goods_name: '',
            goods_price: 0,
            goods_weight: 0,
            goods_number: 0,
            // 商品所属的分类数组
            goods_cat: [],
            // 图片临时路劲数组
            pics: [],
             // 商品的详情描述
            goods_introduce: '',
          },

    3.1,点击添加按钮,发送添加商品请求

    注:此时addForm.goods_cat收集的是一个数组,而添加商品的请求参数是一个字符串,需要改造下

    <el-tab-pane label="商品内容" name="4">
                <!-- 富文本编辑器组件 -->
                <quill-editor v-model="addForm.goods_introduce"></quill-editor>
                <!-- 添加商品的按钮 -->
                <el-button type="primary" style="margin-top:15px" @click="add"
                  >添加商品</el-button

     此时会报错,因为级联选择器组件的v-modle必须是数组,把它改成字符串是报错的,我们需要深拷贝下,复制一份一样的数据,但他们不相关联

    安装lodash,  npm i --save lodash

    引入,import _ from 'lodash'

    此时添加商品的请求参数attrs是一个数组,我们也需要整理下

     在data定义

     // 添加商品的表单数据对象
          addForm: {
            goods_name: '',
            goods_price: 0,
            goods_weight: 0,
            goods_number: 0,
            // 商品所属的分类数组
            goods_cat: [],
            // 图片临时路劲数组
            pics: [],
            // 商品的详情描述
            goods_introduce: '',
            attrs: []
          },
     // 点击添加商品按钮
         add() {
          this.$refs.addFormRef.validate(async valid => {
            if (!valid) {
              return this.$message.error('请填写必要的表单项!')
            }
            // 执行添加的业务逻辑
            // lodash   cloneDeep(obj)
            // 深拷贝
            const form = _.cloneDeep(this.addForm)
            // 数组改造成字符串
            form.goods_cat = form.goods_cat.join(',')
            // 处理动态参数
            this.manyTableData.forEach(item => {
              const newInfo = {
                attr_id: item.attr_id,
                attr_value: item.attr_vals.join(' ')
              }
              this.addForm.attrs.push(newInfo)
            })
            // 处理静态属性
            this.onlyTableData.forEach(item => {
              const newInfo = { attr_id: item.attr_id, attr_value: item.attr_vals }
              this.addForm.attrs.push(newInfo)
            })
            form.attrs = this.addForm.attrs
            console.log(form)
    
            // 发起请求添加商品
            // 商品的名称,必须是唯一的
            const { data: res } = await this.$http.post('goods', form)
    
            if (res.meta.status !== 201) {
              return this.$message.error('添加商品失败!')
            }
    
            this.$message.success('添加商品成功!')
            this.$router.push('/goods')
          })
        }

    注;动态属性的属性值attr_vals是一个数组,需要改造成字符串,而静态参数的attr_vals是一个本身就是字符串

     
     
    
    
    
    
  • 相关阅读:
    Python 操作Excel之通过xlutils实现在保留原格式的情况下追加写入数据
    【转载】Python字符串操作之字符串分割与组合
    【转】Python判断字符串是否为字母或者数字
    Appium 在测试android混合应用时,关于webview页面切换的那些事儿
    使用pip install XX 命令时报错
    Appium笔记(二) 丶Appium的安装
    Android SDK的下载与安装
    KlayGE 4.4中渲染的改进(五):OpenGL 4.4和OpenGLES 3
    最先进的开源游戏引擎KlayGE 4.4发布
    KlayGE 4.4中渲染的改进(四):SSSSS
  • 原文地址:https://www.cnblogs.com/fsg6/p/14286287.html
Copyright © 2020-2023  润新知