#子传父&父传子props和emits #封装的table #vue3

#子传父&父传子props和emits #封装的table #vue3

父组件:emits defineEmits props

子组件:

子组件

bash 复制代码
<template>
 <el-table v-bind="$attrs" ref="innerTableRef" v-loading="loading" border :data="tableData"
    @sort-change="handleSortChange">
<el-table-column v-for="{
      label,
      prop,
      type,
      align,
      width,
      tooltip,
      meta,
      fixed,
      reserveSelection,
      sortable,
    } in visibleColumns" :key="prop" :align="align ?? 'center'" :width="width" :label="label" :prop="prop"
      :show-overflow-tooltip="tooltip ?? true" :type="type" :fixed="fixed" :reserve-selection="reserveSelection"
      :sortable="sortable">
      <template #default="{ row, column: { rawColumnKey } }">
        <template v-if="type === 'operate'">
          <div class="flex justify-evenly">
            <slot :row="row" name="operate" />
          </div>
        </template>
        <template v-else-if="prop">
          <template v-if="type === 'radio'">
            <el-radio v-model="radioVal" class="none-label" :label="row[prop]" @input="onRadioInput(row)" />
          </template>
          <template v-else-if="type === 'link'">
            <template v-if="!meta">
              <el-link class="cell-link" type="primary"
                @click="$emit(`click${getFirstCharUpperCaseProperty(rawColumnKey)}`, row)">{{ row[prop] }}
              </el-link>
            </template>
          </template>
          <template v-else-if="type === 'tag' && meta">
            <el-tag v-if="row[prop] != null" effect="dark" :type="getMetaType(row[prop], meta, 'tag')">
              {{ getMetaLabel(row[prop], meta, 'tag') }}
            </el-tag>
          </template>
          <template v-else-if="type === 'custom'">
            <slot :name="rawColumnKey" :row="row" />
          </template>

          <span v-else>{{ row[prop] }}</span>
        </template>
      </template>
    </el-table-column>
  </el-table>
</template>


<script setup lang="ts">

const emits = defineEmits<{
  sortChange: [data: { column: any, prop: string, order: any }]
}>()
// 表格排序改变事件
function handleSortChange(data: { column: any, prop: string, order: any }) {
  emits('sortChange', data)
}

父组件

bash 复制代码
<template>
<div class="bg-white rounded-md p-2.5 shadow">
    <table-component v-model:page-index="queryParams.pageIndex" v-model:page-size="queryParams.pageSize"
      :table-config="tableData.tableConfig" :table-data="tableData.data" :loading="tableData.loading"
      :total="tableData.totalRows" @fetch="fetchData" @click-sys-uni-code="onClickCode" @sortChange="handleSortChange">

      <template #btn>
        <el-button v-permission="['production_processing:add']" :icon="Plus" type="primary" @click="onHeadEvent('add')">
          添加
        </el-button>
      </template>
      <template #operate="{ row }">
        <el-link v-permission="['production_processing:input']" :icon="View" type="primary"
          @click="onRow('input', row)">
          {{ row.set == true ? '编辑' : '录入' }}
        </el-link>
        <el-link v-permission="['production_processing:delete']" :icon="Delete" type="danger"
          @click="onRow('delete', row)">
          删除
        </el-link>
      </template>
      <template #status="{ row }">
        <template v-if="row.status == ASSEMBLY_ATATUS.PROGRRESS">
          <el-progress :text-inside="true" :stroke-width="15" :percentage="row.progressNumber" />
        </template>
        <template v-if="row.status == ASSEMBLY_ATATUS.NO">
          <el-tag effect="dark" type="danger">未开始</el-tag>
        </template>
        <template v-if="row.status == ASSEMBLY_ATATUS.COMPLETED">
          <el-tag effect="dark" type="success">已完成</el-tag>
        </template>
        <template v-if="row.status == ASSEMBLY_ATATUS.CLOSED">
          <el-tag effect="dark" type="info">已关闭</el-tag>
        </template>
      </template>

      <template #doneTimePreset="{ row }">
        {{ row.doneTimePreset }}
        <triangle border-color="red" title="超"
          v-if="dateVal(nowDate) <= dateVal(row.doneTimePreset) || dateVal(row.doneTimePreset) <= dateVal(row.doneTimeFact)" />
      </template>
      <template #doneTimeFact="{ row }">
        {{ row.doneTimeFact == '' ? '' : row.doneTimeFact.substring(0, 10) }}
        <triangle border-color="red" title="超" v-if="dateVal(nowDate) <= dateVal(row.doneTimeFact)" />
      </template>

    </table-component>
  </div>
