带弹窗的页面--以表格形式展示

逐行详细代码解释

第一部分: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>

样式效果

点击"是"之后的弹窗

相关推荐
yuguo.im2 小时前
我开源了一个 GrapesJS 插件
前端·javascript·开源·grapesjs
摘星编程3 小时前
用React Native开发OpenHarmony应用:NFC读取标签数据
javascript·react native·react.js
GISer_Jing3 小时前
AI驱动营销:业务技术栈实战(From AIGC,待总结)
前端·人工智能·aigc·reactjs
GIS之路5 小时前
GDAL 实现影像裁剪
前端·python·arcgis·信息可视化
AGMTI5 小时前
webSock动态注册消息回调函数功能实现
开发语言·前端·javascript
码界奇点5 小时前
基于SpringBoot+Vue的前后端分离外卖点单系统设计与实现
vue.js·spring boot·后端·spring·毕业设计·源代码管理
不会Android的潘潘5 小时前
受限系统环境下的 WebView 能力演进:车载平台 Web 渲染异常的根因分析与优化实践
android·java·前端·aosp
建军啊5 小时前
java web常见lou洞
android·java·前端
阳无5 小时前
宝塔部署的前后端项目从IP访问改成自定义域名访问
java·前端·部署