电商后台管理系统商品分类参数可选项的添加与删除

╰+攻爆jí腚メ 2021-07-24 15:23 790阅读 0赞

一 代码

1 修改 Params.vue

  1. <template>
  2. <div>
  3. <!-- 面包屑导航区 -->
  4. <el-breadcrumb separator-class="el-icon-arrow-right">
  5. <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
  6. <el-breadcrumb-item>商品管理</el-breadcrumb-item>
  7. <el-breadcrumb-item>分类参数</el-breadcrumb-item>
  8. </el-breadcrumb>
  9. <!-- 卡片视图区 -->
  10. <el-card>
  11. <!-- 警告区-->
  12. <el-alert title="注意:只允许为第三级分类设置相关参数!" type="warning" :closable=false show-icon>
  13. </el-alert>
  14. <!-- 选择商品分类区域 -->
  15. <el-row class="cat-opt">
  16. <el-col>
  17. <span>商品分类:</span>
  18. <!-- 选择商品分类的级联选择框 -->
  19. <!-- options :指定数据源-->
  20. <!-- props :用来指定配置对象-->
  21. <!-- model :选中的父级分类的Id数组-->
  22. <!-- change :当选中改变时触发的事件-->
  23. <!-- clearable :清空选择-->
  24. <el-cascader
  25. expand-trigger="hover"
  26. v-model="selectedCateKeys"
  27. :options="cateList"
  28. :props="cateProps"
  29. @change="handleChange"
  30. clearable
  31. >
  32. </el-cascader>
  33. </el-col>
  34. </el-row>
  35. <!-- tab 页签区-->
  36. <el-tabs v-model="activeName" @tab-click="handleTabClick">
  37. <!-- 添加 动态参数 面板-->
  38. <el-tab-pane label="动态参数" name="many">
  39. <el-button type="primary" size="mini"
  40. :disabled="isBtnDisable"
  41. @click="addDialogVisible = true"
  42. >添加参数
  43. </el-button>
  44. <!-- 动态参数表格 -->
  45. <el-table :data="manyTableData" border stripe>
  46. <!-- 展开行 -->
  47. <el-table-column type="expand">
  48. <template slot-scope="scope">
  49. <!-- 循环渲染tag标签 -->
  50. <el-tag v-for="(item,i) in scope.row.attr_vals" :key="i" closable
  51. @close="handleClose(i,scope.row)">{
  52. {item}}
  53. </el-tag>
  54. <!-- 输入文本框 -->
  55. <el-input
  56. class="input-new-tag"
  57. v-if="scope.row.inputVisible"
  58. v-model="scope.row.inputValue"
  59. ref="saveTagInput"
  60. size="small"
  61. @keyup.enter.native="handleInputConfirm(scope.row)"
  62. @blur="handleInputConfirm(scope.row)"
  63. >
  64. </el-input>
  65. <!-- 按钮 -->
  66. <el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+
  67. New Tag
  68. </el-button>
  69. </template>
  70. </el-table-column>
  71. <!-- 索引列 -->
  72. <el-table-column type="index"></el-table-column>
  73. <el-table-column label="参数名称" prop="attr_name"></el-table-column>
  74. <el-table-column label="操作">
  75. <template slot-scope="scope">
  76. <el-button type="primary" size="mini" icon="el-icon-edit"
  77. @click="showEditDialog(scope.row.attr_id)">编辑
  78. </el-button>
  79. <el-button type="danger" size="mini"
  80. @click="removeParams(scope.row.attr_id)"
  81. icon="el-icon-delete">删除
  82. </el-button>
  83. </template>
  84. </el-table-column>
  85. </el-table>
  86. </el-tab-pane>
  87. <!-- 添加 静态属性 面板-->
  88. <el-tab-pane label="静态属性" name="only">
  89. <el-button type="primary" size="mini"
  90. :disabled="isBtnDisable"
  91. @click="addDialogVisible = true"
  92. >添加属性
  93. </el-button>
  94. <!-- 静态参数表格 -->
  95. <el-table :data="onlyTableData" border stripe>
  96. <!-- 展开行 -->
  97. <!-- 展开行 -->
  98. <el-table-column type="expand">
  99. <template slot-scope="scope">
  100. <!-- 循环渲染tag标签 -->
  101. <el-tag v-for="(item,i) in scope.row.attr_vals" :key="i" closable
  102. @close="handleClose(i,scope.row)">{
  103. {item}}
  104. </el-tag>
  105. <!-- 输入文本框 -->
  106. <el-input
  107. class="input-new-tag"
  108. v-if="scope.row.inputVisible"
  109. v-model="scope.row.inputValue"
  110. ref="saveTagInput"
  111. size="small"
  112. @keyup.enter.native="handleInputConfirm(scope.row)"
  113. @blur="handleInputConfirm(scope.row)"
  114. >
  115. </el-input>
  116. <!-- 按钮 -->
  117. <el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+
  118. New Tag
  119. </el-button>
  120. </template>
  121. </el-table-column>
  122. <!-- 索引列 -->
  123. <el-table-column type="index"></el-table-column>
  124. <el-table-column label="属性名称" prop="attr_name"></el-table-column>
  125. <el-table-column label="操作">
  126. <template slot-scope="scope">
  127. <el-button type="primary" size="mini" icon="el-icon-edit"
  128. @click="showEditDialog(scope.row.attr_id)">编辑
  129. </el-button>
  130. <el-button type="danger" size="mini"
  131. @click="removeParams(scope.row.attr_id)"
  132. icon="el-icon-delete">删除
  133. </el-button>
  134. </template>
  135. </el-table-column>
  136. </el-table>
  137. </el-tab-pane>
  138. </el-tabs>
  139. </el-card>
  140. <!-- 添加参数的对话框框 -->
  141. <el-dialog
  142. :title="'添加'+titleText"
  143. :visible.sync="addDialogVisible"
  144. width="50%"
  145. @close="addDialogClosed"
  146. >
  147. <!-- 添加参数对话框 -->
  148. <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px">
  149. <el-form-item :label="titleText" prop="attr_name">
  150. <el-input v-model="addForm.attr_name"></el-input>
  151. </el-form-item>
  152. </el-form>
  153. <span slot="footer" class="dialog-footer">
  154. <el-button @click="addDialogVisible = false">取 消</el-button>
  155. <el-button type="primary" @click="addParams">确 定</el-button>
  156. </span>
  157. </el-dialog>
  158. <!-- 修改参数对话框-->
  159. <el-dialog
  160. :title="'修改'+titleText"
  161. :visible.sync="editDialogVisible"
  162. width="50%"
  163. @close="editDialogClosed"
  164. >
  165. <!-- 修改参数对话框 -->
  166. <el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="100px">
  167. <el-form-item :label="titleText" prop="attr_name">
  168. <el-input v-model="editForm.attr_name"></el-input>
  169. </el-form-item>
  170. </el-form>
  171. <span slot="footer" class="dialog-footer">
  172. <el-button @click="editDialogVisible = false">取 消</el-button>
  173. <el-button type="primary" @click="editParams">确 定</el-button>
  174. </span>
  175. </el-dialog>
  176. </div>
  177. </template>
  178. <script>
  179. export default {
  180. name: "Params",
  181. data() {
  182. return {
  183. /* 商品分类列表 */
  184. cateList: [],
  185. /* 级联选择框配置对象*/
  186. cateProps: {
  187. value: 'cat_id',
  188. label: 'cat_name',
  189. children: 'children'
  190. },
  191. /* 级联选择框双向绑定到数组*/
  192. selectedCateKeys: [],
  193. // 被激活页签的名称
  194. activeName: 'many',
  195. // 动态参数的数据
  196. manyTableData: [],
  197. // 静态参数的数据
  198. onlyTableData: [],
  199. // 控制添加对话框的显示和隐藏
  200. addDialogVisible: false,
  201. // 添加参数表单数据对象
  202. addForm: {
  203. attr_name: ''
  204. },
  205. // 添加表单验证规则对象
  206. addFormRules: {
  207. attr_name: [
  208. {required: true, message: '请输入参数名称', trigger: 'blur'}
  209. ]
  210. },
  211. // 控制修改对话框的显示和隐藏
  212. editDialogVisible: false,
  213. // 修改参数表单数据对象
  214. editForm: {
  215. attr_name: '',
  216. attr_id: ''
  217. },
  218. // 修改表单验证规则对象
  219. editFormRules: {
  220. attr_name: [
  221. {required: true, message: '请输入参数名称', trigger: 'blur'}
  222. ]
  223. }
  224. }
  225. },
  226. created() {
  227. this.getCateList()
  228. },
  229. methods: {
  230. // 获取所有商品分类列表
  231. async getCateList() {
  232. const {data: res} = await this.$http.get('categories')
  233. if (res.meta.status !== 200) {
  234. return this.$message.error('获取商品分类失败')
  235. }
  236. this.cateList = res.data
  237. },
  238. // 级联选择框选中项变化,会触发这个函数
  239. handleChange() {
  240. this.getParamList()
  241. },
  242. // tab 页签点击事件的处理函数
  243. handleTabClick() {
  244. this.getParamList()
  245. },
  246. // 获得参数列表数据
  247. async getParamList() {
  248. // 证明选中的不是三级分类
  249. if (this.selectedCateKeys.length !== 3) {
  250. this.selectedCateKeys = []
  251. this.manyTableData = []
  252. this.onlyTableData = []
  253. return
  254. }
  255. // 根据所选分类的id和当前所选的面板,获取对应的参数
  256. const {data: res} = await this.$http.get(`categories/${this.cateId}/attributes`, {
  257. params: {
  258. sel: this.activeName
  259. }
  260. })
  261. if (res.meta.status !== 200) {
  262. return this.$message.error('获取商品参数列表失败')
  263. }
  264. res.data.forEach(item => {
  265. /* 将以空格隔开的字符串转换为数组 */
  266. item.attr_vals = item.attr_vals ? item.attr_vals.split(',') : []
  267. /* 控制文本框的显示和隐藏 */
  268. item.inputVisible = false
  269. /* 文本框中输入的值 */
  270. item.inputValue = ''
  271. });
  272. console.log(res.data)
  273. if (this.activeName === 'many') {
  274. this.manyTableData = res.data
  275. } else {
  276. this.onlyTableData = res.data
  277. }
  278. },
  279. // 对话框的关闭事件监听
  280. addDialogClosed() {
  281. this.$refs.addFormRef.resetFields()
  282. },
  283. // 点击按钮,添加参数
  284. addParams() {
  285. this.$refs.addFormRef.validate(async valid => {
  286. if (!valid) return
  287. const {data: res} = await this.$http.post(`categories/${this.cateId}/attributes`, {
  288. attr_name: this.addForm.attr_name,
  289. attr_sel: this.activeName
  290. })
  291. if (res.meta.status !== 201) {
  292. return this.$message.error('添加商品参数列表')
  293. }
  294. this.$message.success('添加商品参数成功')
  295. this.addDialogVisible = false
  296. this.getParamList()
  297. })
  298. },
  299. // 点击按钮,展示修改对话框
  300. async showEditDialog(attr_id) {
  301. // 查询当前参数的信息
  302. const {data: res} = await this.$http.get(`categories/${this.cateId}/attributes/${attr_id}`, {
  303. params: {
  304. attr_sel: this.activeName
  305. }
  306. })
  307. if (res.meta.status !== 200) {
  308. return this.$message.error('获取参数信息失败')
  309. }
  310. this.editForm = res.data
  311. this.editDialogVisible = true;
  312. },
  313. // 重置修改的表单
  314. editDialogClosed() {
  315. this.$refs.editFormRef.resetFields()
  316. },
  317. // 点击按钮,修改参数
  318. editParams() {
  319. this.$refs.editFormRef.validate(async valid => {
  320. if (!valid) return
  321. const {data: res} = await this.$http.put(`categories/${this.cateId}/attributes/${this.editForm.attr_id}`, {
  322. attr_name: this.editForm.attr_name,
  323. attr_sel: this.activeName
  324. })
  325. if (res.meta.status !== 200) {
  326. return this.$message.error('修改商品参数列表')
  327. }
  328. this.$message.success('修改商品参数成功')
  329. this.editDialogVisible = false
  330. this.getParamList()
  331. })
  332. },
  333. // 点击按钮,删除参数
  334. async removeParams(attr_id) {
  335. const confirmResult = await this.$confirm('此操作将永久删除该参数, 是否继续?', '提示', {
  336. confirmButtonText: '确定',
  337. cancelButtonText: '取消',
  338. type: 'warning'
  339. }).catch(err => err)
  340. if (confirmResult !== 'confirm') {
  341. return this.$message.info('已取消删除!')
  342. }
  343. const {data: res} = await this.$http.delete(`categories/${this.cateId}/attributes/${attr_id}`)
  344. if (res.meta.status !== 200) {
  345. return this.$message.error('删除商品参数列表')
  346. }
  347. this.$message.success('删除商品参数成功')
  348. this.getParamList()
  349. },
  350. // 文本框失去焦点,或摁下了 Enter 都会触发
  351. handleInputConfirm(row) {
  352. if (row.inputValue.trim().length === 0) {
  353. row.inputValue = ''
  354. row.inputVisible = false
  355. return
  356. }
  357. // 如果没有return,则证明输入的内容,需要做后续的处理
  358. row.attr_vals.push(row.inputValue.trim())
  359. row.inputValue = ''
  360. row.inputVisible = false
  361. this.saveAttrVals(row)
  362. },
  363. // 点击按钮,展示输入文本框
  364. showInput(row) {
  365. row.inputVisible = true
  366. /* 让文本框自动获得焦点 */
  367. /* $nextTick:页面中的元素被重新渲染后,才会回调函数中的代码*/
  368. this.$nextTick(_ => {
  369. this.$refs.saveTagInput.$refs.input.focus();
  370. });
  371. },
  372. // 将对save_vals的操作,保存到数据库
  373. async saveAttrVals(row) {
  374. // 需要发起请求,保存到数据库中
  375. const {data: res} = await this.$http.put(`categories/${this.cateId}/attributes/${row.attr_id}`, {
  376. attr_name: row.attr_name,
  377. attr_sel: row.attr_sel,
  378. attr_values: row.attr_vals.join(',')
  379. })
  380. if (res.meta.status !== 200) {
  381. return this.$message.error('修改参数项失败!')
  382. }
  383. this.$message.success('修改参数项成功')
  384. },
  385. // 删除对应的参数可选项目
  386. handleClose(i, row) {
  387. row.attr_vals.splice(i, 1)
  388. this.saveAttrVals(row)
  389. }
  390. },
  391. computed: {
  392. // 如果按钮需要被禁用,返回true
  393. isBtnDisable() {
  394. if (this.selectedCateKeys.length !== 3) {
  395. return true
  396. } else {
  397. return false
  398. }
  399. },
  400. // 当前选中的三级分类的Id
  401. cateId() {
  402. if (this.selectedCateKeys.length === 3) {
  403. return this.selectedCateKeys[2]
  404. }
  405. return null
  406. },
  407. // 动态计算标题文本
  408. titleText() {
  409. if (this.activeName === 'many') {
  410. return '动态参数'
  411. } else {
  412. return '静态属性'
  413. }
  414. }
  415. }
  416. }
  417. </script>
  418. <style scoped>
  419. .cat-opt {
  420. margin: 15px 0;
  421. }
  422. .input-new-tag {
  423. width: 120px;
  424. }
  425. </style>

二 测试

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5ncWl1bWluZw_size_16_color_FFFFFF_t_70

发表评论

表情:
评论列表 (有 0 条评论,790人围观)

还没有评论,来说两句吧...

相关阅读