virtualList 封裝使用 虛擬列表 列表優化

虛擬列表 列表優化

  • virtualList 組件封裝

virtualList 組件封裝

本虛擬列表 要求一次性加載完所有數據 不適合分頁
新建一個select.vue 組件頁面

<template><div>	<el-select transfer="true"   :popper-append-to-body="true"popper-class="virtualselect"class="virtual-select-custom-style":value="defaultValue"filterable:filter-method="filterMethod"default-first-optionclearable:placeholder="placeholderParams":multiple="isMultiple":allow-create="allowCreate"@visible-change="visibleChange"v-on="$listeners"@clear="clearChange"><virtual-listref="virtualList"class="virtualselect-list":data-key="value":data-sources="selectArr":data-component="itemComponent":keeps="keepsParams":extra-props="{label: label,value: value,labelTwo:labelTwo,isRight: isRight,isConcat: isConcat,isConcatShowText:isConcatShowText,concatSymbol: concatSymbol}"></virtual-list></el-select></div>
</template>
<script>import {validatenull} from '@/utils/validate.js'import virtualList from 'vue-virtual-scroll-list'import ElOptionNode from './el-option-node'export default {components: {'virtual-list': virtualList},model: {prop: 'bindValue',event: 'change'},props: {// 數組list: {type: Array,default() {return []}},// 顯示名稱1label: {type: String,default: ''},// 顯示名稱2 labelTwo: {type: String,default: ''},// 標識value: {type: String,default: ''},// 是否拼接label | valueisConcat: {type: Boolean,default: false},isConcatShowText:{type: Boolean,default: false},// 拼接label、value符號concatSymbol: {type: String,default: ' | '},// 顯示右邊isRight: {type: Boolean,default: false},// 加載條數keepsParams: {type: Number,default: 10},// 綁定的默認值bindValue: {type: [String, Array,Number],default() {if (typeof this.bindValue === 'string') return ''return []}},// 是否多選isMultiple: {type: Boolean,default: false},placeholderParams: {type: String,default: '請選擇'},// 是否允許創建條目allowCreate: {type: Boolean,default: true}},data() {return {itemComponent: ElOptionNode,selectArr: [],defaultValue: null // 綁定的默認值}},watch: {'list'() {this.init()},bindValue: {handler(val, oldVal) {this.defaultValue = this.bindValueif (validatenull(val)) this.clearChange()this.init()},immediate: false,deep: true}},mounted() {this.defaultValue = this.bindValuethis.init()},methods: {init() {if (!this.defaultValue || this.defaultValue?.length === 0) {this.selectArr = this.list} else {// 回顯問題// 由于只渲染固定keepsParams(10)條數據,當默認數據處于10條之外,在回顯的時候會顯示異常// 解決方法:遍歷所有數據,將對應回顯的那一條數據放在第一條即可this.selectArr = JSON.parse(JSON.stringify(this.list))if (typeof this.defaultValue === 'string' && !this.isMultiple) {let obj = {}if (this.allowCreate) {const arr = this.selectArr.filter(val => {return val[this.value] === this.defaultValue})if (arr.length === 0) {const item = {}// item[this.value] = `Create-${this.defaultValue}`item[this.value] = this.defaultValueitem[this.label] = this.defaultValueitem.allowCreate = truethis.selectArr.push(item)this.$emit('selChange', item)} else {this.$emit('selChange', arr[0])}}// 單選for (let i = 0; i < this.selectArr.length; i++) {const element = this.selectArr[i]// if (element[this.value]?.toLowerCase() === this.defaultValue?.toLowerCase()) {if (element[this.value] === this.defaultValue) {obj = elementthis.selectArr?.splice(i, 1)break}}this.selectArr?.unshift(obj)} else if (this.isMultiple) {if (this.allowCreate) {this.defaultValue.map(v => {const arr = this.selectArr.filter(val => {return val[this.value] === v})if (arr?.length === 0) {const item = {}// item[this.value] = `Create-${v}`item[this.value] = vitem[this.label] = vitem.allowCreate = truethis.selectArr.push(item)this.$emit('selChange', item)} else {this.$emit('selChange', arr[0])}})}// 多選for (let i = 0; i < this.selectArr.length; i++) {const element = this.selectArr[i]this.defaultValue?.map(val => {// if (element[this.value]?.toLowerCase() === val?.toLowerCase()) {if (element[this.value]=== val) {obj = elementthis.selectArr?.splice(i, 1)this.selectArr?.unshift(obj)}})}}}},// 搜索filterMethod(query) {if (!validatenull(query?.trim())) {this.$refs.virtualList.scrollToIndex(0) // 滾動到頂部setTimeout(() => {this.selectArr = this.list.filter(item => {return this.isRight || this.isConcat? (item[this.label].trim()?.toLowerCase()?.indexOf(query?.trim()?.toLowerCase()) > -1 || (item[this.labelTwo]+'')?.toLowerCase()?.indexOf(query?.trim()?.toLowerCase()) > -1): item[this.label]?.toLowerCase()?.indexOf(query?.trim()?.toLowerCase()) > -1// return this.isRight || this.isConcat? (item[this.label].trim().indexOf(query.trim()) > -1 || (item[this.value]+'').trim().indexOf(query.trim()) > -1)//   : item[this.label].indexOf(query.trim()) > -1})}, 100)} else {setTimeout(() => {this.init()}, 100)}},visibleChange(bool) {if (!bool) {this.$refs.virtualList.reset()this.init()}},clearChange() {if (typeof this.defaultValue === 'string') {this.defaultValue = ''} else if (this.isMultiple) {this.defaultValue = []}this.visibleChange(false)}}}
</script>
<style lang="scss" scoped>.virtual-select-custom-style{width:100% !important;}
.virtual-select-custom-style ::v-deep .el-select-dropdown__item {// 設置最大寬度,超出省略號,鼠標懸浮顯示// options 需寫 :title="source[label]"min-width: 300px;max-width: 480px;display: inline-block;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}
.virtualselect {// 設置最大高度&-list {max-height:245px;overflow-y:auto;}
}
::-webkit-scrollbar {width: 6px;height: 6px;background-color: transparent;cursor: pointer;margin-right: 5px;
}
::-webkit-scrollbar-thumb {background-color: rgba(144,147,153,.3) !important;border-radius: 3px !important;
}
::-webkit-scrollbar-thumb:hover{background-color: rgba(144,147,153,.5) !important;
}
::-webkit-scrollbar-track {background-color: transparent !important;border-radius: 3px !important;-webkit-box-shadow: none !important;
}
::v-deep  .el-select__tags {flex-wrap: unset;overflow: auto;
}
</style>

新建一個組件 el-option-node.vue

<template><el-option:key="label+value":label="concatString2(source[label], source[labelTwo])":value="source[value]":disabled="source.disabled":title="concatString2(source[label], source[labelTwo])"><span >{{ concatString(source[label], source[labelTwo]) }}</span><spanv-if="isRight"style="float:right;color:#939393">{{ source[value] }}</span></el-option>
</template>
<script>export default {name: 'ItemComponent',props: {// 每一行的索引index: {type: Number,default: 0},// 每一行的內容source: {type: Object,default() {return {}}},// 需要顯示的名稱label: {type: String,default: ''},// 需要顯示的名稱labelTwo: {type: String,default: ''},// 綁定的值value: {type: String,default: ''},// 是否拼接label | valueisConcat: {type: Boolean,default: false},isConcatShowText:{type: Boolean,default: false},// 拼接label、value符號concatSymbol: {type: String,default: ' | '},// 右側是否顯示綁定的值isRight: {type: Boolean,default() {return false}}},methods: {//選擇后 只顯示label//張三concatString(a, b) {a = a || ''b = b || ''if (this.isConcat) {// return a + ((a && b) ? ' | ' : '') + breturn a + ((a && b) ? this.concatSymbol : '') + b}return a},//選擇下拉展示時 可以展示label和labelTwo//123||張三concatString2(a, b) {a = a || ''b = b || ''if (this.isConcat) {// return a + ((a && b) ? ' | ' : '') + bif(this.isConcatShowText==true){return a + ((a && b) ? this.concatSymbol : '') + b}else{return a}}return a}}}
</script>

組件建議完成后 在頁面使用:

list:數據 [{name:‘張三’,code:‘098’},{}] label:要顯示的字段1 labelTwo:要顯示的字段2
concat-symbol:拼接符號 is-concat是否拼接 is-multiple:是否多選 allowCreate是否可以創建目錄 @change 事件 keeps-params數據多少條

<template><div><virtual-select v-model="item.contractGodsId":list="goodsList" label="name" labelTwo="code" value="id" :placeholder-params="'請選擇產品'":keeps-params="10" :is-concat="true" :isConcatShowText="false":concat-symbol="' || '" :is-multiple="false" :allowCreate="false"@change="goodsChange($event,$index)" /></div>
</template>引入組件import VirtualSelect from '@/views/components/virtualList/select'export default {components: {VirtualSelect},}

如果label和labelTwo都填寫了,顯示效果如下

請添加圖片描述

本虛擬列表 要求一次性加載完所有數據 不適合分頁

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/162747.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/162747.shtml
英文地址,請注明出處:http://en.pswp.cn/news/162747.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

YOLOv8/5不顯示FLPOs

YOLOv8/5不顯示FLPOs,避免自媒體搬運,請下滑! YOLOv8/5不顯示FLPOs,避免自媒體搬運,請下滑! YOLOv8/5不顯示FLPOs,避免自媒體搬運,請下滑! YOLOv8/5不顯示FLPOs,避免自媒體搬運,請下滑! YOLOv8/5不顯示FLPOs,避免自媒體搬運,請下滑! YOLOv8/5不顯示FLPOs,避免自…

安裝第三方包報錯 error: Microsoft Visual C++ 14.0 or greater is required——解決辦法

1、問題描述 手動安裝第三方軟件時&#xff0c;可以使用setup.py&#xff0c;來安裝已經下載的第三方包。一般文件下會存在setup&#xff0c;在所要安裝庫的目錄下的cmd執行&#xff1a;python setup.py install報錯&#xff1a;error: Microsoft Visual C 14.0 or greater i…

所有權成果輸出(宗地基本信息表、界址標示表、界址簽章表、界址點成果表、宗地圖、界址說明表、調查審核表)

一、軟件界面&#xff1a; 二、軟件功能&#xff1a; 一、所有權成果要求(宗地基本信息表、界址標示表、界址簽章表、界址點成果表、宗地圖、界址說明表、調查審核表&#xff09; 1 不動產權籍調查表封面 &#xff08;1&#xff09;宗地&#xff08;海&#xff09;代碼&…

基于element-plus定義表單配置化擴展表單按鈕

文章目錄 前言一、新增btn.vue組件二、使用總結如有啟發&#xff0c;可點贊收藏喲~ 前言 在后臺管理系統一般都存在列表查詢&#xff0c;且可輸入數據進行查詢 基于element-plus定義表單配置化 新增按鈕配置化 一、新增btn.vue組件 <template><template v-for&qu…

代碼隨想錄算法訓練營第四十二天【動態規劃part04】 | 01背包、416. 分割等和子集

01背包問題 題目鏈接&#xff1a; 題目頁面 求解思路&#xff1a; 確定dp數組及其下標含義&#xff1a;dp[i][j] 表示從下標為 [0] 到 [i] 的物品里任意選取&#xff0c;放進容量為j的背包&#xff0c;此時的價值總和最大值確定遞推公式&#xff1a; 不放物品i&#xff0c;…

centos查看空間使用情況

查看磁盤使用空間 df -h 查看該目錄下其他目錄的大小 du -sh *

自動化測試框架[Cypress 常見的“坑”]

Cypress命令是異步的 假設使用Selenium時&#xff0c;有如下這段代碼

Unity中顏色空間Gamma與Linear

文章目錄 前言一、人眼對光照的自適應1、光照強度與人眼所見的關系2、巧合的是&#xff0c;早期的電子脈沖顯示屏也符合這條曲線3、這兩條曲線都巧合的符合 y x^2.2^&#xff08;Gamma2.2空間&#xff09; 二、Gamma矯正1、沒矯正前&#xff0c;人眼看電子脈沖顯示屏&#xff…

學習筆記,http協議1.0,1.1,2.0之間的差別

文章目錄 前言http 1.1與http 1.0http 2.0 與http 1.x注意點 前言 僅做個人學習筆記記錄&#xff0c;如有錯誤&#xff0c;請多多包涵。 學習鏈接&#xff1a; HTTP 1.0與1.1、2.0之間的區別 面試官&#xff1a;說說 HTTP1.0/1.1/2.0 的區別? http 1.1與http 1.0 http協議1…

用 js 實現 判斷兩個數組是否相同

文章目錄 問題分析 問題 有數組 array1 和 array2 &#xff0c;如何判斷這兩個數組是否相同 分析 判斷兩個數組是否相同&#xff0c;你可以檢查它們的長度和每個元素是否相等。下面是一個示例代碼&#xff1a; function arraysAreEqual(arr1, arr2) {if (arr1.length ! arr2.…

事件溯源模式

概念解釋 事件溯源&#xff08;Event Sourcing&#xff09;是一種設計模式&#xff0c;其核心思想是將系統的狀態變化表示為一系列不可變的事件&#xff0c;并將這些事件存儲在事件日志中。系統的當前狀態可以通過重新應用&#xff08;回放&#xff09;這些事件來還原&#xf…

芯片的測試方法

半導體的生產流程包括晶圓制造和封裝測試&#xff0c;在這兩個環節中分別需要完成晶圓檢測(CP, Circuit Probing)和成品測試(FT, Final Test)。無論哪個環節&#xff0c;要測試芯片的各項功能指標均須完成兩個步驟&#xff1a;一是將芯片的引腳與測試機的功能模塊連接起來&…

促進材料基因工程基礎理論、前沿技術和關鍵裝備的發展和應用,第七屆材料基因工程高層論壇將于12月重慶舉辦,龍訊曠騰出席會議

為了進一步促進材料基因工程基礎理論、前沿技術和關鍵裝備的發展和應用&#xff0c;加強國際交流&#xff0c;加速我國新材料的研發和應用&#xff0c;由中國材料研究學會、西部科學城重慶高新區管理委員會主辦&#xff0c;重慶大學、北京科技大學、北京云智材料大數據研究院等…

【GUI】-- 14 GUI編程總結

GUI編程 05 GUI總結 在總結之前&#xff0c;先給出之前的貪吃蛇小游戲全代碼。 游戲的主啟動類&#xff1a; package com.duo.snake;import javax.swing.*;//游戲的主啟動類 public class StartGame {public static void main(String[] args) {JFrame frame new JFrame();…

Java面試-微服務篇-SpringCloud

Java面試-微服務篇-SpringCloud SpringCloud 常見組件注冊中心Eureka, Nacos負載均衡Ribbon服務雪崩, 熔斷降級微服務的監控來源 SpringCloud 常見組件 通常情況下 Eureka: 注冊中心Ribbon: 負載均衡Feign: 遠程調用Hystrix: 服務熔斷Zuul/Gateway: 網關 SpringCloudAlibaba…

【開源】基于Vue.js的天然氣工程運維系統的設計和實現

項目編號&#xff1a; S 022 &#xff0c;文末獲取源碼。 \color{red}{項目編號&#xff1a;S022&#xff0c;文末獲取源碼。} 項目編號&#xff1a;S022&#xff0c;文末獲取源碼。 目錄 一、摘要1.1 項目介紹1.2 項目錄屏 二、功能模塊2.1 系統角色分類2.2 核心功能2.2.1 流程…

服務限流算法:從令人頭疼到信手拈來

前言 隨著系統規模的擴大和用戶量的增加&#xff0c;服務限流成為了一個非常重要的話題。一方面&#xff0c;系統需要能夠處理大量的請求&#xff0c;不至于因為負載過高而崩潰&#xff1b;另一方面&#xff0c;又需要避免惡意攻擊或者其他異常情況對系統造成影響。本文將介紹…

npm相關和私有云

安裝node時npm會自動安裝&#xff0c;npm也可以單獨安裝。 package.json 在使用npm時&#xff0c;package.json文件是非常重要的&#xff0c;因為它包含了關于項目的必要信息&#xff0c;比如名稱、版本、依賴項等。在初始化新項目時&#xff0c;通常會使用npm init命令生成一…

pip安裝python包到指定python版本下

python -m pip install 包名1.命令行進入到指定python安裝目錄。比如我電腦上有python3.8也有python3.9。準備給python3.9安裝指定的包