Vue3 + Element Plus 表格排序实战:基于状态字段的智能排序方案

一、引言

在开发管理系统时,表格排序是常见需求。本文以自动播报列表为例,介绍在 Vue3 + Element Plus 中如何实现按状态字段排序,让未处理项优先显示。

二、业务场景

在自动播报列表中,需要:

  • 未播报(status: 0)优先显示
  • 已播报(status: 1)排在后面
  • 数据变化时自动重新排序

三、解决方案:使用 Vue3 计算属性

3.1 核心思路

使用 Vue3 的 computed 对原始数据排序,生成排序后的数组供表格使用。这样:

  • 响应式:数据变化时自动更新
  • 性能:仅依赖变化时重新计算
  • 解耦:不修改原始数据

3.2 代码实现

javascript 复制代码
<script setup lang="ts">
import { computed, reactive } from "vue";

const par = reactive({
    tableData: [
        { id: 4276, status: 0, content: '未播报事件1' },
        { id: 4271, status: 0, content: '未播报事件2' },
        { id: 4273, status: 1, content: '已播报事件1' },
        { id: 4274, status: 1, content: '已播报事件2' },
        // ... 更多数据
    ],
    // ... 其他属性
});

// 排序后的表格数据:未播报(status: 0)排在已播报(status: 1)前面
const sortedTableData = computed(() => {
    return [...par.tableData].sort((a, b) => {
        // 按 status 排序:0(未播报)在前,1(已播报)在后
        return a.status - b.status;
    });
});
</script>

<template>
    <el-table 
        v-loading="par.loading" 
        :data="sortedTableData" 
        style="width: 100%" 
        row-key="id"
    >
        <!-- 表格列定义 -->
    </el-table>
</template>

3.3 关键点解析

  1. 使用扩展运算符 [...par.tableData]:创建新数组,避免修改原数组
  2. sort() 比较函数:a.status - b.status 实现升序(0 在前,1 在后)
  3. computed 响应式:par.tableData 变化时自动重新计算

四、扩展:多条件排序

4.1 多字段排序示例

javascript 复制代码
const sortedTableData = computed(() => {
    return [...par.tableData].sort((a, b) => {
        // 第一优先级:按 status 排序(0在前,1在后)
        if (a.status !== b.status) {
            return a.status - b.status;
        }
        // 第二优先级:status 相同时,按 level 排序(1>2>3)
        if (a.level !== b.level) {
            return a.level - b.level;
        }
        // 第三优先级:按创建时间倒序(最新的在前)
        return new Date(b.creationTime).getTime() - new Date(a.creationTime).getTime();
    });
});

4.2 可配置排序

javascript 复制代码
const sortConfig = reactive({
    field: 'status',      // 排序字段
    order: 'asc'          // 排序方向:asc 升序,desc 降序
});

const sortedTableData = computed(() => {
    return [...par.tableData].sort((a, b) => {
        const aVal = a[sortConfig.field];
        const bVal = b[sortConfig.field];
        
        if (aVal === bVal) return 0;
        
        const result = aVal > bVal ? 1 : -1;
        return sortConfig.order === 'asc' ? result : -result;
    });
});

五、Element Plus 表格自带排序功能

5.1 使用 Element Plus 列排序

javascript 复制代码
<el-table-column 
    prop="status" 
    label="播报状态" 
    sortable
    :sort-method="customSort"
>
    <!-- 列内容 -->
</el-table-column>

5.2 自定义排序方法

javascript 复制代码
const customSort = (a, b) => {
    // 自定义排序逻辑:0在前,1在后
    return a.status - b.status;
};

5.3 两种方案对比

特性 计算属性排序 Element Plus 排序
适用场景6 全局排序、多条件排序 单列排序、用户交互排序
性能 数据量大时需注意 内置优化
灵活性 中等
用户体验 自动排序 用户可控制

六、性能优化建议

