同一个表格组件在不同的页面下展示不同列

1、需求背景

展示一个任务详情页,这个页面有两个入口

  • 任务创建页点击详情进入;

  • 任务开发页点击详情进入。

进入任务详情后,详情中展示子任务列表,子任务列表还要根据不同的页面来源(任务创建页还是任务开发页)和不同的任务状态展示不同的数据列。

以下举出一个示例。

例如,由任务创建页进入任务详情时:

  • 未开始的任务,任务详情中展示的列为:软件名称,提交要求

  • 已开始未提交的任务,任务详情中展示的列为:软件名称,软件版本,当前状态

  • 已提交的任务,任务详情中展示的列为:软件名称,软件版本,提交版本,提交人,提交时间,审核操作

由任务开发页进入任务详情时:

  • 未开始的任务,任务详情中展示的列为:软件名称,提交要求、开发时间

  • 已开始未提交的任务,任务详情中展示的列为:软件名称,软件版本,当前状态,操作列

  • 已提交的任务,任务详情中展示的列为:软件名称,软件版本,提交版本,提交人,提交时间,审核结果

以下就是实现子任务列表组件的过程。

2、实现思路

2.1 组件规划

使用Table组件,我这里使用的是ant-design-vue,3.x的版本。核心要实现的就是如何根据任务状态展示不同的数据列。有三种思路。

1)写多个table,通过v-if结合任务状态来判断显示那个table;

2)写一个table,根据页面来源和任务状态过滤出要显示的数据列;

3)写一个table,列出所有的数据列,在template中通过v-if集合页面来源和任务状态控制显隐。

第一种思路实现起来比较简单,但是会有很多重复代码;第三种会有很多template中的判断;这里我采用了第二种思路。

2.2 数据映射关系

第二种思路,需要梳理数据列和任务状态的关系,首先,将全量的数据列定义出来。

软件名称、提交要求、软件版本、最新进展、操作列、提交版本、提交人、提交时间、审核操作、开发时间、当前状态、审核结果。定义为一组数组。

const allColumns = [
    {
        title: '软件名称',
        dataIndex: 'softwareName',
        width: 150
    },
    {
        title: '提交要求',
        dataIndex: 'require',
        width: 150
    },
    {
        title: '软件版本',
        dataIndex: 'softwareVersion',
        width: 150
    },
    {
        title: '操作列',
        dataIndex: 'operation',
    },
    {
        title: '提交版本',
        dataIndex: 'version',
    },
    {
        title: '提交人',
        dataIndex: 'updateUser',
    },
    {
        title: '提交时间',
        dataIndex: 'updateTime',
        width: 150
    },
    {
        title: '审核操作',
        dataIndex: 'auditOperation',
    },
    {
        title: '开发时间',
        dataIndex: 'startTime',
    },
    {
        title: '当前状态',
        dataIndex: 'currentStatus',
    },
    {
        title: '审核结果',
        dataIndex: 'result',
    }
]

1)任务状态和表格数据列的关系如下表所示

页面来源source任务状态taskStatus数据列dataIndex
任务创建页source=create未开始taskStatus=1软件名称,提交要求
已开始未提交taskStatus=2软件名称,软件版本,当前状态
已提交taskStatus=3软件名称,软件版本,提交版本,提交人,提交时间,审核操作
任务开发页source=develop未开始taskStatus=1软件名称,提交要求、开发时间
已开始未提交taskStatus=2软件名称,软件版本,当前状态,操作列
已提交taskStatus=3软件名称,软件版本,提交版本,提交人,提交时间,审核结果

将以上对应关系,生成一个JSON的映射关系

const columnsMap = {
    /**
     * module:{
     *  statuskey:[item1,item2...]
     * }
     */
    create: {
        // 1-未开始,2-已开始未提交,3-已提交
        1: ['softwareName', 'require'],
        2: ['softwareName', 'softwareVersion', 'currentStatus'],
        3: ['softwareName', 'softwareVersion', 'version', 'updateUser', 'updateTime', 'auditOperation']
    },
    develop: {
        1: ['softwareName', 'require', 'startTime'],
        2: ['softwareName', 'softwareVersion', 'currentStatus', 'operation'],
        3: ['softwareName', 'softwareVersion', 'version', 'updateUser', 'updateTime', 'result']
    }
}

