1、创建商品分类分支goods_params并push到远程
创建分支goods_params,并切换到当前:
git checkout -b goods_params
推送到远程:(以前码云中没有该分支,所以要加-u,如果码云中有该分支,则不需要加-u)
git push -u origin goods_params
2、通过路由加载分类参数组件
在goods文件夹和Params.vue文件:
<template> <div> <h3>分类参数组件</h3> </div> </template> <script> export default { } </script> <style lang="less" scoped> </style>
添加路由:
import Params from '../components/goods/Params.vue' const routes = [ { path: '/', redirect: '/login' }, // 重定向 { path: '/login', component: Login }, { path: '/home', component: Home, redirect: '/welcome', // 重定向 children: [ // 子路由 { path: '/welcome', component: Welcome }, { path: '/users', component: Users }, // 用户列表 { path: '/rights', component: Rights }, // 权限列表 { path: '/roles', component: Roles }, // 角色列表 { path: '/categories', component: Cate }, // 商品分类 { path: '/params', component: Params } // 分类参数 ] } ]
点击左侧菜单的分类参数的效果如图:
3、渲染分类参数页面的基本UI布局
还是面包屑和card视图:
<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> 123 </el-card> </div> </template>
然后是头部警告区域,需要用到Alert 警告组件,导入element.js里
在 Alert 组件中,你可以设置是否可关闭,关闭按钮的文本以及关闭时的回调函数。closable
属性决定是否可关闭,接受boolean
,默认为true
。你可以设置close-text
属性来代替右侧的关闭图标,注意:close-text
必须为文本。设置close
事件来设置关闭时的回调。通过设置show-icon
属性来显示 Alert 的 icon。
<!--卡片视图区域--> <el-card> <!--警告区域--> <el-alert title="注意:只允许为第三季分类设置相关参数!" type="warning" show-icon :closable="false"></el-alert> <!--选择商品分类区域--> <el-row class="cat_opt"> <el-col> <span>选择商品分类:</span> <!--选择商品分类的级联选择框--> </el-col> </el-row> </el-card> <style lang="less" scoped> .cat_opt{margin:15px 0;} </style>
此时效果图:
4、获取商品分类列表数据
<script> export default { data() { return { cateList: [], // 商品分类列表数据 } }, created() { 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 } } } </script>
5、渲染商品分类的级联选择框
添加级联选择框代码:
<!--选择商品分类的级联选择框--> <!-- options用来指定数据源 props用来指定配置对象--> <el-cascader v-model="selectedCateKeys" :options="cateList" :props="cateProps" @change="cateChanged" clearable></el-cascader> <script> export default { data() { return { // 指定级联选择框的配置对象 cateProps: { expandTrigger: 'hover', // 次级菜单的展开方式 click / hover value: 'cat_id', // 指定选中值的属性 label: 'cat_name', // 指定选中标签的名称 children: 'children' // 指定父子嵌套的属性 }, selectedCateKeys: [] // 级联选择框双向绑定 选中的商品分类的ID数组 } }, methods: { // 级联选择框选中项变化,会触发这个函数 cateChanged() { console.log(this.selectedCateKeys) } } } </script>
此时点击级联选择框,选中商品效果图:
6、控制级联选择框的选中范围
以为警告框写了只允许为第三级分类设置相关参数,所以分类也应该只能选中三级分类:
// 级联选择框选中项变化,会触发这个函数 cateChanged() { // 证明选中的不是三级分类 if (this.selectedCateKeys.length !== 3) { this.selectedCateKeys = [] return } // 证明选中的是三级分类 console.log(this.selectedCateKeys) }
7、渲染分类参数的Tabs标签组件
v-model实现双向数据绑定,tab-click点击事件
label指定标题,name页签名称,自动绑定到v-model的属性上
Tabs 和 TabPane 需要导入element.js中,然后添加代码:
<!--Tabs标签区域--> <el-tabs v-model="activeName" @tab-click="handleTabClick"> <el-tab-pane label="动态参数" name="first">动态参数</el-tab-pane> <el-tab-pane label="静态属性" name="second">静态属性</el-tab-pane> </el-tabs> <script> export default { data() { return { // 被激活的标签的名称,默认为first activeName: 'first' } }, methods: { // tab标签的点击事件处理函数 handleTabClick() { console.log(this.activeName) } } } </script>
点击切换tab标签效果图:
8、渲染添加参数按钮并控制按钮的禁用状态
可以使用disabled
属性来定义按钮是否可用,它接受一个Boolean
值。
需要添加一个计算属性,判断selectedCateKeys的长度不等于3时返回一个布尔值,绑定到按钮来禁用
<!--添加参数的按钮--> <el-button type="primary" size="mini" :disabled="isBtnDisabled">添加参数</el-button> <!--添加属性的按钮--> <el-button type="primary" size="mini" :disabled="isBtnDisabled">添加属性</el-button> <script> export default { computed: { // 计算属性 // 如果按钮需要被禁用 则返回true,否则返回false isBtnDisabled() { if (this.selectedCateKeys.length !== 3) { return true } return false } } } </script>
效果图:
9、获取分类参数列表数据
调用api的分类参数列表接口,请求路径:categories/:id/attributes,请求方法:get,请求参数:sel [only,many] 不能为空,通过 only 或 many 来获取分类静态参数还是动态参数
因为请求参数sel 需要传递动态或者静态,所以把Tabs标签的name值改为相对应的many 和 only
<!--添加动态参数的面板--> <el-tab-pane label="动态参数" name="many"> <!--添加静态属性的面板--> <el-tab-pane label="静态属性" name="only"> // 被激活的标签的名称,默认为many activeName: 'many'
在级联选择框选中三级分类时,请求获取分类参数列表数据,所以在cateChanged函数中添加代码:
// 级联选择框选中项变化,会触发这个函数 async cateChanged() { // 证明选中的不是三级分类 if (this.selectedCateKeys.length !== 3) { this.selectedCateKeys = [] return } // 证明选中的是三级分类 console.log(this.selectedCateKeys) // 根据所选分类的id 和当前所处的面板,获取对应的参数数据列表 const { data: res } = await this.$http.get( `categories/${this.cateId}/attributes`, { params: { sel: this.activeName } } ) if (res.meta.status !== 200) { return this.$message.error('获取参数列表失败') } console.log(res.data) },
10、切换Tabs面板后,重新获取参数列表数据
把根据所选分类的id 和当前所处的面板,获取对应的参数数据列表这些操作单独为一个函数,然后级联选择框选中项变化和切换tabs标签时都调用这个函数
// 级联选择框选中项变化,会触发这个函数 cateChanged() { // 证明选中的不是三级分类 if (this.selectedCateKeys.length !== 3) { this.selectedCateKeys = [] return } // 证明选中的是三级分类 console.log(this.selectedCateKeys) this.getParamsList() }, // tab标签的点击事件处理函数 handleTabClick() { // console.log(this.activeName) this.getParamsList() }, // 获取参数的列表数据 async getParamsList() { // 根据所选分类的id 和当前所处的面板,获取对应的参数数据列表 const { data: res } = await this.$http.get( `categories/${this.cateId}/attributes`, { params: { sel: this.activeName } } ) if (res.meta.status !== 200) { return this.$message.error('获取参数列表失败') } console.log(res.data) }
11、将获取到的参数列表数据挂载到对应的数据源上
在获取到参数列表数据后,还要判断是动态参数还是静态属性的,然后赋值给对应的数组:
manyTableData: [], // 动态参数的数据列表 onlyTableData: [] // 静态属性的数据列表 // 获取参数的列表数据 async getParamsList() { // 根据所选分类的id 和当前所处的面板,获取对应的参数数据列表 const { data: res } = await this.$http.get( `categories/${this.cateId}/attributes`, { params: { sel: this.activeName } } ) if (res.meta.status !== 200) { return this.$message.error('获取参数列表失败') } console.log(res.data) if (this.activeName === 'many') { this.manyTableData = res.data } else { this.onlyTableData = res.data } }
12、渲染动态参数和静态属性的Table表格
添加代码:
<!--动态参数表格--> <el-table :data="manyTableData" border stripe> <!--展开列--> <el-table-column type="expand"> </el-table-column> <el-table-column type="index" label="#"></el-table-column> <el-table-column label="参数名称" prop="attr_name"></el-table-column> <el-table-column label="操作"> <!-- 作用域插槽 --> <template slot-scope="scope"> <el-button size="mini" type="primary" icon="el-icon-edit">编辑</el-button> <el-button size="mini" type="danger" icon="el-icon-delete">删除</el-button> </template> </el-table-column> </el-table> <!--静态属性表格--> <el-table :data="onlyTableData" border stripe> <!--展开列--> <el-table-column type="expand"> </el-table-column> <el-table-column type="index" label="#"></el-table-column> <el-table-column label="属性名称" prop="attr_name"></el-table-column> <el-table-column label="操作"> <!-- 作用域插槽 --> <template slot-scope="scope"> <el-button size="mini" type="primary" icon="el-icon-edit">编辑</el-button> <el-button size="mini" type="danger" icon="el-icon-delete">删除</el-button> </template> </el-table-column> </el-table>
此时效果图:
13、渲染添加参数的对话框
添加动态参数和静态属性,共用一个对话框,就需要添加计算属性做一些判断
先添加一个计算属性函数:
// 动态计算添加参数对话框标题的文本 titleText() { if (this.activeName === 'many') { return '动态参数' } else { return '静态属性' } }
添加对话框代码:
<!--参加参数的对话框--> <el-dialog :title="'添加' + titleText" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed"> <!--内容主体区域--> <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="90px"> <el-form-item :label="titleText" prop="attr_name"> <el-input v-model="addForm.attr_name"></el-input> </el-form-item> </el-form> <!--底部按钮区域--> <span slot="footer" class="dialog-footer"> <el-button @click="addDialogVisible = false">取 消</el-button> <el-button type="primary" @click="addDialogVisible = false">确 定</el-button> </span> </el-dialog> <script> export default { data() { return { addDialogVisible: false, // 控制添加参数对话框是否显示 // 添加参数的表单数据对象 addForm: { attr_name: '' }, // 添加表单的验证规则对象 addFormRules: { attr_name: [ { required: true, message: '请输入参数名称', trigger: 'blur' } ] } } }, methods: { // 监听 添加参数对话框的关闭事件 addDialogClosed() { // 表单内容重置为空 this.$refs.addFormRef.resetFields() } } } </script>
点击添加参数按钮的效果图:
14、完成动态参数和静态属性的添加操作
调用api的添加动态参数或者静态属性接口,请求路径:categories/:id/attributes,请求方法:post,
请求参数:
attr_name 参数名称 不能为空
attr_sel [only,many] 不能为空
ttr_vals 如果是 many 就需要填写值的选项,以逗号分隔 【可选参数】
先填写要添加的参数名称,然后点击确定按钮做表单的预校验,当预校验成功后,发起网络请求,向服务添加对应的参数
先给确定按钮添加点击事件:
<el-button type="primary" @click="addParams">确 定</el-button>
addParams事件函数:
// 点击确认 添加新的参数 addParams() { // console.log(this.addForm) this.$refs.addFormRef.validate(async valid => { // 预校验 if (!valid) return 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.$message.error('添加参数失败!') } this.$message.success('添加参数成功!') this.getParamsList() this.addDialogVisible = false }) }
效果图:
15、渲染编辑修改参数的对话框
给编辑按钮添加点击事件:
<el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditDialog">编辑</el-button>
// 监听 展示编辑参数的对话框 showEditDialog(id) { this.editDialogVisible = true }
复制添加参数对话框的代码,修改为编辑对话框:
<!--编辑参数的对话框--> <el-dialog :title="'编辑' + titleText" :visible.sync="editDialogVisible" width="50%" @close="editDialogClosed" > <!--内容主体区域--> <el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="90px"> <el-form-item :label="titleText" prop="attr_name"> <el-input v-model="editForm.attr_name"></el-input> </el-form-item> </el-form> <!--底部按钮区域--> <span slot="footer" class="dialog-footer"> <el-button @click="editDialogVisible = false">取 消</el-button> <el-button type="primary" @click="editParams">确 定</el-button> </span> </el-dialog> <script> export default { data() { return { editDialogVisible: false, // 控制编辑参数对话框是否显示 // 编辑参数的表单数据对象 editForm: {} } }, methods: { // 监听 展示编辑参数的对话框 showEditDialog() { this.editDialogVisible = true }, // 监听 编辑参数对话框的关闭事件 editDialogClosed() { // 表单内容重置为空 this.$refs.editFormRef.resetFields() }, // 点击确认 编辑修改参数 editParams() { } } } </script>
16、完成修改参数的操作
先调用api的根据 ID 查询参数接口,请求路径:categories/:id/attributes/:attrId,请求方法:get,
请求参数:
attr_sel [only,many] 不能为空
attr_vals 如果是 many 就需要填写值的选项,以逗号分隔
修改编辑按钮:
<el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditDialog(scope.row.attr_id)">编辑</el-button>
完善showEditDialog代码:
// 监听 展示编辑参数的对话框 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.$message.error('查询参数信息失败') } this.editForm = res.data this.editDialogVisible = true },
修改参数后,需要调用api的编辑提交参数接口,请求路径:categories/:id/attributes/:attrId,请求方法:put,
请求参数:
attr_name 新属性的名字 不能为空,携带在`请求体`中
attr_sel 属性的类型[many或only] 不能为空,携带在`请求体`中
attr_vals 参数的属性值 可选参数,携带在`请求体`中
点击确定按钮做表单的预校验,当预校验成功后,发起网络请求,向服务提交修改的参数:
// 点击确认 编辑修改参数 editParams() { this.$refs.editFormRef.validate(async valid => { if (!valid) return // 可以发起修改参数信息的网络请求 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.$message.error('编辑参数信息失败!') } this.$message.success('编辑参数信息成功!') this.getParamsList() this.editDialogVisible = false }) }
效果图:
17、完成删除参数的操作
给删除按钮添加点击事件:
<el-button size="mini" type="danger" icon="el-icon-delete" @click="delParamsDialog(scope.row.attr_id)">删除</el-button>
调用api的删除参数接口,请求路径: categories/:id/attributes/:attrid,请求方法:delete
// 根据id删除参数对话框 async delParamsDialog(arrtId) { // console.log(arrtId) // 弹框 询问用户是否删除 const confirmResult = await this.$confirm('此操作将永久删除该参数, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).catch(err => err) // 如果用户确认删除,则返回值为字符串 confirm // 如果用户取消删除,则返回值为字符串 cancel // console.log(confirmResult) if (confirmResult !== 'confirm') { return this.$message.info('已取消删除') } // console.log('确认删除') // 发起删除参数的网络请求 const { data: res } = await this.$http.delete(`categories/${this.cateId}/attributes/${arrtId}`) if (res.meta.status !== 200) { return this.$message.error('删除参数信息失败!') } this.$message.success('删除参数信息成功!') this.getParamsList() }
效果图:
18、渲染参数下的可选项
后台返回的数据中attr_vals字段参数给的是字符串类型,不能进行循环渲染,所以要进行改造:
循环data中的每一项,把attr_vals参数的字符串,重新赋值为attr_vals数组,在进行for循环渲染
修改getParamsList函数,在获取所有参数项后,以空格分隔attr_vals:
// 获取参数的列表数据 async getParamsList() { // 根据所选分类的id 和当前所处的面板,获取对应的参数数据列表 const { data: res } = await this.$http.get( `categories/${this.cateId}/attributes`, { params: { sel: this.activeName } } ) if (res.meta.status !== 200) { return this.$message.error('获取参数列表失败') } console.log(res.data) // 循环data中的每一项,把attr_vals参数的字符串,重新赋值为item.attr_vals数组 res.data.forEach(item => { item.attr_vals = item.attr_vals.split(' ') }) if (this.activeName === 'many') { this.manyTableData = res.data } else { this.onlyTableData = res.data } },
然后在展开列中进行for循环渲染;
<!--展开列--> <el-table-column type="expand"> <template slot-scope="scope"> <el-tag v-for="(item, i) in scope.row.attr_vals" :key="i" closable>{{item}}</el-tag> </template> </el-table-column>
此时点击展开列的效果图:
19、解决attr_vals字段为空字符时的小bug
当attr_vals字段为空时,会显示一个带X的空tag标签,因为空字符串以空格分割时,会返回一个数组,包含一个空字符串,所以就会渲染出一个空白的tag标签
还是在getParamsList函数中,加一个判断:
// 获取参数的列表数据 async getParamsList() { // 根据所选分类的id 和当前所处的面板,获取对应的参数数据列表 const { data: res } = await this.$http.get( `categories/${this.cateId}/attributes`, { params: { sel: this.activeName } } ) if (res.meta.status !== 200) { return this.$message.error('获取参数列表失败') } console.log(res.data) // 循环data中的每一项,把attr_vals参数的字符串,重新赋值为item.attr_vals数组 res.data.forEach(item => { // if (item.attr_vals.length === 0) return // item.attr_vals = item.attr_vals.split(' ') item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : [] }) if (this.activeName === 'many') { this.manyTableData = res.data } else { this.onlyTableData = res.data } },
20、控制按钮与文本框的切换显示
添加代码:
<!--输入文本框--> <el-input class="input-new-tag" v-if="inputVisible" v-model="inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm" @blur="handleInputConfirm"></el-input> <!--添加的按钮--> <el-button v-else class="button-new-tag" size="small" @click="showInput">+ New Tag</el-button> <script> export default { data() { return { inputVisible: false, // 控制按钮与文本框的切换显示 inputValue: '' // 文本框中输入的内容 } }, methods: { // 文本框失去焦点或按下回车键时都会触发 handleInputConfirm() { console.log('ok') }, // 点击按钮展示文本输入框 showInput() { this.inputVisible = true } } } </script> <style lang="less" scoped> .input-new-tag { width: 120px; } </style>
@keyup.enter.native 表示按下键盘的回车键
@blur 表示失去焦点的时候
21 、为每一行数据提供单独的inputVisible和inputValue
在获取所有参数的getParamsList函数中给每个item单独添加:
// 获取参数的列表数据 async getParamsList() { // 根据所选分类的id 和当前所处的面板,获取对应的参数数据列表 const { data: res } = await this.$http.get( `categories/${this.cateId}/attributes`, { params: { sel: this.activeName } } ) if (res.meta.status !== 200) { return this.$message.error('获取参数列表失败') } console.log(res.data) // 循环data中的每一项,把attr_vals参数的字符串,重新赋值为item.attr_vals数组 res.data.forEach(item => { // if (item.attr_vals.length === 0) return // item.attr_vals = item.attr_vals.split(' ') item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : [] // 控制文本框的显示与隐藏 item.inputVisible = false // 文本框中输入的值 item.inputValue = '' }) if (this.activeName === 'many') { this.manyTableData = res.data } else { this.onlyTableData = res.data } },
记得要把data里定义的inputVisible和inputValue删除掉,因为这里已经定义了。
然后修改代码:
<!--输入文本框--> <el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm" @blur="handleInputConfirm"></el-input> <!--添加的按钮--> <el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button>
showInput函数修改:
// 点击按钮展示文本输入框 showInput(row) { row.inputVisible = true }
现在就不会联动了,效果图:
22、让文本框自动获得焦点
在showInput函数里添加代码:
// 点击按钮展示文本输入框 showInput(row) { row.inputVisible = true // 让文本框自动获得焦点 // $nextTick 方法的作用:就是当页面上元素被重新渲染之后,才会执行回调中的代码 this.$nextTick(_ => { this.$refs.saveTagInput.$refs.input.focus() }) }
23、实现文本框与按钮的切换显示
修改代码:
<!--输入文本框--> <el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(scope.row)" @blur="handleInputConfirm(scope.row)"></el-input>
handleInputConfirm函数添加代码:
// 文本框失去焦点或按下回车键时都会触发 handleInputConfirm(row) { // trim() 去除字符串两端的空格 if (row.inputValue.trim().length === 0) { row.inputValue = '' row.inputVisible = false return } // 如果没有return,则证明输入的内容,需要做后续处理 console.log('ok') },
24、完成参数可选项的添加操作
先把row.inputValue的值push到row.attr_vals中,然后发起网络请求
调用api的编辑提交参数接口,请求路径:categories/:id/attributes/:attrId,请求方法:put
请求参数:
attr_name 新属性的名字 不能为空,携带在`请求体`中
attr_sel 属性的类型[many或only] 不能为空,携带在`请求体`中
attr_vals 参数的属性值 可选参数,携带在`请求体`中
继续完善handleInputConfirm函数:
// 文本框失去焦点或按下回车键时都会触发 async handleInputConfirm(row) { // trim() 去除字符串两端的空格 if (row.inputValue.trim().length === 0) { row.inputValue = '' row.inputVisible = false return } // 如果没有return,则证明输入的内容,需要做后续处理 row.attr_vals.push(row.inputValue.trim()) row.inputValue = '' row.inputVisible = false // 发起请求保存操作 const { data: res } = await this.$http.put( `categories/${this.cateId}/attributes/${row.attr_id}`, { attr_name: row.attr_name, attr_sel: row.attr_sel, attr_vals: row.attr_vals.join(' ') } ) if (res.meta.status !== 200) { return this.$message.error('添加修改参数项失败!') } this.$message.success('添加修改参数项成功!') },
此时效果图:
25、删除参数下的可选项
给el-tag标签绑定close事件:
<!--循环渲染tag标签--> <el-tag v-for="(item, i) in scope.row.attr_vals" :key="i" closable @close="handleClosed(scope.row, i)">{{item}}</el-tag>
函数handleClosed:
// 根据索引删除对应参数的可选项 async handleClosed(row, i) { // console.log(row) // console.log(i) row.attr_vals.splice(i, 1) // 发起请求保存操作 const { data: res } = await this.$http.put( `categories/${this.cateId}/attributes/${row.attr_id}`, { attr_name: row.attr_name, attr_sel: row.attr_sel, attr_vals: row.attr_vals.join(' ') } ) if (res.meta.status !== 200) { return this.$message.error('添加修改参数项失败!') } this.$message.success('添加修改参数项成功!') }
发现保存操作的代码重复了,可以单独提出来写一个函数,独立出来后记得把上面的handleInputConfirm函数也修改下:
// 文本框失去焦点或按下回车键时都会触发 handleInputConfirm(row) { // trim() 去除字符串两端的空格 if (row.inputValue.trim().length === 0) { row.inputValue = '' row.inputVisible = false return } // 如果没有return,则证明输入的内容,需要做后续处理 row.attr_vals.push(row.inputValue.trim()) row.inputValue = '' row.inputVisible = false // 发起请求保存操作 this.saveAttrVals(row) }, // 将对 attr_vals 的操作保存到数据库 async saveAttrVals(row) { // 发起请求保存操作 const { data: res } = await this.$http.put( `categories/${this.cateId}/attributes/${row.attr_id}`, { attr_name: row.attr_name, attr_sel: row.attr_sel, attr_vals: row.attr_vals.join(' ') } ) if (res.meta.status !== 200) { return this.$message.error('添加修改参数项失败!') } this.$message.success('添加修改参数项成功!') }, // 根据索引删除对应参数的可选项 handleClosed(row, i) { // console.log(row) // console.log(i) row.attr_vals.splice(i, 1) // 发起请求保存操作 this.saveAttrVals(row) }
效果图:
26、小bug清空表格数据
因为我们设置了只允许选中三级分类,但是当选中三级分类后,又选中二级分类时,下面表格中的三级数据还有显示。
修改cateChanged函数:
// 级联选择框选中项变化,会触发这个函数 cateChanged() { // 证明选中的不是三级分类 if (this.selectedCateKeys.length !== 3) { this.selectedCateKeys = [] this.manyTableData = [] this.onlyTableData = [] return } // 证明选中的是三级分类 console.log(this.selectedCateKeys) this.getParamsList() },
27、完成静态属性表格中的展开列效果
把动态参数的展开列代码,复制一份,粘贴到静态属性的展开列中就可以了。
<!--展开列--> <el-table-column type="expand"> <template slot-scope="scope"> <!--循环渲染tag标签--> <el-tag v-for="(item, i) in scope.row.attr_vals" :key="i" closable @close="handleClosed(scope.row, i)">{{item}}</el-tag> <!--输入文本框--> <el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(scope.row)" @blur="handleInputConfirm(scope.row)" > </el-input> <!--添加的按钮--> <el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button> </template> </el-table-column>
ok,测试可以没问题。
28、将本地goods_params分支的代码推送到远程
查看分支:
git branch
查看状态:
git status
保存到暂存区:
git add .
提交到本地仓库:
git commit -m "完成了分类参数的开发"
推送到远程:
git push
合并到master:
git checkout master
git merge goods_params
git push