当前位置: 首页 > news >正文

郑州正规的网站制作价钱顺德电子画册网站建设

郑州正规的网站制作价钱,顺德电子画册网站建设,潍坊兆通网站建设,不用实名认证的网页游戏文章目录 封装BrandPickerVirtual.vue组件页面使用组件属性 select下拉接口一次性返回10万条数据#xff0c;页面卡死#xff0c;如何优化#xff1f;#xff1f;这里使用 分页 虚拟列表#xff08;vue-virtual-scroll-list#xff09;#xff0c;去模拟一个下拉的内容… 文章目录 封装BrandPickerVirtual.vue组件页面使用组件属性 select下拉接口一次性返回10万条数据页面卡死如何优化这里使用 分页 虚拟列表vue-virtual-scroll-list去模拟一个下拉的内容显示区域。支持单选 多选 模糊查询 滚动触底自动分页请求。 粗略实现满足需求即可哈哈哈哈哈哈哈 单选 多选: 封装BrandPickerVirtual.vue组件 templatediv classbrand-picker-virtualel-popoverv-modelvisibleplacementbottom-starttriggerclickpopper-classbrand-picker-popper:append-to-bodyfalse:width300div classbrand-picker-popoverdiv classsearch-boxel-inputv-modelsearchKeywordplaceholder搜索品牌prefix-iconel-icon-searchclearable //divdiv classbrand-list refbrandListvirtual-listrefvirtualListclassscroller:data-keybrand_id:data-sourcesfilteredBrands:data-componentitemComponent:estimate-size40:keeps20:item-classbrand-item:extra-props{multiple,isSelected: isSelected,handleSelect: handleSelect,disabled}:buffer10:bottom-threshold30tobottomhandleScrollToBottom/div v-ifloading classloading-morei classel-icon-loading/i 加载中.../divdiv refobserver classobserver-target/div/divdiv v-ifmultiple classfooterel-button sizesmall clickhandleClear清空/el-buttonel-button typeprimary sizesmall clickhandleConfirm确定/el-button/div/divdiv slotreference classel-input el-input--suffix select-trigger:class{ is-focus: visible }div classel-input__inner select-innerdiv classselect-tags v-ifmultiple selectedBrands.lengthel-tagv-forbrand in selectedBrands:keybrand.brand_idclosable:disable-transitionsfalseclosehandleRemoveTag(brand)sizesmallclassbrand-tag{{ brand.name }}/el-tag/divdiv v-else-if!multiple selectedBrands.length classselected-singlespan classselected-label{{ selectedBrands[0].name }}/span/divinputtypetextreadonly:placeholdergetPlaceholderclassselect-inputi v-ifselectedBrands.length classel-icon-circle-close clear-icon click.stophandleClear/i/div/div/el-popover/div /templatescript import VirtualList from vue-virtual-scroll-list import request from /utils/requestconst 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: , // 搜索关键字brandList: [], // 品牌列表数据selectedBrands: [], // 已选中的品牌列表tempSelectedBrands: [], // 多选时的临时选中列表loading: false, // 是否正在加载数据itemComponent: BrandItem, // 品牌项组件pageNo: 1, // 当前页码pageSize: 20, // 每页数量hasMore: true, // 是否还有更多数据searchTimer: null, // 搜索防抖定时器searchLoading: false, // 搜索加载状态lastScrollTop: 0, // 上次滚动位置isFirstPageLoaded: false, // 是否已加载第一页数据observer: null // 交叉观察器实例}},computed: {/*** 根据搜索关键字过滤品牌列表* 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: {/*** 监听默认品牌ID变化同步选中状态*/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]}},/*** 监听弹窗显示状态首次打开时加载数据*/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()}})}},/*** 监听搜索关键字变化带防抖的搜索处理*/searchKeyword(val) {if (this.searchTimer) {clearTimeout(this.searchTimer)}this.searchTimer setTimeout(() {this.resetData()this.getBrandList()}, 300)}},beforeDestroy() {if (this.observer) {this.observer.disconnect()}},methods: {/*** 初始化交叉观察器用于监听滚动到底部*/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)}},/*** 获取品牌列表数据* param {boolean} isLoadMore - 是否是加载更多*/async getBrandList(isLoadMore false) {if (this.loading || (!isLoadMore this.searchLoading)) returnif (isLoadMore !this.hasMore) returnconst loading isLoadMore ? loading : searchLoadingthis[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}},/*** 滚动到底部的处理函数*/handleScrollToBottom() {if (!this.loading this.hasMore) {this.getBrandList(true)}},/*** 初始化选中状态*/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) {// 阻止事件冒泡防止触发下拉框if (e) {e.stopPropagation()}this.selectedBrands []this.tempSelectedBrands []this.emitChange()},/*** 确认多选结果*/handleConfirm() {this.selectedBrands [...this.tempSelectedBrands]this.visible falsethis.emitChange()},/*** 触发选中值变化事件*/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()},/*** 重置列表相关数据*/resetData() {this.brandList []this.pageNo 1this.hasMore truethis.loading falsethis.searchLoading false}} } /scriptstyle langscss .brand-picker-popper {max-height: calc(100vh - 100px);overflow: visible !important;left: 0 !important;top: 26px !important;.el-popover__title {margin: 0;padding: 0;} } /stylestyle langscss 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/svgxml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik00MDYuNjU2IDcwNi45NDRsLTE2MC0xNjBjLTEyLjQ4LTEyLjQ4LTMyLjc2OC0xMi40OC00NS4yNDggMHMtMTIuNDggMzIuNzY4IDAgNDUuMjQ4bDE4Mi42MjQgMTgyLjYyNGMxMi40OCAxMi40OCAzMi43NjggMTIuNDggNDUuMjQ4IDBsNDAwLTQwMGMxMi40OC0xMi40OCAxMi40OC0zMi43NjggMC00NS4yNDhzLTMyLjc2OC0xMi40OC00NS4yNDggMEw0MDYuNjU2IDcwNi45NDR6IiBmaWxsPSIjNDA5RUZGIi8PC9zdmc) 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-idsingleBrandIdchangedhandleBrandChange/!-- 多选模式 --brand-picker-virtualmultiple:default-brand-idmultipleBrandIdschangedhandleMultipleBrandChange/ /templatescript // 注册组件别忘了我这里省略了我是个全局注册的 export default {data() {return {singleBrandId: null, // 单选模式存储单个品牌IDmultipleBrandIds: [] // 多选模式存储品牌ID数组}},methods: {// 单选回调handleBrandChange(brandId) {this.singleBrandId brandId},// 多选回调handleMultipleBrandChange(brandIds) {this.multipleBrandIds brandIds}} } /script组件属性 props: {// 是否多选模式multiple: {type: Boolean,default: false},// 默认选中的品牌ID单选时为number/string多选时为arraydefaultBrandId: {type: [Array, String, Number],default: () []},// 自定义接口地址api: {type: String,default: admin/goods/brands},// 是否禁用disabled: {type: Boolean,default: false} }
http://www.zqtcl.cn/news/536112/