2)写一个方法,根据页面来源和任务状态返回数据列。在template中使用计算属性绑定数据列。

const getColumsByStatus = (fnModule, status) => {
    let res = []
    let transStatus = status.toString()
    if (columnsMap[fnModule]) {
        let arr = columnsMap[fnModule][transStatus]
        allColumns.forEach(item => {
            if (arr.includes(item.dataIndex)) {
                res.push(item)
            }
        })
    }
    return res
}
// 计算属性
const computedCols = computed(() => {
    return getColumsByStatus(query.taskSource, query.taskStatus)
})

//template中的绑定
<Table :columns="computedCols" :data-source="computedDataSource" bordered :pagination="false"></Table>

3、代码实现

页面来源和任务状态参数是通过页面的URL进行传递的,然后通过route.query进行访问。完整代码实现如下所示。

<template>
    <Table :columns="computedCols" :data-source="computedDataSource" bordered :pagination="false">
        <template #bodyCell="{ column, text, record }">
            <template v-if="column.dataIndex === 'auditOperation'">
                <div class="editable-row-operations">
                    <a>审核</a>
                </div>
            </template>
            <template v-if="column.dataIndex === 'operation'">
                <div class="editable-row-operations">
                    <a>操作</a>
                </div>
            </template>
        </template>
    </Table>
</template>
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { Table } from 'ant-design-vue'
import { getTaskDetailList } from '@/api/server'

const route = useRoute()
const query = route.query
const dataSource = ref<any[]>([])
onMounted(() => {
    initData()
})
const initData = async () => {
    // 调接口获取子任务列表
    let res = await getTaskDetailList({
        taskId: query.taskId
    })
    dataSource.value = res?.data || []
}
// 计算属性,返回表格的数据列
const computedCols = computed(() => {
    return getColumsByStatus(query.taskSource, query.taskStatus)
})
// 定义所有的列
const allColumns = [
    {
        title: '软件名称',
        dataIndex: 'softwareName',
        width: 150
    },
    {
        title: '提交要求',
        dataIndex: 'require',
        width: 150
    },
    {
        title: '软件版本',
        dataIndex: 'softwareVersion',
        width: 150
    },
    {
        title: '操作列',
        dataIndex: 'operation',
    },
    {
        title: '提交版本',
        dataIndex: 'version',
    },
    {
        title: '提交人',
        dataIndex: 'updateUser',
    },
    {
        title: '提交时间',
        dataIndex: 'updateTime',
        width: 150
    },
    {
        title: '审核操作',
        dataIndex: 'auditOperation',
    },
    {
        title: '开发时间',
        dataIndex: 'startTime',
    },
    {
        title: '当前状态',
        dataIndex: 'currentStatus',
    },
    {
        title: '审核结果',
        dataIndex: 'result',
    }
]
// 定义页面来源、任务状态和数据列的映射关系
const columnsMap = {
    /**
     * module:{
     *  statuskey:[item1,item2...]
     * }
     */
    create: {
        // 1-未开始,2-已开始未提交,3-已提交
        1: ['softwareName', 'require'],
        2: ['softwareName', 'softwareVersion', 'currentStatus'],
        3: ['softwareName', 'softwareVersion', 'version', 'updateUser', 'updateTime', 'auditOperation']
    },
    develop: {
        1: ['softwareName', 'require', 'startTime'],
        2: ['softwareName', 'softwareVersion', 'currentStatus', 'operation'],
        3: ['softwareName', 'softwareVersion', 'version', 'updateUser', 'updateTime', 'result']
    }
}
// 根据页面来源和任务状态获取数据列的方法
const getColumsByStatus = (fnModule, status) => {
    let res = []
    let transStatus = status.toString()
    if (columnsMap[fnModule]) {
        let arr = columnsMap[fnModule][transStatus]
        allColumns.forEach(item => {
            if (arr.includes(item.dataIndex)) {
                res.push(item)
            }
        })
    }
    return res
}
</script>
<style scoped lang="scss">
.editable-row-operations a {
    margin-right: 8px;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值