<script setup lang="ts">
const queryParams = ref({
  fBillNo: '', //订单编号
  sysUniCode: '', //系统序列码
  fMaterialNumber: '', //物料编号
  fMaterialName: '', //物料名称
  fMaterialSpecification: '', //规格型号
  status: [] as number[], //状态 0未开始 1进行中 2已完成
  srcProjectType: null, //源项目类型 1合同 2研发 3维修
  srcSysUniCode: '', //源项目系统序列码
  pageIndex: 1,
  pageSize: 10,
  outsource: false, //是否筛选加工外协
  OrderBy: null,
  Desc: true
})
const tableData = ref({
  tableConfig: [
    {
      label: '序号',
      type: 'index',
      width: 60
    },
    {
      label: '系统序列号',
      prop: 'sysUniCode',
      type: 'link'
    },
    {
      label: '订单编号',
      prop: 'fBillNo'
    },
    {
      label: '物料编码',
      prop: 'fMaterialNumber'
    },
    {
      label: '物料名称',
      prop: 'fMaterialName'
    },
    {
      label: '规格型号',
      prop: 'fMaterialSpecification'
    },
    {
      label: '单位',
      prop: 'fUnit',
      width: '90'
    },
    {
      label: '数量',
      prop: 'fAmount',
      width: '90'
    },
    {
      label: '合格品入库数量',
      prop: 'okInStock',
      width: '130'
    },
    {
      label: '进度',
      prop: 'status',
      type: 'custom',
      width: '200'
    },
    {
      label: '当前工序',
      prop: 'currProcedure'
    },
    {
      label: '预计完成时间',
      prop: 'doneTimePreset',
      type: 'custom',
      sortable: 'custom',
    },
    {
      label: '实际完成时间',
      prop: 'doneTimeFact',
      type: 'custom',
      sortable: 'custom',
    },
    {
      label: '来源项目',
      prop: 'srcProjectType',
      type: 'tag',
      meta: {
        tagConfig: [
          {
            label: '合同项目',
            value: SOURCE_PROJECT.CONTRACT,
            type: 'primary'
          },
          {
            label: '研发项目',
            value: SOURCE_PROJECT.RESEARCH,
            type: 'warning'
          },
          {
            label: '维修项目',
            value: SOURCE_PROJECT.SERVICE,
            type: 'danger'
          }
        ]
      }
    },
    {
      label: '来源序列号',
      prop: 'srcSysUniCode'
    },
    {
      label: '操作',
      type: 'operate',
      width: 150
    }
  ],
  data: [],
  loading: false,
  totalRows: 0
})
// 排序
function handleSortChange(data: { prop: string, order: string }) {
  console.log(data, 222)
  // 有排序
  if (data.order) {
    console.log(data.prop, (data.prop === 'doneTimePreset' ? 1 : 2));
    queryParams.value.OrderBy = (data.prop === 'doneTimePreset' ? 1 : 2)
    queryParams.value.Desc = (data.order === 'descending')
  } else {
    // 没排序-使用默认排序
    queryParams.value.OrderBy = null
  }
  // 还原成第一页并重新发起请求
  queryParams.value.pageIndex = 1
  fetchData()
}

怎么说呢还是得多看多写

相关推荐
JieE2123 小时前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
冬奇Lab5 小时前
AI Workflow 定义的四次演进:从 Markdown 到 JS 脚本,再到分布式多 Agent
javascript·人工智能·agent
一颗烂土豆11 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
kyriewen13 小时前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
weedsfly16 小时前
迭代器、生成器与异步迭代——让数据“按需流动”的艺术
前端·javascript
假如让我当三天老蒯16 小时前
前端跨域解决方案(学习用)
前端·javascript·面试
铁皮饭盒18 小时前
Bun 哪比 Node.js 快?
javascript·后端
JieE2121 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
candyTong1 天前
RTK 技术原理:一次典型会话里,80% 上下文是怎么省下来的
javascript·后端·架构
_柳青杨1 天前
深入理解 JavaScript 事件循环
前端·javascript