Vue+Ant Design進(jìn)行大數(shù)據(jù)量下拉框卡頓與表單提交優(yōu)化
前言
在現(xiàn)代前端開發(fā)中,處理大數(shù)據(jù)量渲染和表單交互是常見的挑戰(zhàn)。本文基于實(shí)際項(xiàng)目中的問題,探討如何優(yōu)化 Ant Design Vue 下拉框(Select)在大數(shù)據(jù)量情況下的性能問題,并解決 表單提交后重復(fù)提示的問題。
我們將從問題現(xiàn)象出發(fā),分析原因,并提供多種優(yōu)化方案,最終形成最佳實(shí)踐。文章包含詳細(xì)代碼示例,適合中高級(jí)前端開發(fā)者閱讀。
1. 問題背景
(1) 大數(shù)據(jù)量下拉框卡頓
在管理后臺(tái)中,我們經(jīng)常遇到需要渲染大量數(shù)據(jù)的下拉選擇框(如廣告位ID選擇)。當(dāng) mediaAdSlotList 數(shù)據(jù)量較大時(shí)(例如超過1000條),Ant Design 的 a-select 會(huì)渲染所有 option,導(dǎo)致 DOM 節(jié)點(diǎn)過多,頁面卡頓。
問題代碼:
<a-select v-decorator="['mediaAdId']" show-search option-filter-prop="children" > <a-select-option v-for="item in mediaAdSlotList" :key="item.mediaAdId" :value="item.mediaAdId" > {{ item.mediaAdId }} </a-select-option> </a-select>
(2) 表單提交后重復(fù)提示
在提交表單時(shí),有時(shí)會(huì)出現(xiàn) 兩次 “新增成功” 提示,影響用戶體驗(yàn)。這通常是由于 子組件和父組件都觸發(fā)了提示,或者 全局?jǐn)r截器重復(fù)提示 導(dǎo)致的。
問題代碼:
// 子組件 handleSubmit() { apiCall().then(res => { this.$message.success("操作成功") // 第一次提示 this.$emit('success') // 父組件可能再次提示 }) } // 父組件 <child-component @success="showSuccess" /> methods: { showSuccess() { this.$message.success("操作成功") // 第二次提示 } }
2. 解決方案:優(yōu)化大數(shù)據(jù)量下拉框
(1) 虛擬滾動(dòng)(Virtual Scroll)
Ant Design Vue 的 a-select 支持虛擬滾動(dòng),僅渲染可視區(qū)域內(nèi)的選項(xiàng),大幅提升性能。
優(yōu)化代碼:
<a-select v-decorator="['mediaAdId']" show-search :options="mediaAdSlotOptions" :virtual-scroll="{ itemSize: 32, // 每個(gè)選項(xiàng)高度 height: 256 // 下拉框高度 }" />
轉(zhuǎn)換數(shù)據(jù)格式:
computed: { mediaAdSlotOptions() { return this.mediaAdSlotList.map(item => ({ label: item.mediaAdId, value: item.mediaAdId })) } }
(2) 分頁加載(Pagination)
如果數(shù)據(jù)量極大(如 10,000+ 條),可以采用分頁加載策略。
優(yōu)化代碼:
async fetchMediaAdSlotList(page = 1, pageSize = 100) { const { data } = await api.getMediaAdSlots({ page, pageSize }) if (page === 1) { this.mediaAdSlotList = data } else { this.mediaAdSlotList.push(...data) } }
(3) 搜索時(shí)懶加載(Lazy Loading)
僅在用戶輸入時(shí)加載匹配的數(shù)據(jù),減少初始請(qǐng)求量。
優(yōu)化代碼:
methods: { handleSearch: debounce(async (keyword) => { if (!keyword) return const { data } = await api.searchMediaAdSlots({ keyword }) this.mediaAdSlotList = data }, 500) }
(4) 防抖優(yōu)化(Debounce)
避免頻繁觸發(fā)搜索請(qǐng)求,減少服務(wù)器壓力。
import { debounce } from 'lodash' methods: { handleSearch: debounce(async (keyword) => { // 搜索邏輯 }, 500) }
3. 解決方案:避免表單提交重復(fù)提示
(1) 統(tǒng)一消息提示位置
推薦方案:只在子組件提示,父組件僅刷新數(shù)據(jù)。
// 子組件 handleSubmit() { apiCall().then(res => { this.$message.success("操作成功") // 僅在這里提示 this.$emit('success') // 父組件只刷新數(shù)據(jù) }) } // 父組件 <child-component @success="handleRefreshData" /> methods: { handleRefreshData() { this.fetchData() // 不顯示提示 } }
(2) 事件冒泡管理
如果必須由父組件控制提示,可以傳遞消息內(nèi)容:
// 子組件 this.$emit('success', '操作成功') // 父組件 <child-component @success="(msg) => $message.success(msg)" />
(3) 攔截器優(yōu)化
如果全局?jǐn)r截器導(dǎo)致重復(fù)提示,可以添加 skipMessage 選項(xiàng):
// API 調(diào)用 api.postData(params, { skipMessage: true }) // 攔截器 axios.interceptors.response.use(res => { if (res.config.skipMessage) return res if (res.data.success) { Message.success(res.data.message) } return res })
4. 完整優(yōu)化代碼示例
優(yōu)化后的 Select 組件
<template> <a-select v-decorator="['mediaAdId']" show-search :options="mediaAdSlotOptions" :virtual-scroll="{ itemSize: 32, height: 256 }" @search="handleSearch" /> </template> <script> import { debounce } from 'lodash' export default { data() { return { mediaAdSlotList: [] } }, computed: { mediaAdSlotOptions() { return this.mediaAdSlotList.map(item => ({ label: item.mediaAdId, value: item.mediaAdId })) } }, methods: { handleSearch: debounce(async (keyword) => { const { data } = await api.searchMediaAdSlots({ keyword }) this.mediaAdSlotList = data }, 500) } } </script>
優(yōu)化后的表單提交邏輯
// 子組件 handleSubmit() { apiCall().then(res => { this.$message.success("操作成功") this.$emit('success') // 父組件只刷新數(shù)據(jù) }) } // 父組件 <child-component @success="fetchData" />
5. 總結(jié)與最佳實(shí)踐
(1) 下拉框優(yōu)化總結(jié)
方案 | 適用場景 | 優(yōu)點(diǎn) | 缺點(diǎn) |
---|---|---|---|
虛擬滾動(dòng) | 大數(shù)據(jù)量(1,000+) | 高性能,流暢渲染 | 需要 Ant Design 支持 |
分頁加載 | 超大數(shù)據(jù)量(10,000+) | 減少初始加載時(shí)間 | 需要額外分頁邏輯 |
搜索懶加載 | 動(dòng)態(tài)過濾場景 | 按需加載,減少請(qǐng)求 | 依賴用戶輸入 |
防抖優(yōu)化 | 頻繁搜索場景 | 減少請(qǐng)求次數(shù) | 需要額外庫(lodash) |
2) 表單提交優(yōu)化總結(jié)
推薦只在子組件提示,父組件僅負(fù)責(zé)數(shù)據(jù)刷新。
避免全局?jǐn)r截器重復(fù)提示,可通過 skipMessage 控制。
保持單向數(shù)據(jù)流,減少組件間耦合。
(3) 最終建議
默認(rèn)使用虛擬滾動(dòng) 優(yōu)化大數(shù)據(jù)量下拉框。
統(tǒng)一提示位置,避免重復(fù)消息。
結(jié)合防抖 + 懶加載 提升搜索體驗(yàn)。
結(jié)語
通過本文的優(yōu)化方案,可以有效解決 大數(shù)據(jù)量下拉框卡頓 和 表單重復(fù)提示 的問題。如果你的項(xiàng)目也遇到類似問題,不妨嘗試這些方法!
到此這篇關(guān)于Vue+Ant Design進(jìn)行大數(shù)據(jù)量下拉框卡頓與表單提交優(yōu)化的文章就介紹到這了,更多相關(guān)Vue+Ant Design優(yōu)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Vue中導(dǎo)入并讀取Excel數(shù)據(jù)的操作步驟
在工作中遇到需要前端上傳excel文件獲取到相應(yīng)數(shù)據(jù)處理之后傳給后端并且展示上傳文件的數(shù)據(jù),所以本文就來給大家介紹一下Vue中導(dǎo)入并讀取Excel數(shù)據(jù)的操作步驟,需要的朋友可以參考下2023-08-08vue2使用el-tag實(shí)現(xiàn)自定義菜單導(dǎo)航標(biāo)簽
這篇文章主要為大家詳細(xì)介紹了vue2如何使用el-tag實(shí)現(xiàn)自定義菜單導(dǎo)航標(biāo)簽,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12vue 實(shí)現(xiàn)模糊檢索并根據(jù)其他字符的首字母順序排列
這篇文章主要介紹了vue 實(shí)現(xiàn)模糊檢索,并根據(jù)其他字符的首字母順序排列,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09簡化版的vue-router實(shí)現(xiàn)思路詳解
這篇文章主要介紹了簡化版的vue-router,需要的朋友可以參考下2018-10-10vue3.2最新語法使用socket.io實(shí)現(xiàn)即時(shí)通訊詳解
這篇文章主要為大家介紹了vue3.2最新語法使用socket.io實(shí)現(xiàn)即時(shí)通訊詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06vue3 elementPlus 表格實(shí)現(xiàn)行列拖拽及列檢索功能(完整代碼)
本文通過實(shí)例代碼給大家介紹vue3 elementPlus 表格實(shí)現(xiàn)行列拖拽及列檢索功能,代碼簡單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-10-10Vue首屏性能優(yōu)化組件知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理了一篇關(guān)于Vue首屏性能優(yōu)化組件知識(shí)點(diǎn)總結(jié),有需要的朋友們可以跟著學(xué)習(xí)下。2021-11-11