动态表格在 Vue 3 中的实现指南【前端】

目录

什么是动态表格

动态表格(Dynamic Table)是指:

  • 表格结构和内容在运行时可以动态生成或修改。
  • 表头和数据行不固定,可根据后端接口或前端逻辑生成。
  • 支持排序、筛选、分页、可编辑、操作按钮等复杂交互。

区别于静态表格:静态表格表头固定,无法灵活应对动态数据。

使用场景

  • 管理后台数据列表(用户管理、订单管理)
  • 数据报表系统
  • 可编辑的数据录入表格
  • 数据对比与分析平台

基础实现方式

HTML + Vue 3

代码展示:

最基础的动态表格实现方式是利用 Vue 3 的 v-for 渲染表头和内容:

javascript 复制代码
<template>
  <table border="1">
    <thead>
      <tr>
        <th v-for="column in columns" :key="column.key">
          {{ column.label }}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="row in tableData" :key="row.id">
        <td v-for="column in columns" :key="column.key">
          {{ row[column.key] }}
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script setup>
import { ref } from 'vue'

const columns = ref([
  { key: 'id', label: 'ID' },
  { key: 'name', label: '姓名' },
  { key: 'age', label: '年龄' }
])

const tableData = ref([
  { id: 1, name: '张三', age: 18 },
  { id: 2, name: '李四', age: 22 },
  { id: 3, name: '王五', age: 20 }
])
</script>

特点:

  • 表头和内容完全动态生成
  • 可配合后端 API 动态加载数据(响应式数据绑定)

动态表格常用功能

排序

可以使用数组的 sort 或第三方库提供的排序功能

javascript 复制代码
<th @click="sort('age')">年龄</th>

<script setup>
const sort = (key) => {
  tableData.value.sort((a, b) => a[key] - b[key])
}
</script>

筛选

使用 computed 来过滤数据:

javascript 复制代码
<input v-model="searchName" placeholder="搜索姓名" />

<tr v-for="row in filteredData" :key="row.id">
  ...
</tr>

<script setup>
import { ref, computed } from 'vue'

const searchName = ref('')

const filteredData = computed(() =>
  tableData.value.filter(row => row.name.includes(searchName.value))
)
</script>

分页

简单的分页逻辑:

javascript 复制代码
const currentPage = ref(1)
const pageSize = ref(5)

const pagedData = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value
  return tableData.value.slice(start, start + pageSize.value)
})

可编辑单元格

结合 v-model 实现单元格编辑:

javascript 复制代码
<td v-for="column in columns" :key="column.key">
  <input v-model="row[column.key]" />
</td>

使用第三方库实现动态表格

Element Plus

javascript 复制代码
<template>
  <el-input v-model="searchName" placeholder="搜索姓名" style="margin-bottom: 10px;" />
  <el-table :data="filteredData" style="width: 100%">
    <el-table-column prop="id" label="ID" sortable></el-table-column>
    <el-table-column prop="name" label="姓名" sortable>
      <template #default="{ row }">
        <el-input v-model="row.name"></el-input>
      </template>
    </el-table-column>
    <el-table-column prop="age" label="年龄" sortable></el-table-column>
    <el-table-column prop="email" label="邮箱"></el-table-column>
  </el-table>
  <el-pagination
    v-model:current-page="currentPage"
    :page-size="pageSize"
    :total="tableData.length"
    style="margin-top: 10px;"
  ></el-pagination>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import axios from 'axios'

const tableData = ref([])
const searchName = ref('')
const currentPage = ref(1)
const pageSize = ref(5)

onMounted(async () => {
  const res = await axios.get('/api/users')
  tableData.value = res.data
})

const filteredData = computed(() => {
  const filtered = tableData.value.filter(row => row.name.includes(searchName.value))
  const start = (currentPage.value - 1) * pageSize.value
  return filtered.slice(start, start + pageSize.value)
})
</script>

Naive UI

javascript 复制代码
<template>
  <n-data-table
    :columns="columns"
    :data="tableData"
    :bordered="true"
  />
</template>

<script setup>
import { ref, h } from 'vue'
import { NButton } from 'naive-ui'

const columns = [
  { title: 'ID', key: 'id' },
  { title: '姓名', key: 'name' },
  { title: '年龄', key: 'age' },
  {
    title: '操作',
    key: 'actions',
    render(row) {
      return h(NButton, { type: 'primary', size: 'small', onClick: () => alert('编辑: ' + row.name) }, { default: () => '编辑' })
    }
  }
]

const tableData = ref([
  { id: 1, name: '张三', age: 18 },
  { id: 2, name: '李四', age: 22 }
])
</script>

特点:

  • columns 配置化
  • 支持 render 自定义渲染单元格
  • 非常适合中后台业务系统

性能优化与注意事项

  • 大数据量表格建议使用虚拟滚动(Element Plus virtual-scroll 或 Naive UI virtual-scroll)
  • 避免在 v-for 中写复杂逻辑,尤其是计算密集型操作
  • 分页、筛选尽量在服务端处理,避免一次性加载全部数据
  • 自定义操作列用 render或插槽,保持表格组件可复用
相关推荐
SwJieJie11 小时前
Day 3|表格表单分页范式与 vue-request 最佳实践:从配置驱动到业务落地
前端·javascript·vue.js
ZengLiangYi11 小时前
任务队列设计:p-queue 限速 + 重试策略
前端·javascript·后端
sugar__salt11 小时前
从零吃透 ES6 核心:变量声明、作用域、变量提升与坑点
前端·javascript·ecmascript·es6
罗超驿11 小时前
1.HTML基础入门:标签、属性与路径详解(VSCode开发环境)
前端·vscode·html
Dante丶11 小时前
Codex Desktop 不断 Reconnecting 的代理环境变量处理
前端·后端·代码规范
Asmewill11 小时前
LangGraph学习笔记五(Command+Send+Runtime)
前端
代码搬运媛11 小时前
【前端必知】浏览器原生 API 底层机制详解
前端
咔咔库奇11 小时前
js-执行上下文
开发语言·前端·javascript
咪饭只吃一小碗11 小时前
JS 打工记:同步搬砖、异步摸鱼,Promise 来救场
前端·javascript·面试