基于Vue3實(shí)現(xiàn)動(dòng)態(tài)表格的完整指南
什么是動(dòng)態(tài)表格
動(dòng)態(tài)表格(Dynamic Table)是指:
- 表格結(jié)構(gòu)和內(nèi)容在運(yùn)行時(shí)可以動(dòng)態(tài)生成或修改。
- 表頭和數(shù)據(jù)行不固定,可根據(jù)后端接口或前端邏輯生成。
- 支持排序、篩選、分頁(yè)、可編輯、操作按鈕等復(fù)雜交互。
區(qū)別于靜態(tài)表格:靜態(tài)表格表頭固定,無(wú)法靈活應(yīng)對(duì)動(dòng)態(tài)數(shù)據(jù)。
使用場(chǎng)景
- 管理后臺(tái)數(shù)據(jù)列表(用戶管理、訂單管理)
- 數(shù)據(jù)報(bào)表系統(tǒng)
- 可編輯的數(shù)據(jù)錄入表格
- 數(shù)據(jù)對(duì)比與分析平臺(tái)
基礎(chǔ)實(shí)現(xiàn)方式
HTML + Vue 3
代碼展示:
最基礎(chǔ)的動(dòng)態(tài)表格實(shí)現(xiàn)方式是利用 Vue 3 的 v-for 渲染表頭和內(nèi)容:
<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>特點(diǎn):
- 表頭和內(nèi)容完全動(dòng)態(tài)生成
- 可配合后端 API 動(dòng)態(tài)加載數(shù)據(jù)(響應(yīng)式數(shù)據(jù)綁定)
動(dòng)態(tài)表格常用功能
排序
可以使用數(shù)組的 sort 或第三方庫(kù)提供的排序功能:
<th @click="sort('age')">年齡</th>
<script setup>
const sort = (key) => {
tableData.value.sort((a, b) => a[key] - b[key])
}
</script>篩選
使用 computed 來(lái)過(guò)濾數(shù)據(jù):
<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>分頁(yè)
簡(jiǎn)單的分頁(yè)邏輯:
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)
})
可編輯單元格
結(jié)合 v-model 實(shí)現(xiàn)單元格編輯:
<td v-for="column in columns" :key="column.key"> <input v-model="row[column.key]" /> </td>
使用第三方庫(kù)實(shí)現(xiàn)動(dòng)態(tài)表格
Element Plus
<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
<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>特點(diǎn):
- columns 配置化
- 支持 render 自定義渲染單元格
- 非常適合中后臺(tái)業(yè)務(wù)系統(tǒng)
性能優(yōu)化與注意事項(xiàng)
大數(shù)據(jù)量表格建議使用虛擬滾動(dòng)(Element Plus virtual-scroll 或 Naive UI virtual-scroll)
避免在 v-for 中寫復(fù)雜邏輯,尤其是計(jì)算密集型操作
分頁(yè)、篩選盡量在服務(wù)端處理,避免一次性加載全部數(shù)據(jù)
自定義操作列用 render或插槽,保持表格組件可復(fù)用
到此這篇關(guān)于基于Vue3實(shí)現(xiàn)動(dòng)態(tài)表格的完整指南的文章就介紹到這了,更多相關(guān)Vue3動(dòng)態(tài)表格內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 基于Vue3和Element Plus實(shí)現(xiàn)一個(gè)可定制的動(dòng)態(tài)表格列配置組件
- vue基于ElementUI動(dòng)態(tài)設(shè)置表格高度的3種方法
- Vue?3?表格時(shí)間監(jiān)控與動(dòng)態(tài)后端請(qǐng)求觸發(fā)詳解?附Demo展示
- element-plus+Vue3實(shí)現(xiàn)表格數(shù)據(jù)動(dòng)態(tài)渲染
- Vue中如何動(dòng)態(tài)顯示表格內(nèi)容
- Vue動(dòng)態(tài)擴(kuò)展表頭的表格及數(shù)據(jù)方式(數(shù)組嵌套對(duì)象)
相關(guān)文章
Vue關(guān)于訪問(wèn)外鏈?zhǔn)〉膯?wèn)題
這篇文章主要介紹了Vue關(guān)于訪問(wèn)外鏈?zhǔn)〉膯?wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
vue大數(shù)據(jù)表格卡頓問(wèn)題的完美解決方案
這篇文章主要給大家介紹了基于vue大數(shù)據(jù)表格卡頓問(wèn)題的完美解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
vue使用el-upload上傳文件及Feign服務(wù)間傳遞文件的方法
這篇文章主要介紹了vue使用el-upload上傳文件及Feign服務(wù)間傳遞文件的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03
Vue 打包的靜態(tài)文件不能直接運(yùn)行的原因及解決辦法
這篇文章主要介紹了Vue 打包的靜態(tài)文件不能直接運(yùn)行的原因及解決辦法,幫助大家更好的理解和學(xué)習(xí)vue框架,感興趣的朋友可以了解下2020-11-11
Vue項(xiàng)目如何關(guān)閉語(yǔ)法檢查
這篇文章主要介紹了Vue項(xiàng)目如何關(guān)閉語(yǔ)法檢查問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04

