Vue實(shí)現(xiàn)極致舒適的可編輯表格
使用ElementPlus的Table啥都好,就是沒有可編輯表格?。?!
既然UI庫(kù)不支持,那我們實(shí)現(xiàn)一個(gè)可編輯表格是很難的事么?難么?不難么?...
個(gè)人覺得如果是業(yè)務(wù)固定的可編輯表格,使用ElementPlus實(shí)現(xiàn)都不難。但是如果需要的是一個(gè)通用的可編輯表格,這好像還真說不好。
對(duì)于通用的可編輯表格,網(wǎng)上的實(shí)現(xiàn)方案也是五花八門,但是看下來多少都有些問題。個(gè)人認(rèn)為一個(gè)通用的可編輯表格需要給使用方提供以下能力:
- 支持新增、刪除、編輯、保存
- 定義可編輯列
- 定義表單組件,既可以是原生標(biāo)簽,也可以是自定義組件
- 定義表單校驗(yàn)規(guī)則
- 定義數(shù)據(jù)展示部分
- 定義操作區(qū)域
- 幾乎無學(xué)習(xí)成本
實(shí)現(xiàn)了以上需求的可編表格,就可以滿足基本的生產(chǎn)需求了。
在<el-table>
組件的基礎(chǔ)上實(shí)現(xiàn)可編輯表格,保留<el-table>
的使用方式不變,還能提供可編輯功能。同時(shí)可編輯功能的配置與<el-table>
的使用風(fēng)格一致,降低學(xué)習(xí)成本。
準(zhǔn)備數(shù)據(jù)
const tableData = [ { date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', }, { date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', }, { date: '2016-05-04', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', }, { date: '2016-05-01', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', }, ]
基礎(chǔ)表格
基礎(chǔ)表格的用法與<el-table>
幾乎沒有區(qū)別,唯一的不同就是<el-table>
中的data
,在<EditTable>
中被data-source
替換。
<section> <h1>無編輯效果</h1> <EditTable class="edit-table" :data-source="tableData"> <EditTableColumn prop="date" label="時(shí)間"> </EditTableColumn> <EditTableColumn prop="name" label="姓名"> </EditTableColumn> <EditTableColumn prop="address" label="地址"> </EditTableColumn> </EditTable> </section>
可修改表格
<EditTableColumn>
存在一個(gè)#default
默認(rèn)插槽和一個(gè)#edit
具名插槽,默認(rèn)插槽和具名插槽都提供了row
、actions
、$index
等值。
可修改表格是在基礎(chǔ)表格上給<EditTableColumn>
添加名為edit
的具名插槽<template #edit>
。
- 通過
row
可以獲取到當(dāng)前行的數(shù)據(jù)。插槽中的表單組件可通過v-model="row.*"
對(duì)編輯值進(jìn)行雙向綁定。 - 通過
actions
可以獲取編輯表格的能力,通過action.startEditable($index)
開啟編輯,action.cancelEditable($index)
取消編輯,action.saveEditable
保存編輯。
<section> <h1>可編輯效果</h1> <EditTable class="edit-table" :data-source="tableData"> <EditTableColumn prop="date" label="時(shí)間"> <template #edit="{ row }"> <input v-model="row.date" /> </template> </EditTableColumn> <EditTableColumn prop="name" label="姓名"> <template #edit="{ row }"> <input v-model="row.name" /> </template> </EditTableColumn> <EditTableColumn prop="address" label="地址"> <template #edit="{ row }"> <input v-model="row.address" /> </template> </EditTableColumn> <EditTableColumn label="操作"> <template #default="{ actions, $index }"> <button @click="actions.startEditable($index)">操作</button> </template> <template #edit="{ actions, $index }"> <button @click="actions.saveEditable($index)">保存</button> <button @click="actions.cancelEditable($index)">取消</button> </template> </EditTableColumn> </EditTable> </section>
刪除效果
在上述表格的操作區(qū)域增加刪除按鈕,刪除按鈕點(diǎn)擊時(shí)調(diào)用actions.delete($index)
用來刪除當(dāng)前行。
<section> <h1>刪除效果</h1> <EditTable class="edit-table" :data-source="tableData"> <EditTableColumn prop="date" label="時(shí)間"> <template #edit="{ row }"> <input v-model="row.date" /> </template> </EditTableColumn> <EditTableColumn prop="name" label="姓名"> <template #edit="{ row }"> <input v-model="row.name" /> </template> </EditTableColumn> <EditTableColumn prop="address" label="地址"> <template #edit="{ row }"> <input v-model="row.address" /> </template> </EditTableColumn> <EditTableColumn label="操作"> <template #default="{ actions, $index }"> <button @click="actions.startEditable($index)">操作</button> <button @click="actions.deleteRow($index)">刪除</button> </template> <template #edit="{ actions, $index }"> <button @click="actions.saveEditable($index)">保存</button> <button @click="actions.cancelEditable($index)">取消</button> <button @click="actions.deleteRow($index)">刪除</button> </template> </EditTableColumn> </EditTable> </section>
新增效果
組件<EditTable>
并不需要提供新增按鈕,如果直接將新增按鈕封裝在組件內(nèi),那么這個(gè)組件就太呆了。因此<EditTable>
只提供了actions.addRow
方法,調(diào)用方可以根據(jù)自己的需求完成新增功能。
<script lang="ts" setup> import { ref } from 'vue'; import EditTable from '@/components/EditTable.vue'; import EditTableColumn from '@/components/EditTableColumn.vue'; const tableData = [...]; const addEditTableRef = ref<InstanceType<typeof EditTable>>(); </script> <template> <div class="wrapper"> <section> <h1>新增效果</h1> <EditTable ref="addEditTableRef" class="edit-table" :data-source="tableData"> <EditTableColumn prop="date" label="時(shí)間"> <template #edit="{ row }"> <input v-model="row.date" /> </template> </EditTableColumn> <EditTableColumn prop="name" label="姓名"> <template #edit="{ row }"> <input v-model="row.name" /> </template> </EditTableColumn> <EditTableColumn prop="address" label="地址"> <template #edit="{ row }"> <input v-model="row.address" /> </template> </EditTableColumn> <EditTableColumn label="操作"> <template #default="{ actions, $index }"> <button @click="actions.startEditable($index)">操作</button> <button @click="actions.deleteRow($index)">刪除</button> </template> <template #edit="{ actions, $index }"> <button @click="actions.saveEditable($index)">保存</button> <button @click="actions.cancelEditable($index)">取消</button> <button @click="actions.deleteRow($index)">刪除</button> </template> </EditTableColumn> </EditTable> <button @click="addEditTableRef?.editActions.addRow()">新增</button> </section> </div> </template>
表單校驗(yàn)
組件<EditTableColumn>
允許驗(yàn)證用戶的輸入是否符合規(guī)范,來找到和糾正錯(cuò)誤。只需要為<EditTableColumn :rules="rules">
的rules
屬性傳入約定的驗(yàn)證規(guī)則,高級(jí)用法可參考async-validator
。
總之校驗(yàn)規(guī)則和表單的校驗(yàn)規(guī)則一致。
<section> <h1>表單校驗(yàn)效果</h1> <EditTable ref="formEditTableRef" class="edit-table" :data-source="tableData"> <EditTableColumn prop="date" label="時(shí)間" :rules="[{ required: true, message: '時(shí)間是必填項(xiàng)', trigger: 'blur' }]" > <template #edit="{ row }"> <input v-model="row.date" /> </template> </EditTableColumn> <EditTableColumn prop="name" label="姓名" :rules="[{ required: true, message: '姓名是必填項(xiàng)', trigger: 'blur' }]" > <template #edit="{ row }"> <input v-model="row.name" /> </template> </EditTableColumn> <EditTableColumn prop="address" label="地址" :rules="[{ required: true, message: '地址是必填項(xiàng)', trigger: 'blur' }]" > <template #edit="{ row }"> <input v-model="row.address" /> </template> </EditTableColumn> <EditTableColumn label="操作"> <template #default="{ actions, $index }"> <button @click="actions.startEditable($index)">操作</button> <button @click="actions.deleteRow($index)">刪除</button> </template> <template #edit="{ actions, $index }"> <button @click="actions.saveEditable($index)">保存</button> <button @click="actions.cancelEditable($index)">取消</button> <button @click="actions.deleteRow($index)">刪除</button> </template> </EditTableColumn> </EditTable> <button @click="formEditTableRef?.editActions.addRow()">新增</button> </section>
獲取編輯后的表單數(shù)據(jù)
組件<EditTable>
對(duì)外暴露了resultData
響應(yīng)式對(duì)象,可以用來獲取表格的最新數(shù)據(jù)。
<section> <h1>獲取編輯結(jié)果</h1> <EditTable ref="formEditTableRef" class="edit-table" :data-source="tableData"> <EditTableColumn prop="date" label="時(shí)間" :rules="[{ required: true, message: '時(shí)間是必填項(xiàng)', trigger: 'blur' }]" > <template #edit="{ row }"> <input v-model="row.date" /> </template> </EditTableColumn> <EditTableColumn prop="name" label="姓名" :rules="[{ required: true, message: '姓名是必填項(xiàng)', trigger: 'blur' }]" > <template #edit="{ row }"> <input v-model="row.name" /> </template> </EditTableColumn> <EditTableColumn prop="address" label="地址" :rules="[{ required: true, message: '地址是必填項(xiàng)', trigger: 'blur' }]" > <template #edit="{ row }"> <input v-model="row.address" /> </template> </EditTableColumn> <EditTableColumn label="操作"> <template #default="{ actions, $index }"> <button @click="actions.startEditable($index)">操作</button> <button @click="actions.deleteRow($index)">刪除</button> </template> <template #edit="{ actions, $index }"> <button @click="actions.saveEditable($index)">保存</button> <button @click="actions.cancelEditable($index)">取消</button> <button @click="actions.deleteRow($index)">刪除</button> </template> </EditTableColumn> </EditTable> <button @click="formEditTableRef?.editActions.addRow()">新增</button> <p>獲取數(shù)據(jù):{{ formEditTableRef?.resultData }}</p> </section>
另一種數(shù)據(jù)配置
組件<EditTable>
除了支持data-source
的方式配置數(shù)據(jù)外,還支持request
屬性傳入返回?cái)?shù)據(jù)的函數(shù)。
<script lang="ts" setup name="Page-B"> import { ref } from 'vue'; import EditTable from '@/components/EditTable.vue'; import EditTableColumn from '@/components/EditTableColumn.vue'; const loadData = async () => [ { date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', }, { date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', }, { date: '2016-05-04', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', }, { date: '2016-05-01', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', }, ]; </script> <template> <div class="wrapper"> <section> <h1>另一種數(shù)據(jù)配置</h1> <EditTable class="edit-table" :request="loadData"> <EditTableColumn prop="date" label="時(shí)間"> </EditTableColumn> <EditTableColumn prop="name" label="姓名"> </EditTableColumn> <EditTableColumn prop="address" label="地址"> </EditTableColumn> </EditTable> </section> </div> </template>
以上就是Vue實(shí)現(xiàn)極致舒適的可編輯表格的詳細(xì)內(nèi)容,更多關(guān)于Vue可編輯表格的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue中v-form標(biāo)簽里的:rules作用及定義方法
文章介紹了在Vue項(xiàng)目中使用ElementUI或ElementPlus組件庫(kù)時(shí),如何通過`el-form`標(biāo)簽的`:rules`屬性進(jìn)行表單驗(yàn)證,`:rules`屬性用于定義表單項(xiàng)的驗(yàn)證規(guī)則,包括必填項(xiàng)、格式校驗(yàn)、長(zhǎng)度限制等,文章還展示了如何定義基本驗(yàn)證規(guī)則和自定義驗(yàn)證函數(shù),感興趣的朋友一起看看吧2025-03-03關(guān)于vue-tree-chart簡(jiǎn)單的使用
這篇文章主要介紹了關(guān)于vue-tree-chart簡(jiǎn)單的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08Vue3時(shí)間軸組件問題記錄(時(shí)間信息收集組件)
本文介紹了如何在Vue3項(xiàng)目中封裝一個(gè)時(shí)間信息收集組件,采用雙向綁定響應(yīng)式數(shù)據(jù),通過對(duì)Element-Plus的Slider組件二次封裝,實(shí)現(xiàn)時(shí)間軸功能,解決了小數(shù)計(jì)算導(dǎo)致匹配問題和v-model綁定組件無效問題,感興趣的朋友跟隨小編一起看看吧2024-09-09vue開發(fā)中的base和publicPath的區(qū)別
本文主要介紹了vue開發(fā)中的base和publicPath的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07簡(jiǎn)單了解Vue + ElementUI后臺(tái)管理模板
這篇文章主要介紹了簡(jiǎn)單了解Vue + ElementUI后臺(tái)管理模板,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Element實(shí)現(xiàn)登錄+注冊(cè)的示例代碼
登錄注冊(cè)是最常用的網(wǎng)站功能,本文主要介紹了Element實(shí)現(xiàn)登錄+注冊(cè)的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09