相关文章:

  • docker可以做网站吗专业的营销型网站
  • 重庆市建设工程安全网站上海制造网站公司
  • 咨询网站公司建设计划书安卓软件开发软件
  • 手机网站建设文章直播平台开发多少钱
  • 站长综合查询工具常用的网站开发语言有哪些
  • 免费网站看v片在线第一次做乌市seo网络营销流程
  • 社交网站模板下载柬埔寨网赌网站开发
  • 网站开发合同是否要交印花税杭州集团网站建设
  • 企业网站建设排名资讯一个公司做两个网站可以吗
  • 简单门户网站开发灰色行业seo大神
  • 网站开发学那种语言外贸推广网站建设
  • 公司网站建设及推广中国优秀企业网站欣赏
  • 个人代做网站建设京东类的网站需要什么流程
  • 建设一个地方门户网站厦门网站开发排名
  • 网站建设公司广告标题语网站设计主题有哪些
  • 网站推广方式主要通过做网站所需的知识技能
  • 我想在阿里巴巴网站开店_怎么做app建设网站公司
  • 西安做百度网站的制作网站公司选 择乐云seo
  • 网站优化建设河南手机模拟器
  • 网站建设运维标准深圳企业vi设计公司
  • 做网站怎么挣钱中小型企业网站建设
  • 深圳如何搭建建网站学校网站的建设与应用
  • 免费推广网站入口2023燕wordpress看图插件
  • 网站做不做301四川省住建设厅网站
  • 优化方案官网电子版一个网站做两个优化可以做吗
  • 企业网站排名提升软件智能优化上海网站制作的费用
  • 建分类信息网站西安高端模板建站
  • 南昌做网站哪家好成都三合一网站建设
  • 中国市政建设局网站做外单网站
  • 做本地网站赚钱吗wordpress 预约系统