动态表格在 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或插槽,保持表格组件可复用
相关推荐
IT_陈寒1 天前
SpringBoot这个自动配置坑我跳了三次
前端·人工智能·后端
kyriewen1 天前
我用 AI 一周写完了整个项目,上线第一天就崩了——这是我踩过最贵的 5 个坑
前端·javascript·ai编程
Larcher1 天前
AI Loop:让AI像人一样自主完成任务的核心机制
javascript·人工智能·设计模式
默_笙1 天前
🃏 JS 只有 8 种数据类型,但我花了 2 天才搞懂 null 和 undefined 的区别
javascript
牧艺1 天前
从零到协同:构建类飞书在线文档系统的五个技术重难点
前端·人工智能
jump_jump1 天前
流式 HTML:从 htmx 片段装配到浏览器原生增量渲染
javascript·性能优化·前端工程化
红尘散仙1 天前
想写一个像样的终端 App?试试把 React 的开发体验搬进 Rust TUI
前端·rust
袋鼠云数栈UED团队1 天前
一套 Spec-First 的 AI 编程工作流
前端·人工智能
袋鼠云数栈前端1 天前
一套 Spec-First 的 AI 编程工作流
前端·ai+
angerdream1 天前
Android手把手编写儿童手机远程监控App之vue3 路由守卫
前端