中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

中企動力科技股份有限公司網(wǎng)站官網(wǎng)2020十大網(wǎng)絡(luò)熱詞

中企動力科技股份有限公司網(wǎng)站官網(wǎng),2020十大網(wǎng)絡(luò)熱詞,國際網(wǎng)站 建設(shè),wordpress 4.1.1 漏洞文章目錄 封裝BrandPickerVirtual.vue組件頁面使用組件屬性 select下拉接口一次性返回10萬條數(shù)據(jù),頁面卡死,如何優(yōu)化??這里使用 分頁 虛擬列表(vue-virtual-scroll-list),去模擬一個下拉的內(nèi)容…

文章目錄

      • 封裝BrandPickerVirtual.vue組件
      • 頁面使用
      • 組件屬性

在這里插入圖片描述

select下拉接口一次性返回10萬條數(shù)據(jù),頁面卡死,如何優(yōu)化??這里使用 分頁 + 虛擬列表(vue-virtual-scroll-list),去模擬一個下拉的內(nèi)容顯示區(qū)域。支持單選 + 多選 + 模糊查詢 + 滾動觸底自動分頁請求


粗略實現(xiàn),滿足需求即可哈哈哈哈哈哈哈:
單選:
在這里插入圖片描述


多選:
在這里插入圖片描述


封裝BrandPickerVirtual.vue組件

