Vue电商项目—商品管理—商品列表模块-09
Vue电商项目—商品管理—商品列表模块1.1 商品管理概述商品管理模块用于维护电商平台的商品信息,包括商品的类型、参数、图片、详情等信息。通过商品管理模块可以实现商品的添加、修改、展示和删除等功能。1.2 商品列表 实现商品列表布局效果 调用后台接口获取商品列表数据// 根据分页获取对应的商品列表数据asyncgetGoodsList() {// 发送请求const {data: res} =
Vue电商项目—商品管理—商品列表模块-09
1.1 商品管理概述
商品管理模块用于维护电商平台的商品信息,
包括商品的类型、参数、图片、详情等信息。通过商品管理模块
可以实现商品的添加、修改、展示和删除等功能。
1.2 商品列表
实现商品列表布局效果
调用后台接口获取商品列表数据
// 根据分页获取对应的商品列表数据
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('获取商品列表数据成功!');
this.goodslist = res.data.goods;
this.total = res.data.total;
// console.log(this.goodslist);
// console.log(this.total);
}
1.3 添加商品
1. 基本布局与分布条效果
添加商品基本布局
分布条组件用法
<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-alert title="添加商品信息" show-icon center :closable='false'></el-alert>
<!-- 步骤条 -->
<!-- active 激活项索引 Number -->
<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>
<!-- 添加表单 -->
<!-- label-position label标签位置 -->
<el-form :model="addForm" :rules="addRules" ref="addRef" label-width="100px" label-position='top'>
<!-- 侧边导航栏 -->
<!-- v-model 绑定值,选中选项卡的name String -->
<!-- before-leave 切换标签之前的钩子,
若返回 false 或者返回 Promise 且被 reject,则阻止切换。 类型:函数 -->
<el-tabs v-model="activeIndex" tab-position="left" :before-leave='beforeTabLeave' @tab-click='tabClicked'>
<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-cascader
expand-trigger="hover"
:options="cateList"
:props="catePropos"
v-model="addForm.goods_cat"
@change="handleChange" >
</el-cascader>
</el-form-item>
</el-tab-pane>
<el-tab-pane label="商品参数" name="1">
<el-form-item :label="item.attr_name" v-for="item in manyTableData" :key="item.attr_id">
<!-- 复选框组 -->
<el-checkbox-group v-model="item.attr_vals">
<el-checkbox :label="cb" v-for='(cb,i) in item.attr_vals' :key="i" border></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 文件上传路径 -->
<!-- on-preview 指令预览事件 -->
<!-- on-remove 文件列表移除文件时的钩子-->
<!-- headers 设置上传的请求头部 object -->
<!-- on-success 文件上传成功时的钩子 -->
<!-- list-type 文件呈现方式 -->
<el-upload
:action="uploadURL"
:on-preview="handlePreview"
:on-remove="handleRemove"
:headers="headerObj"
:on-success='hadleSuccess'
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-tab-pane>
<el-tab-pane label="商品内容" name="4">
<!-- 富文本编辑器组件 -->
<quill-editor v-model="addForm.goods_introduce"></quill-editor>
<!-- 添加商品按钮 -->
<el-button type="primary" @click="add">添加商品</el-button>
</el-tab-pane>
</el-tabs>
</el-form>
</el-card>
<!-- 图片预览 -->
<el-dialog title="图片预览" :visible.sync="previewVisible" width="50%">
<img :src="previewPath" class="previewImg">
</el-dialog>
</div>
2. 商品信息选项卡Tab布局效果
Tab 组件的基本使用
<el-tabs tab-position="left" v-model="activeName" :before-leave="beforeTabLeave">
<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>
3. Steps 步骤条 与 Tabs 标签的联动效果
// 设置当前激活步骤
activeIndex: '0'
<!-- active 激活项索引 Number -->
<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-steps>
<!-- 侧边导航栏 -->
<!-- v-model 绑定值,选中选项卡的name String -->
<!-- before-leave 切换标签之前的钩子,
若返回 false 或者返回 Promise 且被 reject,则阻止切换。 类型:函数 -->
<el-tabs v-model="activeIndex" tab-position="left" :before-leave='beforeTabLeave' @tab-click='tabClicked'>
<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-cascader
expand-trigger="hover"
:options="cateList"
:props="catePropos"
v-model="addForm.goods_cat"
@change="handleChange" >
</el-cascader>
</el-form-item>
</el-tab-pane>
<el-tab-pane label="商品参数" name="1">
<el-form-item :label="item.attr_name" v-for="item in manyTableData" :key="item.attr_id">
<!-- 复选框组 -->
<el-checkbox-group v-model="item.attr_vals">
<el-checkbox :label="cb" v-for='(cb,i) in item.attr_vals' :key="i" border></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 文件上传路径 -->
<!-- on-preview 指令预览事件 -->
<!-- on-remove 文件列表移除文件时的钩子-->
<!-- headers 设置上传的请求头部 object -->
<!-- on-success 文件上传成功时的钩子 -->
<!-- list-type 文件呈现方式 -->
<el-upload
:action="uploadURL"
:on-preview="handlePreview"
:on-remove="handleRemove"
:headers="headerObj"
:on-success='hadleSuccess'
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-tab-pane>
<el-tab-pane label="商品内容" name="4">
<!-- 富文本编辑器组件 -->
<quill-editor v-model="addForm.goods_introduce"></quill-editor>
<!-- 添加商品按钮 -->
<el-button type="primary" @click="add">添加商品</el-button>
</el-tab-pane>
</el-tabs>
4. 商品分类信息
商品分类布局
商品分类数据加载
<!-- 商品分类级联选择器 -->
<el-cascader
expand-trigger="hover"
:options="cateList"
:props="catePropos"
v-model="addForm.goods_cat"
@change="handleChange" >2
</el-cascader>
// 获取商品分类数据
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);
}
5. 未选择任何商品分类,阻止tabs导航栏的切换
<!-- 侧边导航栏 -->
<!-- v-model 绑定值,选中选项卡的name String -->
<!-- before-leave 切换标签之前的钩子, 若返回 false 或者返回 Promise 且被 reject,则阻止切换。 类型:函数 -->
<el-tabs
v-model="activeIndex"
tab-position="left"
:before-leave='beforeTabLeave'
@tab-click='tabClicked'>
</el-tabs>
// 切换标签之前的钩子
// activeName 即将进入的标签页名称
// oldActiveName 即将离开的标签页名称
beforeTabLeave(activeName, oldActiveName) {
// 即将离开的,是否为基本信息页,且根据选择商品分类的数组长度,判断是否选中了三级分类
if(oldActiveName === '0' && this.addForm.goods_cat.length !== 3)
{
this.$message.error('请先选择商品分类!');
// 只要返回 false,就会阻止标签页的切换
return false
}
}
6. 商品动态参数
获取商品动态参数数据
商品动态参数布局
// 侧边栏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('获取动态参数列表失败!');
// 将动态参数中的 attr_vals,转换为 数组,供 多选框组 使用
res.data.forEach(item => {
item.attr_vals = item.attr_vals.length === 0 ? [] : item.attr_vals.split(' ');
});
this.manyTableData = res.data;
// console.log(this.manyTableData);
}
}
7. 商品静态属性
获取商品静态属性数据
商品静态属性布局
// 侧边栏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('获取动态参数列表失败!');
// 将动态参数中的 attr_vals,转换为 数组,供 多选框组 使用
res.data.forEach(item => {
item.attr_vals = item.attr_vals.length === 0 ? [] : item.attr_vals.split(' ');
});
this.manyTableData = res.data;
// console.log(this.manyTableData);
}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;
// console.log(this.onlyTableData);
}
}
8. 商品图片上传
图片上传组件基本使用
<!-- 上传商品图片区域 -->
<!-- action 文件上传路径 -->
<!-- on-preview 指令预览事件 -->
<!-- on-remove 文件列表移除文件时的钩子-->
<!-- headers 设置上传的请求头部 object -->
<!-- on-success 文件上传成功时的钩子 -->
<!-- list-type 文件呈现方式 -->
<el-upload
:action="uploadURL"
:on-preview="handlePreview"
:on-remove="handleRemove"
:headers="headerObj"
:on-success='hadleSuccess'
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
main.js入口文件中,设置了 自定义属性的请求头,
而图片上传有自带的一套发送请求的方式,
因为请求头缺少 Authorization属性,导致上传不成功
// 导入axios
import axios from 'axios'
// 配置请求的根路径
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/';
// 通过axios请求拦截器添加token,保证拥有获取数据的权限
// axios请求拦截
// 在 request 拦截器中,展示进度条 NProgress.start()
axios.interceptors.request.use(config => {
// 显示进度条
NProgress.start();
// 为请求头对象,添加token 验证的Authorization字段
config.headers.Authorization = window.sessionStorage.getItem('token');
return config;
});
// 上传图片的URL地址
uploadURL: 'http://127.0.0.1:8888/api/private/v1/upload',
// 因为upload组件有自己的一套Ajax,不走我们axios设置的
// 设置图片上传组件的headers请求头对象
headerObj: {
Authorization: window.sessionStorage.getItem('token')
},
// 预览图片展示路径
previewPath: '',
// 控制图片预览对话框的显示与隐藏
previewVisible: false
// 添加商品的表单数据对象
addForm: {
goods_name: '',
goods_price: 0,
goods_weight: 0,
goods_number: 0,
goods_cat: [],
// 图片路径的数组
pics: [],
// 商品介绍
goods_introduce: '',
// 商品参数,包括 动态参数manyTableData 和 静态属性onlyTableData
attrs: []
}
// 监听图片上传成功事件
hadleSuccess(response) {
// console.log(response);
// 1、将虚拟路径,拼接得到一个图片信息对象
const picInco = {pic: response.data.tmp_path}
// 2、将图片信息对象,push 到 pics 数组中
this.addForm.pics.push(picInco);
// console.log(this.addForm);
}
图片预览
// 处理图片预览效果
handlePreview(file) {
// 保存图片预览的真实路径
this.previewPath = file.response.data.url;
// 显示图片预览对话框
this.previewVisible = true;
}
图片删除
// 图片移除操作
handleRemove(file) {
// 1、获取将要删除的图片的临时路径
const filePath = file.response.data.tmp_path;
// 2、从 pics 数组中,找到这个图片对应的索引值
const index = this.addForm.pics.findIndex(x => x.pic === filePath);
// 3、调用数组的 splice 方法,把图片信息对象,从 pics 数组中移除
this.addForm.pics.splice(index, 1);
console.log(this.addForm);
}
9. 商品详情
富文本编辑器基本使用
在main.js 入口文件中
// 导入富文本编辑器
import VueQuillEditor from 'vue-quill-editor'
// require styles 导入富文本编辑器对应的样式
import 'quill/dist/quill.core.css' // import styles
import 'quill/dist/quill.snow.css' // for snow theme
import 'quill/dist/quill.bubble.css' // for bubble theme
// 将富文本编辑器,注册为全局可用的组件
Vue.use(VueQuillEditor);
使用
<!-- 富文本编辑器组件 -->
<quill-editor v-model="addForm.goods_introduce"></quill-editor>
10. 添加商品
注意点一: 级联选择器v-model数据绑定值goods_cat,必须是 数组
// 添加商品的表单数据对象
addForm: {
goods_name: '',
goods_price: 0,
goods_weight: 0,
goods_number: 0,
goods_cat: [],
// 图片路径的数组
pics: [],
// 商品介绍
goods_introduce: '',
// 商品参数,包括 动态参数manyTableData 和 静态属性onlyTableData
attrs: []
}
<el-form-item label="商品分类" prop="goods_cat">
<!-- 商品分类级联选择器 -->
<el-cascader
expand-trigger="hover"
:options="cateList"
:props="catePropos"
v-model="addForm.goods_cat"
@change="handleChange" >
</el-cascader>
</el-form-item>
注意点二:而提交表单参数的 goods_cat值,是 字符串
1.请求参数中,商品分类参数处理
如果在 添加商品时,将 goods_cat转换成 字符串,会导致页面报错,
因为, 级联选择器v-model数据绑定值goods_cat,必须是 数组
解决方案: 通过lodash.cloneDeep()方法,将对象进行 深拷贝
// 导入lodash,用于深拷贝
// 官方提倡命名为 _
import _ from 'lodash'
// 验证通过
// this.addForm.goods_cat 供级联选择器使用 类型必须是数组
// 提交参数中的 goods_cat,必须是字符串
// 通过深拷贝,解决这个问题
const form = _.cloneDeep(this.addForm);
form.goods_cat = form.goods_cat.join(',');
2. 请求参数中,商品参数处理
// 添加商品的表单数据对象
addForm: {
goods_name: '',
goods_price: 0,
goods_weight: 0,
goods_number: 0,
goods_cat: [],
// 图片路径的数组
pics: [],
// 商品介绍
goods_introduce: '',
// 商品参数,包括 动态参数manyTableData 和 静态属性onlyTableData
attrs: []
}
// 动态参数列表数据
manyTableData: [],
// 静态属性列表数据
onlyTableData: []
动态参数列表中的 atrr_vals 是数组
// 处理动态参数
this.manyTableData.forEach(item => {
const newInfo = {
attr_id: item.attr_id,
attr_vals: item.attr_vals.join(' ')
}
this.addForm.attrs.push(newInfo);
});
// 处理静态属性
this.onlyTableData.forEach(item => {
const newInfo = {
attr_id: item.attr_id,
attr_vals: item.attr_vals
}
this.addForm.attrs.push(newInfo);
});
// 将处理好的addForm.attrs,赋值给 深拷贝的 form对象
form.attrs = this.addForm.attrs;
发送请求
// 发送请求
// 商品的名称,必须是唯一的
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');
});
该模块的完整代码
<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-alert title="添加商品信息" show-icon center :closable='false'></el-alert>
<!-- 步骤条 -->
<!-- active 激活项索引 Number -->
<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>
<!-- 添加表单 -->
<!-- label-position label标签位置 -->
<el-form :model="addForm" :rules="addRules" ref="addRef" label-width="100px" label-position='top'>
<!-- 侧边导航栏 -->
<!-- v-model 绑定值,选中选项卡的name String -->
<!-- before-leave 切换标签之前的钩子,
若返回 false 或者返回 Promise 且被 reject,则阻止切换。 类型:函数 -->
<el-tabs v-model="activeIndex" tab-position="left" :before-leave='beforeTabLeave' @tab-click='tabClicked'>
<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-cascader
expand-trigger="hover"
:options="cateList"
:props="catePropos"
v-model="addForm.goods_cat"
@change="handleChange" >
</el-cascader>
</el-form-item>
</el-tab-pane>
<el-tab-pane label="商品参数" name="1">
<el-form-item :label="item.attr_name" v-for="item in manyTableData" :key="item.attr_id">
<!-- 复选框组 -->
<el-checkbox-group v-model="item.attr_vals">
<el-checkbox :label="cb" v-for='(cb,i) in item.attr_vals' :key="i" border></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 文件上传路径 -->
<!-- on-preview 指令预览事件 -->
<!-- on-remove 文件列表移除文件时的钩子-->
<!-- headers 设置上传的请求头部 object -->
<!-- on-success 文件上传成功时的钩子 -->
<!-- list-type 文件呈现方式 -->
<el-upload
:action="uploadURL"
:on-preview="handlePreview"
:on-remove="handleRemove"
:headers="headerObj"
:on-success='hadleSuccess'
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-tab-pane>
<el-tab-pane label="商品内容" name="4">
<!-- 富文本编辑器组件 -->
<quill-editor v-model="addForm.goods_introduce"></quill-editor>
<!-- 添加商品按钮 -->
<el-button type="primary" @click="add">添加商品</el-button>
</el-tab-pane>
</el-tabs>
</el-form>
</el-card>
<!-- 图片预览 -->
<el-dialog title="图片预览" :visible.sync="previewVisible" width="50%">
<img :src="previewPath" class="previewImg">
</el-dialog>
</div>
</template>
<script>
// 导入lodash,用于深拷贝
import _ from 'lodash'
export default {
data() {
return {
// 设置当前激活步骤
activeIndex: '0',
// 添加商品的表单数据对象
addForm: {
goods_name: '',
goods_price: 0,
goods_weight: 0,
goods_number: 0,
goods_cat: [],
// 图片路径的数组
pics: [],
// 商品介绍
goods_introduce: '',
// 商品参数,包括 动态参数manyTableData 和 静态属性onlyTableData
attrs: []
},
// 添加商品的表单数据验证规则
addRules: {
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: [],
// 配置级联选择器
catePropos: {
label: 'cat_name',
value: 'cat_id',
children: 'children'
},
// 动态参数列表数据
manyTableData: [],
// 静态属性列表数据
onlyTableData: [],
// 上传图片的URL地址
uploadURL: 'http://127.0.0.1:8888/api/private/v1/upload',
// 因为upload组件有自己的一套Ajax,不走我们axios设置的
// 设置图片上传组件的headers请求头对象
headerObj: {
Authorization: window.sessionStorage.getItem('token')
},
// 预览图片展示路径
previewPath: '',
// 控制图片预览对话框的显示与隐藏
previewVisible: false
}
},
created() {
// 获取商品分类数据
this.getCateList();
},
computed: {
cateId() {
if(this.addForm.goods_cat.length === 3) {
return this.addForm.goods_cat[2];
}
return null;
}
},
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);
},
// 级联选择器选中项变化,触发函数
handleChange() {
// 限制级联选择器,只能选中最后一项
if(this.addForm.goods_cat.length !== 3) {
this.addForm.goods_cat = [];
}
// console.log(this.addForm.goods_cat);
},
// 切换标签之前的钩子
beforeTabLeave(activeName, oldActiveName) {
if(oldActiveName === '0' && this.addForm.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('获取动态参数列表失败!');
// 将静态参数中的 attr_vals,转换为 数组,供 多选框组 使用
res.data.forEach(item => {
item.attr_vals = item.attr_vals.length === 0 ? [] : item.attr_vals.split(' ');
});
this.manyTableData = res.data;
// console.log(this.manyTableData);
}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;
// console.log(this.onlyTableData);
}
},
// 处理图片预览效果
handlePreview(file) {
// 保存图片预览的真实路径
this.previewPath = file.response.data.url;
// 显示图片预览对话框
this.previewVisible = true;
},
// 图片移除操作
handleRemove(file) {
// 1、获取将要删除的图片的临时路径
const filePath = file.response.data.tmp_path;
// 2、从 pics 数组中,找到这个图片对应的索引值
const index = this.addForm.pics.findIndex(x => x.pic === filePath);
// 3、调用数组的 splice 方法,把图片信息对象,从 pics 数组中移除
this.addForm.pics.splice(index, 1);
console.log(this.addForm);
},
// 监听图片上传成功事件
hadleSuccess(response) {
// console.log(response);
// 1、将虚拟路径,拼接得到一个图片信息对象
const picInco = {pic: response.data.tmp_path}
// 2、将图片信息对象,push 到 pics 数组中
this.addForm.pics.push(picInco);
// console.log(this.addForm);
},
// 添加商品点击事件
add() {
// 表单预验证
this.$refs.addRef.validate( async valid => {
// 验证失败
if(!valid) return this.$message.error('请填写必要的表单项!');
// 验证通过
// this.addForm.goods_cat 供级联选择器使用 类型必须是数组
// 提交参数中的 goods_cat,必须是字符串
// 通过深拷贝,解决这个问题
const form = _.cloneDeep(this.addForm);
form.goods_cat = form.goods_cat.join(',');
// 处理动态参数
this.manyTableData.forEach(item => {
const newInfo = {
attr_id: item.attr_id,
attr_vals: item.attr_vals.join(' ')
}
this.addForm.attrs.push(newInfo);
});
// 处理静态属性
this.onlyTableData.forEach(item => {
const newInfo = {
attr_id: item.attr_id,
attr_vals: 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');
});
}
}
}
</script>
<style lang="less" scoped>
.el-steps {
margin: 15px 0;
}
.el-checkbox {
margin: 0 10px 0 0!important;
}
// 预览的图片
.previewImg {
width: 100%;
}
.quill-editor {
margin-bottom: 10px;
}
</style>
更多推荐
所有评论(0)