路由——商品管理
安装:npm install element-plus
main.js配置
import ElementPlus from 'element-plus'
app.use(ElementPlus)
<template> <el-table :data="goodsList" border style="width: 100%"> <el-table-column type="index" label="编号" /> <el-table-column prop="goods_name" label="商品名称" /> <el-table-column prop="goods_price" label="商品价格" /> <el-table-column label="标签"> <!-- 修改1:使用 #default="scope" 代替 v-slot="{ row }",更稳定 --> <template #default="scope"> <!-- 修改2:增加 v-if="scope" 判断,避免解构 undefined --> <div v-if="scope" class="flex gap-2 items-center"> <!-- 修改3:从 scope.row 获取当前行数据 --> <el-tag v-for="(tag, idx) in scope.row.tags" :key="idx" closable disable-transitions @close="() => handleClose(scope.row, tag)" > {{ tag }} </el-tag> <el-input v-if="scope.row.inputVisible" v-model="scope.row.inputValue" size="small" class="w-20" @keyup.enter="() => handleInputConfirm(scope.row)" @blur="() => handleInputConfirm(scope.row)" /> <el-button v-else class="button-new-tag" size="small" @click="() => showInput(scope.row)" > + Tag </el-button> </div> <!-- 数据未加载时显示空白 --> <div v-else>加载中...</div> </template> </el-table-column> <el-table-column label="操作"> <template #default="scope"> <el-button type="danger" plain @click="onRemove(scope.row.id)"> 删除 </el-button> </template> </el-table-column> </el-table> </template> <script setup> import { ref, nextTick } from 'vue' const goodsList = ref([ { id: 1, goods_name: '夏季专柜同款女鞋', goods_price: 298, tags: ['舒适', '透气'], inputVisible: false, inputValue: '' }, { id: 2, goods_name: '冬季保暖女士休闲雪地靴 舒适加绒防水短靴 防滑棉鞋', goods_price: 89, tags: ['保暖', '防滑'], inputVisible: false, inputValue: '' }, { id: 3, goods_name: '秋冬新款女士毛衣 套头宽松针织衫 简约上衣', goods_price: 199, tags: ['秋冬', '毛衣'], inputVisible: false, inputValue: '' }, { id: 4, goods_name: '2023春秋装新款大码女装 衬衫 上衣', goods_price: 19, tags: ['雪纺衫', '打底'], inputVisible: false, inputValue: '' }, { id: 5, goods_name: '长款长袖圆领女士毛衣 2022秋装新款假两件连衣裙', goods_price: 178, tags: ['圆领', '连衣裙'], inputVisible: false, inputValue: '' } ]) const handleClose = (row, tag) => { const idx = row.tags.indexOf(tag) if (idx >= 0) row.tags.splice(idx, 1) } const showInput = async (row) => { row.inputVisible = true await nextTick() // 聚焦输入框(改进选择器) const input = document.querySelector('.el-input__inner:focus') input?.focus() } const handleInputConfirm = (row) => { if (row.inputValue.trim()) { row.tags.push(row.inputValue.trim()) } row.inputValue = '' row.inputVisible = false } const onRemove = (id) => { goodsList.value = goodsList.value.filter(item => item.id !== id) } </script> <style scoped> .flex { display: flex; } .gap-2 { gap: 8px; } .items-center { align-items: center; } .w-20 { width: 80px; } .button-new-tag { height: 24px; line-height: 24px; padding: 0 8px; } </style>