<template><div class="brand-picker-virtual"><el-popoverv-model="visible"placement="bottom-start"trigger="click"popper-class="brand-picker-popper":append-to-body="false":width="300"><div class="brand-picker-popover"><div class="search-box"><el-inputv-model="searchKeyword"placeholder="搜索品牌"prefix-icon="el-icon-search"clearable /></div><div class="brand-list" ref="brandList"><virtual-listref="virtualList"class="scroller":data-key="'brand_id'":data-sources="filteredBrands":data-component="itemComponent":estimate-size="40":keeps="20":item-class="'brand-item'":extra-props="{multiple,isSelected: isSelected,handleSelect: handleSelect,disabled}":buffer="10":bottom-threshold="30"@tobottom="handleScrollToBottom"/><div v-if="loading" class="loading-more"><i class="el-icon-loading"></i> 加載中...</div><div ref="observer" class="observer-target"></div></div><div v-if="multiple" class="footer"><el-button size="small" @click="handleClear">清空</el-button><el-button type="primary" size="small" @click="handleConfirm">確定</el-button></div></div><div slot="reference" class="el-input el-input--suffix select-trigger":class="{ 'is-focus': visible }"><div class="el-input__inner select-inner"><div class="select-tags" v-if="multiple && selectedBrands.length"><el-tagv-for="brand in selectedBrands":key="brand.brand_id"closable:disable-transitions="false"@close="handleRemoveTag(brand)"size="small"class="brand-tag">{{ brand.name }}</el-tag></div><div v-else-if="!multiple && selectedBrands.length" class="selected-single"><span class="selected-label">{{ selectedBrands[0].name }}</span></div><inputtype="text"readonly:placeholder="getPlaceholder"class="select-input"><i v-if="selectedBrands.length" class="el-icon-circle-close clear-icon" @click.stop="handleClear"></i></div></div></el-popover></div>
</template><script>
import VirtualList from 'vue-virtual-scroll-list'
import request from '@/utils/request'const BrandItem = {name: 'BrandItem',props: {source: {type: Object,required: true},multiple: Boolean,isSelected: Function,handleSelect: Function,disabled: Boolean},render(h) {const isItemSelected = this.isSelected(this.source)return h('div', {class: {'item-content': true,'is-selected': isItemSelected && !this.multiple},on: {click: (e) => {if (!this.disabled) {this.handleSelect(this.source)}}}}, [this.multiple && h('el-checkbox', {props: {value: isItemSelected,disabled: this.disabled}}),h('span', { class: 'brand-name' }, this.source.name)])}
}export default {name: 'BrandPickerVirtual',components: {VirtualList},props: {multiple: {type: Boolean,default: false},defaultBrandId: {type: [Array, String, Number],default: () => []},api: {type: String,default: 'admin/goods/brands'},disabled: {type: Boolean,default: false}},data() {return {visible: false, // 彈窗是否可見searchKeyword: '', // 搜索關(guān)鍵字brandList: [], // 品牌列表數(shù)據(jù)selectedBrands: [], // 已選中的品牌列表tempSelectedBrands: [], // 多選時的臨時選中列表loading: false, // 是否正在加載數(shù)據(jù)itemComponent: BrandItem, // 品牌項組件pageNo: 1, // 當(dāng)前頁碼pageSize: 20, // 每頁數(shù)量hasMore: true, // 是否還有更多數(shù)據(jù)searchTimer: null, // 搜索防抖定時器searchLoading: false, // 搜索加載狀態(tài)lastScrollTop: 0, // 上次滾動位置isFirstPageLoaded: false, // 是否已加載第一頁數(shù)據(jù)observer: null // 交叉觀察器實例}},computed: {/*** 根據(jù)搜索關(guān)鍵字過濾品牌列表* @returns {Array} 過濾后的品牌列表*/filteredBrands() {if (!this.searchKeyword) return this.brandListconst keyword = this.searchKeyword.toLowerCase()return this.brandList.filter(item =>item.name.toLowerCase().includes(keyword))},/*** 選中品牌的顯示文本* @returns {string} 顯示文本*/selectedText() {if (this.multiple) {return this.selectedBrands.length? `已選擇 ${this.selectedBrands.length} 個品牌`: ''}return (this.selectedBrands[0] && this.selectedBrands[0].name) || ''},/*** 獲取占位符文本*/getPlaceholder() {if (this.multiple) {return this.selectedBrands.length ? '' : '請選擇品牌(可多選)'}return this.selectedBrands.length ? '' : '請選擇品牌'}},watch: {/*** 監(jiān)聽默認品牌ID變化,同步選中狀態(tài)*/defaultBrandId: {immediate: true,handler(val) {if (!val || !this.brandList.length) returnif (this.multiple) {this.selectedBrands = this.brandList.filter(item =>val.includes(item.brand_id))} else {const brand = this.brandList.find(item =>item.brand_id === val)this.selectedBrands = brand ? [brand] : []}this.tempSelectedBrands = [...this.selectedBrands]}},/*** 監(jiān)聽彈窗顯示狀態(tài),首次打開時加載數(shù)據(jù)*/visible(val) {if (val) {if (this.multiple) {this.tempSelectedBrands = [...this.selectedBrands]}this.resetData()this.getBrandList()// 確保虛擬列表在顯示時重新初始化this.$nextTick(() => {if (this.$refs.virtualList) {this.$refs.virtualList.reset()}})}},/*** 監(jiān)聽搜索關(guān)鍵字變化,帶防抖的搜索處理*/searchKeyword(val) {if (this.searchTimer) {clearTimeout(this.searchTimer)}this.searchTimer = setTimeout(() => {this.resetData()this.getBrandList()}, 300)}},beforeDestroy() {if (this.observer) {this.observer.disconnect()}},methods: {/*** 初始化交叉觀察器,用于監(jiān)聽滾動到底部*/initObserver() {this.observer = new IntersectionObserver((entries) => {const target = entries[0]if (target.isIntersecting && !this.loading && this.hasMore) {this.getBrandList(true)}},{root: this.$el.querySelector('.scroller'),threshold: 0.1})if (this.$refs.observer) {this.observer.observe(this.$refs.observer)}},/*** 獲取品牌列表數(shù)據(jù)* @param {boolean} isLoadMore - 是否是加載更多*/async getBrandList(isLoadMore = false) {if (this.loading || (!isLoadMore && this.searchLoading)) returnif (isLoadMore && !this.hasMore) returnconst loading = isLoadMore ? 'loading' : 'searchLoading'this[loading] = truetry {if (isLoadMore) {this.pageNo++} else {this.pageNo = 1}const response = await request({url: this.api,method: 'get',params: {page_no: this.pageNo,page_size: this.pageSize,keyword: this.searchKeyword},loading: false})const { data, data_total } = response        if (!isLoadMore) {this.brandList = datathis.isFirstPageLoaded = true} else {this.brandList = [...this.brandList, ...data]}this.hasMore = this.brandList.length < data_totalif (this.defaultBrandId && !isLoadMore) {this.initializeSelection()}} catch (error) {console.error('獲取品牌列表失敗:', error)} finally {this[loading] = false}},/*** 滾動到底部的處理函數(shù)*/handleScrollToBottom() {if (!this.loading && this.hasMore) {this.getBrandList(true)}},/*** 初始化選中狀態(tài)*/initializeSelection() {if (this.multiple) {this.selectedBrands = this.brandList.filter(item =>this.defaultBrandId.includes(item.brand_id))} else {const brand = this.brandList.find(item =>item.brand_id === this.defaultBrandId)this.selectedBrands = brand ? [brand] : []}this.tempSelectedBrands = [...this.selectedBrands]},/*** 判斷品牌是否被選中* @param {Object} item - 品牌項* @returns {boolean} 是否選中*/isSelected(item) {return this.multiple? this.tempSelectedBrands.some(brand => brand.brand_id === item.brand_id): this.selectedBrands.some(brand => brand.brand_id === item.brand_id)},/*** 處理品牌選擇* @param {Object} item - 選中的品牌項*/handleSelect(item) {if (this.multiple) {const index = this.tempSelectedBrands.findIndex(brand => brand.brand_id === item.brand_id)if (index > -1) {this.tempSelectedBrands.splice(index, 1)} else {this.tempSelectedBrands.push(item)}} else {this.selectedBrands = [item]this.visible = falsethis.emitChange()}},/*** 清空選中的品牌*/handleClear(e) {// 阻止事件冒泡,防止觸發(fā)下拉框if (e) {e.stopPropagation()}this.selectedBrands = []this.tempSelectedBrands = []this.emitChange()},/*** 確認多選結(jié)果*/handleConfirm() {this.selectedBrands = [...this.tempSelectedBrands]this.visible = falsethis.emitChange()},/*** 觸發(fā)選中值變化事件*/emitChange() {const value = this.multiple? this.selectedBrands.map(item => item.brand_id): (this.selectedBrands[0] && this.selectedBrands[0].brand_id) || nullthis.$emit('changed', value)},handleRemoveTag(brand) {const index = this.selectedBrands.findIndex(item => item.brand_id === brand.brand_id)if (index > -1) {this.selectedBrands.splice(index, 1)}this.tempSelectedBrands = [...this.selectedBrands]this.emitChange()},/*** 重置列表相關(guān)數(shù)據(jù)*/resetData() {this.brandList = []this.pageNo = 1this.hasMore = truethis.loading = falsethis.searchLoading = false}}
}
</script><style lang="scss">
.brand-picker-popper {max-height: calc(100vh - 100px);overflow: visible !important;left: 0 !important;top: 26px !important;.el-popover__title {margin: 0;padding: 0;}
}
</style><style lang="scss" scoped>
.brand-picker-virtual {display: inline-block;width: 100%;position: relative;.select-trigger {width: 100%;&.is-focus .el-input__inner {border-color: #409EFF;}}.select-inner {padding: 3px 8px;min-height: 32px;height: auto;cursor: pointer;position: relative;background-color: #fff;border: 1px solid #dcdfe6;border-radius: 4px;display: flex;align-items: center;flex-wrap: wrap;}.select-tags {display: flex;flex-wrap: wrap;gap: 4px;flex: 1;min-height: 24px;padding: 2px 0;.brand-tag {max-width: 100%;margin: 2px 0;&:last-child {margin-right: 4px;}}}.select-input {width: 0;min-width: 60px;margin: 2px 0;padding: 0;background: none;border: none;outline: none;height: 24px;line-height: 24px;font-size: 14px;color: #606266;flex: 1;&::placeholder {color: #c0c4cc;}}.clear-icon {position: absolute;right: 8px;color: #c0c4cc;font-size: 14px;cursor: pointer;transition: color .2s;&:hover {color: #909399;}}.selected-single {display: flex;align-items: center;flex: 1;padding-right: 24px;.selected-label {flex: 1;font-size: 14px;color: #606266;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}}.el-input__suffix,.el-icon-arrow-down {display: none;}.brand-picker-popover {margin-top: 4px !important;.search-box {padding: 0 0 12px;.el-input {font-size: 14px;}}.brand-list {position: relative;height: 320px;border: 1px solid #EBEEF5;border-radius: 4px;overflow: hidden;.scroller {height: 100%;overflow-y: auto !important;overflow-x: hidden;padding: 4px 0;/deep/ .virtual-list-container {position: relative !important;}/deep/ .virtual-list-phantom {position: relative !important;}/deep/ .brand-item {.item-content {padding-left: 8px;height: 40px;line-height: 40px;cursor: pointer;transition: all 0.3s;box-sizing: border-box;position: relative;font-size: 14px;color: #606266;border-bottom: 1px solid #f0f0f0;display: flex;align-items: center;user-select: none;.el-checkbox {margin-right: 8px;}.brand-name {flex: 1;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}&:hover {background-color: #F5F7FA;}&.is-selected {background-color: #F5F7FA;color: #409EFF;font-weight: 500;&::after {content: '';position: absolute;right: 15px;width: 14px;height: 14px;background: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik00MDYuNjU2IDcwNi45NDRsLTE2MC0xNjBjLTEyLjQ4LTEyLjQ4LTMyLjc2OC0xMi40OC00NS4yNDggMHMtMTIuNDggMzIuNzY4IDAgNDUuMjQ4bDE4Mi42MjQgMTgyLjYyNGMxMi40OCAxMi40OCAzMi43NjggMTIuNDggNDUuMjQ4IDBsNDAwLTQwMGMxMi40OC0xMi40OCAxMi40OC0zMi43NjggMC00NS4yNDhzLTMyLjc2OC0xMi40OC00NS4yNDggMEw0MDYuNjU2IDcwNi45NDR6IiBmaWxsPSIjNDA5RUZGIi8+PC9zdmc+) no-repeat center center;background-size: contain;}}}}}.loading-more {position: absolute;bottom: 0;left: 0;right: 0;padding: 8px;text-align: center;background: rgba(255, 255, 255, 0.95);color: #909399;font-size: 13px;z-index: 1;border-top: 1px solid #f0f0f0;}.observer-target {height: 2px;width: 100%;position: absolute;bottom: 0;left: 0;}}.footer {margin-top: 12px;text-align: right;padding: 0 2px;}}.selected-label {flex: 1;font-size: 14px;color: #606266;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}.selected-single {display: flex;align-items: center;flex: 1;padding: 0 4px;.selected-label {flex: 1;font-size: 14px;height: 24px;line-height: 24px;color: #606266;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}.el-icon-circle-close {margin-left: 8px;color: #c0c4cc;font-size: 14px;cursor: pointer;transition: color .2s;&:hover {color: #909399;}}}
}
</style> 

頁面使用

<template><!-- 單選模式 --><brand-picker-virtual:default-brand-id="singleBrandId"@changed="handleBrandChange"/><!-- 多選模式 --><brand-picker-virtualmultiple:default-brand-id="multipleBrandIds"@changed="handleMultipleBrandChange"/>
</template><script>
// 注冊組件別忘了,我這里省略了,我是個全局注冊的
export default {data() {return {singleBrandId: null,  // 單選模式:存儲單個品牌IDmultipleBrandIds: []  // 多選模式:存儲品牌ID數(shù)組}},methods: {// 單選回調(diào)handleBrandChange(brandId) {this.singleBrandId = brandId},// 多選回調(diào)handleMultipleBrandChange(brandIds) {this.multipleBrandIds = brandIds}}
}
</script>

組件屬性


props: {// 是否多選模式multiple: {type: Boolean,default: false},// 默認選中的品牌ID(單選時為number/string,多選時為array)defaultBrandId: {type: [Array, String, Number],default: () => []},// 自定義接口地址api: {type: String,default: 'admin/goods/brands'},// 是否禁用disabled: {type: Boolean,default: false}
}
http://www.risenshineclean.com/news/43141.html

相關(guān)文章:

  • 新手引導(dǎo)做的差的網(wǎng)站免費建站軟件
  • 動態(tài)網(wǎng)站完整版百度pc網(wǎng)頁版
  • ??诜慨a(chǎn)網(wǎng)站建設(shè)最近發(fā)生的熱點事件
  • 廣州市公司網(wǎng)站建設(shè)公司在線培訓(xùn)app
  • 網(wǎng)站 建設(shè)需求上海aso蘋果關(guān)鍵詞優(yōu)化
  • 網(wǎng)站域名 設(shè)置快速網(wǎng)站seo效果
  • 怎樣做網(wǎng)站首頁圖片變換seo研究中心培訓(xùn)機構(gòu)
  • 做俄羅斯外貿(mào)的網(wǎng)站設(shè)計網(wǎng)址域名ip查詢
  • 潮汕網(wǎng)站建設(shè)antnw網(wǎng)頁設(shè)計需要學(xué)什么
  • 網(wǎng)站加速服務(wù)武漢seo網(wǎng)絡(luò)優(yōu)化公司
  • 做網(wǎng)站的學(xué)什么代碼海外推廣服務(wù)
  • 麗水微信網(wǎng)站建設(shè)哪家好滄州網(wǎng)絡(luò)推廣公司
  • 建立網(wǎng)站的詳細步驟營銷模式有哪些 新型
  • 香港空間建網(wǎng)站百度一下百度網(wǎng)頁版
  • html網(wǎng)站要怎么做簡單制作html靜態(tài)網(wǎng)頁
  • 眉山市住房和城鄉(xiāng)建設(shè)局網(wǎng)站西安推廣平臺排行榜
  • 還有哪些免費的網(wǎng)站可以做H5優(yōu)化推廣什么意思
  • 南京響應(yīng)式網(wǎng)站制作搜索引擎營銷案例有哪些
  • 1高端網(wǎng)站建設(shè)百度sem競價托管公司
  • 做美食的網(wǎng)站有那一些2345中國最好的網(wǎng)址站
  • 云南網(wǎng)站做的好的公司自己怎么免費做百度推廣
  • 做網(wǎng)站用哪些語言seo是什么縮寫
  • 網(wǎng)站推廣結(jié)束語長沙網(wǎng)站優(yōu)化公司
  • 網(wǎng)站后臺密碼忘了全國人大常委會
  • 在godaddy做網(wǎng)站貴嗎在線識別圖片
  • 做網(wǎng)站是怎么賺錢的違法百度關(guān)鍵詞搜索趨勢
  • 網(wǎng)站設(shè)計多少錢一個優(yōu)化設(shè)計一年級下冊數(shù)學(xué)答案
  • 夜間正能量不良網(wǎng)站入口不用下載什么是搜索關(guān)鍵詞
  • 網(wǎng)站建設(shè)案例簡介怎么寫西安百度關(guān)鍵詞推廣
  • 上海青浦房地產(chǎn)網(wǎng)站建設(shè)太原做網(wǎng)站的工作室