逐行详细代码解释
第一部分:template模板部分
vue
<template>
<!-- 根容器 -->
<div>
<!-- Element UI表格组件,用于展示商品信息 -->
<el-table
:data="goodsInfo" <!-- 绑定表格数据源,来自props中的goodsInfo -->
stripe <!-- 启用斑马纹样式 -->
:header-cell-style="{ background: '#f5f7fa', color: '#303133' }" <!-- 设置表头背景与文字颜色-->
>
<!-- 第一列:商品编码 -->
<el-table-column
prop="goodsNo" <!-- 绑定数据字段goodsNo -->
label="商品编码" <!-- 列标题 -->
align="center" <!-- 内容居中对齐 -->
show-overflow-tooltip <!-- 内容溢出时悬浮提示 -->
/>
<!-- 第二列:序列号管理 -->
<el-table-column
label="序列号管理"
align="center"
show-overflow-tooltip>
<!-- 使用作用域插槽自定义单元格内容 -->
<template slot-scope="scope"> <!-- 在 Vue 2 中,自定义列内容需要用具名插槽,声明一个插槽作用域对象,Element UI 会把当前行、列等信息注入到这个对象里。这里取名 scope,常用字段:scope.row 当前行的数据对象;scope.$index 当前行的索引;scope.column 当前列配置。 -->
<!-- 如果是序列号管理商品,显示可点击的链接 -->
<el-link <!--使用 Element UI 的链接组件-->
v-if="isTrue(scope.row.snFlag)" <!-- 条件判断,调用isTrue方法 -->
type="primary" <!-- 觉风格设为主色调(蓝色) -->
@click="openDetail(scope.row, 'sn')" <!-- 点击事件,传入行数据和类型 -->
>
是 <!-- 链接显示文本 -->
</el-link>
<!-- 否则显示普通文本 -->
<span v-else>否</span>
</template>
</el-table-column>
<!-- 第三列:箱规管理(逻辑与第二列类似) -->
<el-table-column label="箱规管理" align="center" show-overflow-tooltip>
<template slot-scope="scope">
<el-link
v-if="isCarton(scope.row)" <!-- 使用isCarton方法判断 -->
type="primary"
@click="openDetail(scope.row, 'carton')" <!-- 传入类型'carton' -->
>
是
</el-link>
<span v-else>否</span>
</template>
</el-table-column>
<!-- 第四列:保质期商品(逻辑与第二列类似) -->
<el-table-column label="保质期商品" align="center" show-overflow-tooltip>
<template slot-scope="scope">
<el-link
v-if="isTrue(scope.row.lifeFlag)" <!-- 判断lifeFlag字段 -->
type="primary"
@click="openDetail(scope.row, 'life')" <!-- 传入类型'life' -->
>
是
</el-link>
<span v-else>否</span>
</template>
</el-table-column>
<!-- 第五列:是否越库 -->
<el-table-column label="是否越库" align="center" show-overflow-tooltip>
<template slot-scope="scope">
<!-- 直接使用formatBoolean方法格式化显示 -->
{{ formatBoolean(scope.row.isCrossDocking) }}
</template>
</el-table-column>
<!-- 第六至八列:直接显示数据字段 -->
<el-table-column prop="expectedQty" label="采购量" align="center" show-overflow-tooltip />
<el-table-column prop="receivedQty" label="验收量" align="center" show-overflow-tooltip />
<el-table-column prop="containerNo" label="推荐容器" align="center" show-overflow-tooltip />
</el-table>
<!-- 弹窗组件,用于显示详细信息 -->
<el-dialog
:title="dialogTitle" <!-- 动态绑定对话框标题 -->
:visible.sync="dialogVisible" <!-- 控制对话框显示/隐藏,使用.sync修饰符实现双向绑定 -->
width="60%" <!-- 对话框宽度为视口的60% -->
destroy-on-close <!-- 关闭时销毁对话框内部组件,避免缓存问题 -->
>
<!-- 对话框内容区域 -->
<div>
<!-- 序列号管理详情区域 -->
<div v-if="dialogType === 'sn' && isTrue(dialogRow.snFlag)" class="section">
<h4>序列号管理</h4>
<!-- 序列号规则表格 -->
<el-table
:data="dialogRow.snRulesModels || []" <!-- 数据源,为空时使用空数组避免错误 -->
size="small" <!-- 小尺寸表格 -->
border <!-- 显示边框 -->
empty-text="商品是序列号管理商品,但未维护序列号规则" <!-- 空数据提示文本 -->
>
<!-- 序列号规则表格的各列定义 -->
<el-table-column prop="goodsNo" label="商品编码" align="center" />
<el-table-column prop="snprefixlen" label="序列号前缀长度" align="center" />
<el-table-column prop="snprefix" label="序列号前缀" align="center" />
<el-table-column prop="snsuffixlen" label="序列号后缀长度" align="center" />
<el-table-column prop="snsuffix" label="序列号后缀" align="center" />
<el-table-column prop="snlen" label="序列号长度" align="center" />
<el-table-column prop="regexRule" label="序列号规则" align="center" />
</el-table>
</div>
<!-- 保质期商品详情区域 -->
<div v-if="dialogType === 'life' && isTrue(dialogRow.lifeFlag)" class="section">
<!-- 使用描述列表展示保质期信息 -->
<el-descriptions
:column="2" <!-- 分为2列显示 -->
border <!-- 显示边框 -->
size="small" <!-- 小尺寸 -->
label-width="130px" <!-- 标签宽度 -->
class="desc-block" <!-- 自定义样式类 -->
>
<!-- 各项描述信息 -->
<el-descriptions-item label="商品保质期管理类型">
{{ formatShelfLifeType(dialogRow.shelfLifeMoedel?.shelflifeManagerType) }}
</el-descriptions-item>
<el-descriptions-item label="商品保质天数">
{{ dialogRow.shelfLifeMoedel?.datedurability ?? '-' }} <!-- 使用空值合并运算符提供默认值 -->
</el-descriptions-item>
<el-descriptions-item label="商品三级分类">
{{ dialogRow.shelfLifeMoedel?.goodsTypeNo ?? '-' }}
</el-descriptions-item>
<el-descriptions-item label="三级分类保质期类型(dps)">
{{ dialogRow.shelfLifeMoedel?.dps ?? '-' }}
</el-descriptions-item>
<el-descriptions-item label="保质期限制天数(stock)">
{{ dialogRow.shelfLifeMoedel?.stock ?? '-' }}
</el-descriptions-item>
</el-descriptions>
</div>
<!-- 箱规管理详情区域 -->
<div v-if="dialogType === 'carton' && isCarton(dialogRow)" class="section">
<h4>箱规规则</h4>
<!-- 箱规规则表格 -->
<el-table
:data="dialogRow.boxRuleModels || []"
size="small"
border
empty-text="暂无箱规" <!-- 空数据提示 -->
>
<el-table-column prop="goodsNo" label="商品编码" align="center" />
<el-table-column prop="boxRuleCode" label="箱规编码" align="center" />
<el-table-column prop="boxRuleName" label="箱规名称" align="center" />
<el-table-column prop="baseUnitFlag" label="是否基础单位" align="center">
<!-- 自定义单元格,格式化布尔值显示 -->
<template slot-scope="scope">
{{ formatBoolean(scope.row.baseUnitFlag) }}
</template>
</el-table-column>
</el-table>
</div>
</div>
</el-dialog>
</div>
</template>
第二部分:script脚本部分
javascript
<script>
export default {
// 定义接收的props属性
props: {
goodsInfo: { // 商品信息数据
type: Array, // 类型为数组
default: () => [] // 默认值为空数组
}
},
// 组件内部数据
data() {
return {
dialogVisible: false, // 控制对话框显示/隐藏
dialogRow: null, // 当前操作的行数据
dialogType: '' // 对话框类型:'sn'、'life'、'carton'
}
},
// 计算属性
computed: {
dialogTitle() {
// 根据对话框类型返回对应的标题
const map = {
sn: '序列号规则',
life: '保质期规则',
carton: '箱规规则'
}
return map[this.dialogType] || '商品特殊属性' // 默认标题
}
},
// 组件方法
methods: {
// 格式化布尔值显示为"是"/"否"
formatBoolean(value) {
return this.isTrue(value) ? '是' : '否'
},
// 判断值是否为真(支持多种真值表示)
isTrue(value) {
return value === true || value === 1 || value === '1'
},
// 判断是否为箱规管理商品
isCarton(row) {
return this.isTrue(row?.isCarton) // 使用可选链操作符避免错误
},
// 格式化保质期类型显示
formatShelfLifeType(value) {
const map = {
1: '日',
2: '月',
3: '年'
}
return map[value] || value || '-' // 返回映射值或原值或默认值
},
// 打开详情对话框
openDetail(row, type) {
// 获取各种标志状态
const hasSn = this.isTrue(row.snFlag)
const hasLife = this.isTrue(row.lifeFlag)
const hasCarton = this.isCarton(row)
// 根据类型和对应标志判断是否允许打开对话框
if (type === 'sn' && !hasSn) return
if (type === 'life' && !hasLife) return
if (type === 'carton' && !hasCarton) return
// 如果没有任何特殊属性,则不打开
if (!hasSn && !hasLife && !hasCarton) return
// 设置对话框数据并显示
this.dialogRow = row
this.dialogType = type
this.dialogVisible = true
}
}
}
</script>
第三部分:style样式部分
scss
<style lang="scss" scoped>
// 全局表格样式调整
:deep(.el-table) { // 使用深度选择器穿透scoped限制,修改Element UI组件内部样式
.el-table__header-wrapper {
.el-table__header {
th {
font-weight: 600; // 表头字体加粗
}
}
}
.el-table__body-wrapper {
.el-table__body {
td {
padding: 12px 0; // 表格单元格上下内边距
}
}
}
}
// 详情区域区块样式
.section {
margin-top: 12px; // 区块上边距
h4 {
margin: 0 0 8px 0; // 标题边距
font-size: 14px; // 标题字体大小
font-weight: 600; // 标题字体加粗
color: #303133; // 标题颜色
}
}
// 对话框内容区域样式
:deep(.el-dialog__body) {
max-height: 700px; // 最大高度限制
overflow-y: auto; // 垂直方向溢出时显示滚动条
}
// 描述列表区块样式
.desc-block {
:deep(.el-descriptions__table) {
table-layout: fixed; // 固定表格布局
width: 100%; // 宽度100%
}
:deep(.el-descriptions__label) {
width: 20%; // 标签宽度占20%
white-space: nowrap; // 标签文本不换行
}
:deep(.el-descriptions__content) {
width: 80%; // 内容宽度占80%
word-break: break-all; // 允许在任意字符处换行
}
}
</style>
样式效果

点击"是"之后的弹窗