6.1 大数据量优化

javascript 复制代码
// 使用防抖,避免频繁排序
import { debounce } from 'lodash-es';

const sortedTableData = computed(() => {
    // 如果数据量很大,可以考虑分页后再排序
    if (par.tableData.length > 1000) {
        // 先分页,再排序
        const pageData = par.tableData.slice(
            (par.page - 1) * par.limit, 
            par.page * par.limit
        );
        return pageData.sort((a, b) => a.status - b.status);
    }
    return [...par.tableData].sort((a, b) => a.status - b.status);
});

6.2 使用 Web Worker(超大数据量)

javascript 复制代码
// worker.js
self.onmessage = function(e) {
    const { data } = e.data;
    const sorted = [...data].sort((a, b) => a.status - b.status);
    self.postMessage(sorted);
};

// 组件中
const sortedTableData = ref([]);

const sortInWorker = (data) => {
    const worker = new Worker('/worker.js');
    worker.postMessage({ data });
    worker.onmessage = (e) => {
        sortedTableData.value = e.data;
        worker.terminate();
    };
};

七、常见排序场景

7.1 数字排序

javascript 复制代码
return a.number - b.number;  // 升序
return b.number - a.number;  // 降序

7.2 字符串排序

javascript 复制代码
return a.name.localeCompare(b.name);  // 中文排序
return a.name > b.name ? 1 : -1;      // 简单排序

7.3 日期排序

javascript 复制代码
return new Date(a.date).getTime() - new Date(b.date).getTime();

八、完整示例代码

javascript 复制代码
<template>
    <div class="broadcast-list">
        <el-table 
            v-loading="par.loading" 
            :data="sortedTableData" 
            style="width: 100%" 
            row-key="id"
            @row-click="handleRowClick"
        >
            <el-table-column prop="id" label="事件编号" />
            <el-table-column prop="type" label="事件类型" />
            <el-table-column prop="content" label="事件内容" />
            <el-table-column label="播报状态">
                <template #default="scope">
                    <span v-if="scope.row.status === 0">未播报</span>
                    <span v-else>已播报</span>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script setup lang="ts">
import { computed, reactive } from "vue";

const par = reactive({
    loading: false,
    tableData: [] as any[],
});

// 排序后的表格数据
const sortedTableData = computed(() => {
    return [...par.tableData].sort((a, b) => {
        // 未播报(0)在前,已播报(1)在后
        return a.status - b.status;
    });
});

const handleRowClick = (row: any) => {
    console.log('点击行:', row);
};
</script>

九、总结

  1. 使用 computed 实现响应式排序,代码简洁
  2. 通过扩展运算符避免修改原数组
  3. 多条件排序时按优先级依次比较
  4. 大数据量时考虑分页或 Web Worker
  5. 根据场景选择计算属性排序或 Element Plus 列排序

创作不易,如果对你有帮助的话可以评论留言或者点赞收藏+关注哦

相关推荐
再吃一根胡萝卜1 小时前
从 Element UI 到 Element Plus:el-table 大数据量性能为何下降了?
前端
转转技术团队1 小时前
转转UI自动化走查方案探索
前端
yzx9910131 小时前
基于Flask的智能语音增强系统模拟
前端·javascript·html
青衫码上行1 小时前
【Java Web学习 | 第14篇】JavaScript(8) -正则表达式
java·前端·javascript·学习·正则表达式
我的虾分发2 小时前
虾分发是一个键打包封装APP内测分发平台
javascript
草帽lufei2 小时前
解锁AI新维度:深入体验Google Antigravity的Gemini3模型
前端·ai编程·gemini
CoolerWu2 小时前
TRAE SOLO实战:一个所见即所得的笔记软体
前端·trae
没落英雄2 小时前
简单了解 shadowDom
前端·html
天才熊猫君2 小时前
vue3 基于 el-table 的无限滚动自定义指令实现
前端·javascript