elementplus 二次封装 select 自定义指令上拉加载更多 完美解决 多次接口调用 重新加载数据多次调用!!!

news2024/9/22 23:21:45

ps: 我封装的 select 实现了:1、上拉加载更多。2、远程搜索。3、单选多选。4、二次回显之前选择的数据。5、option 里面显示的内容自定义

如果有您想要实现的功能 可以私聊我

本文只讲解上拉触底加载更多

效果:(名字都是测试数据 随便乱写的 若有冒犯 请联系)

select 二次封装

网上的这种自定义指令上拉加载更多的实例有很多,但是基本都是有缺陷和问题的。为了记录这个问题 我研究了一天,在今天终于搞定了 呜呜呜。

网上遇到的问题:

1、封装的自定义指令没法用(后续会讲解原理)

2、封装完 select 之后 如果一个页面有多个封装的 select 会导致多次触发加载更多。比如一个页面有3个 select 其中一个触发了加载更多 则其他两个也会同时触发(如果是调接口则会触发三次)(后续会讲解原理)

3、当上拉触底多次(比如调用接口可能是 pageindex:1, pageindex:2, pageindex:3 获取三次的数据),这个时候点击其他区域 将 option 隐藏起来 这时候重新点击 select 会重新触发三次的接口请求。(后续会讲解原理)

开始二次封装 selec 组件(只写重点代码其他自己参考)

"element-plus": "^2.8.0",
"vue": "^3.2.47",

1、子组件

1、components/el-load-search-select/index.vue

<template>
  <!-- :popper-class-name 和 :popper-class 和 v-loadmore 为这里的重点!!!!-->
  <el-select
    :popper-class-name="popperClassName"
    v-model="selectedValue"
    v-loadmore="handleLoadMore"
    placeholder="请选择"
    :popper-class="popperClassName"
    :multiple="!isOnlySingle"
    collapse-tags
    reserve-keyword
    v-bind="$attrs"
    :teleported="true"
    filterable
    remote
    :remote-method="handleRemoteMethod"
    @visible-change="handleVisibleChange"
    @change="onSelectChange"
  >
    <el-option v-if="isShowAll" label="全部" value=""></el-option>
    <!-- :label="item.Name" -->
    <el-option
      v-for="item in baseSelectUserList"
      :key="item.Id"
      :label="item.Name"
      :value="item[keyName]"
    >
      <span style="float: left">{{ item.Name }}</span>
      <span style="float: right; color: #8492a6; font-size: 13px">{{
        onShowLabel(item)
      }}</span>
    </el-option>
  </el-select>
</template>
<script setup lang="ts">
   const props = defineProps({
  /** 双向绑定 */
  modelValue: {
    type: [String, Array as () => Array<string>],
    default: null,
  },
  /** 机构参数 */
  orgIds: {
    type: [String, Array as () => Array<string>],
    default: "",
  },
  /** 科室参数 */
  deptIds: {
    type: [String, Array as () => Array<string>],
    default: "",
  },
  /** 角色 */
  roleTypes: {
    type: [String, Array as () => Array<string>],
    default: "",
  },
  /** 是否获取权限内的数据 */
  scopeable: {
    type: Boolean,
    default: false,
  },
  /** 是否是通过redash */
  isRedash: {
    type: Boolean,
    default: false,
  },
  /** 选择的是否是单选 */
  isOnlySingle: {
    type: Boolean,
    default: true,
  },
  /** 双向绑定的值是哪个字段 */
  keyName: {
    type: String,
    default: "Id",
  },
  /** 关键字搜索默认数据 */
  remoteName: {
    type: String,
    default: "",
  },
  /** dtoType */
  dtoTypeName: {
    type: String,
    default: "QueryUserOutputDto3",
  },
  /** 下拉列表显示什么数据 */
  selectShowLabel: {
    type: String,
    default: "",
  },
  /** 是否显示全部选择 */
  isShowAll: {
    type: Boolean,
    default: true,
  },
  /** 是否显示默认列表数据(主要是做回显操作) */
  isUseDefaultList: {
    type: Boolean,
    default: false,
  },
  /** 一个页面多次使用 select popperClassName不能重复 切记!!!!!!  */
  popperClassName: {
    require: true,
    type: String,
  },
});
</script>

2、父组件

<el-load-search-select
            v-model="transferAssistant.oldPhone"
            placeholder="请选择医助"
            :role-types="['doctor']"
            :scopeable="false"
            :is-redash="false"
            :is-only-single="true"
            key-name="PhoneNumber"
            popper-class-name="oldAssistant" // 这里是重点
            style="width: 140px;"
          />

3、自定义指令

src/directive/elSelectLoadMore.ts

import { debounce, DebouncedFunc } from "lodash";
export default {
  mounted(el: any, binding: { value: () => void; },vnode:any) {
    console.log('el', el)

    // 这里的popper-class-name就是使用 select 时候传递的 popper-class-name="oldAssistant" !!!!!
    const popperClassName = el.getAttribute('popper-class-name')
    console.log('popperClassName', popperClassName);
    
    let scrollWrap = document.querySelector(`.${popperClassName} .el-select-dropdown__wrap`)!
    
    // let scrollWrap = document.querySelector('.selectPopperClass .el-select-dropdown__wrap')!
    // 把监听的方法防抖一下
    const handle = debounce((e) => {
      console.log('scrollWrap.scrollTop', scrollWrap.scrollTop);
      console.log('scrollWrap.scrollHeight', scrollWrap.scrollHeight);
      console.log('scrollWrap.clientHeight', scrollWrap.clientHeight);
      let scrollDistance = scrollWrap.scrollHeight - scrollWrap.scrollTop
      // 比如此处预留10个像素的位置用于触底
      if (scrollWrap.clientHeight + 10 > scrollDistance) {
        binding.value() // 触底通知一下,外界
      }
    }, 170)
    // 绑定监听滚动事件
    scrollWrap?.addEventListener('scroll', handle)
    // 方法挂载到元素身上便于解绑时使用
    el._hanlde = handle
 
  },
  unmounted(el: { _hanlde: EventListenerOrEventListenerObject | null; }, binding: any) {
    let scrollWrap: any = document.querySelector('.el-scrollbar__wrap')
    console.log('scrollWrap', scrollWrap)
    scrollWrap?.removeEventListener('scroll', el._hanlde)
    el._hanlde = null
 
  }
}

src/directive/index.ts

import loadmore from "./elSelectLoadMore";
// 自定义指令对象,用于遍历注册
const directives = {
  loadmore,
} as any;
// 批量注册指令并暴露到main.js中去便于注册
export default {
  install(app: { directive: (arg0: string, arg1: any) => void }) {
    Object.keys(directives).forEach((key) => {
      app.directive(key, directives[key]);
    });
  },
};

src/mian.ts

import directive from './directive';
app.use(directive);

上面是所有的代码,接下来讲解上面的三个问题

三个问题的讲解

1、 封装的自定义指令没法用

原因出在let scrollWrap = document.querySelector()! 时候里面写的 class 实际在 dom 中不存在

在 elementplus 时候 select 进行了重构 element 的封装不适合了

2、封装完 select 之后 如果一个页面有多个封装的 select 会导致多次触发加载更多

这里的 select 是在 body 上面的 里面的 class 名称都是一样的 如果你  let scrollWrap = document.querySelector()!里面写的 class 名称是一样的话 就是导致这个问题

因为你每一个都是相同的 class 都回触发自定义指令

而我这边是自己传入了一个自定义属性(上面框起来 有 oldAssistant 和 newAssistant) 通过querySelector(自定义属性)! 那就每一个select不一样了

所以为什么我很强调popper-class-name="" 使用组件的这个属性为什么一定要不一样

3、点击其他区域 将 option 隐藏起来 这时候重新点击 select 会重新触发多次请求

在之前可能你请求了三次 数据可能有100条  假设每一条高度是20px 这时候你的整体高度就是2000px  这个时候你重新点击 select  又去加载数据(远程搜索 空字符串)可能只有30条 这个时候高度就是600px 那么之前的滚动条是在最底部的 elementplus 记录了你上一次的位置 这次你的高度只有600px 完全没有到达之前的高度 就会导致一直触发上拉触底 一直等到你的高度>=2000px的时候才会停止(以上只是推理 没有验证)

完美收官!! 若有问题 下方评论哦 对你有用是我最大的荣幸

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2050898.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】PTA 链式表的按序号查找 C语言

本题要求实现一个函数&#xff0c;找到并返回链式表的第K个元素。 函数接口定义&#xff1a; ElementType FindKth( List L, int K ); 其中List结构定义如下&#xff1a; typedef struct LNode *PtrToLNode; struct LNode {ElementType Data;PtrToLNode Next; }; typedef P…

Mysql原理与调优-Mysql的内存结构

1.绪论 前面说过InnoDB每次查询数据或者更新数据&#xff0c;都是先以16kb的大小将数据读取到内存中&#xff0c;然后对内存中的数据页进行操作。为了减少磁盘IO&#xff0c;Innodb的会先单独的申请一块连续的空间&#xff0c;将从磁盘中的数据页缓存到这片内存中。这片内存就…

数字化转型下的客户服务创新:智能、便捷、人性化

当今这个日新月异的数字时代&#xff0c;企业的竞争已不再局限于产品或服务的本身&#xff0c;而是延伸到了客户体验的每一个细微之处。数字化转型作为推动这一变革的重要力量&#xff0c;正深刻改变着客户服务的面貌&#xff0c;使之变得更加智能、便捷且充满人性化。 一、数字…

Xilinx 7系列收发器GTX入门讲解

目录 一、前言 二、芯片间数据传输技术发展 2.1 时钟/数据同步方式 三、 7系列GTX/GTH 3.1 GTXE2 3.2 Quad 3.3 GTXE2_CHANNEL 3.4 参考时钟结构 3.4.1 外部参考时钟 3.5 CPLL 3.6 QPLL 四、收发器GTX/GTH 4.1 发送器TX 4.2 接收器RX 4.3 TX与RX全流程分析 五、…

CeresPCL 岭回归拟合(曲线拟合)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 由于在使用最小二乘插值拟合时,会涉及到矩阵求逆的操作,但是如果这个矩阵接近于奇异时,那么拟合的结果就会与我们期望的结果存在较大差距,因此就有学者提出在最小二乘的误差函数中添加正则项,即: 这里我们也可…

Catf1ag CTF Web(一)

前言 Catf1agCTF 是一个面向所有CTF&#xff08;Capture The Flag&#xff09;爱好者的综合训练平台&#xff0c;尤其适合新手学习和提升技能 。该平台由catf1ag团队打造&#xff0c;拥有超过200个原创题目&#xff0c;题目设计注重知识点的掌握&#xff0c;旨在帮助新手掌握C…

Pycharm远程连接服务器调试程序(包含VPN连接)

一、Ubuntu服务器使用指南 1、建立个人账户&#xff1a; sudo adduser yourname 2、个人账户中建立conda环境 1&#xff09;将anaconda\miniconda安装包上传到服务器home\yourname目录下 2&#xff09;bash安装miniconda 3&#xff09;source .bashrc激活 3、MobaXterm连…

Spring Cloud Gateway 请求转发源码分析

一、背景 Spring Cloud Gateway 作为一种微服务网关组件&#xff0c;相信大家都不陌生&#xff0c;一个请求经过Spring Cloud Gateway是如何转发出去的&#xff0c;今天我们就来分析一下这部分的源码。 二、正文 下面这张图大家在学习Spring Cloud Gateway的时候肯定见过&am…

NASA数据集:DC-8 飞机上收集测量数据(冰原和永久冻土融化、雪反照率降低以及海盐气溶胶)

ARCTAS DC-8 Aircraft Merge Data 简介 ARCTAS_Merge_DC8_Aircraft_Data 是在 "从飞机和卫星收集对流层成分的北极研究 "亚轨道活动期间&#xff0c;从 DC-8 飞机上收集测量数据的各种现场仪器中预先生成的合并文件。该产品的数据收集工作已经完成。 北极是了解气…

网络编程-阻塞、非阻塞、多路复用、Selector对于accept、read、write事件监听实现详解

阻塞 理论 阻塞模式下&#xff0c;相关方法&#xff08;accept、read、write&#xff09;都会导致线程暂停。 ServerSocketChannel.accept 会在没有连接建立时让线程暂停。SocketChannel.read 会在没有数据可读时让线程暂停。阻塞的表现其实就是线程暂停了&#xff0c;暂停期…

Spring 解决bean的循环依赖

Spring循环依赖-博客园 1. 什么是循环依赖 2. 循环依赖能引发什么问题 循环依赖可能引发以下问题&#xff1a; 初始化顺序不确定&#xff1a;循环依赖导致无法确定哪个对象应该先被创建和初始化&#xff0c;从而造成初始化顺序的混乱。这可能导致错误的结果或意外的行为。死…

YouTube 创作者起诉 Nvidia 和 OpenAI

- **YouTube 创作者 David Millette**&#xff1a;一位 YouTube 创作者 David Millette 起诉了 AI 巨头 Nvidia&#xff0c;指控该公司未经许可使用他的视频来训练 AI 模型。此前不久&#xff0c;Millette 还起诉了 OpenAI&#xff0c;但并未指控这两家公司侵犯版权。 - **指控…

YOLOV8网络结构|搞懂Backbone-C2f

c2f没有改变图像的输入通道数和分辨率 传进去的和传出去的没变 n = 3*d d是模型缩放里面的depth split成两个分支:a和b 经过一个bottleneck就是加一个c 有n个bottleneck 一共是(n+2)个 学习资料:

加密创投周期进化论(下篇):失落的未来

“中心化主义收编”后时代&#xff0c;叙事枯竭怎么破&#xff1f; 作者&#xff1a;Wenser&#xff1b;编辑&#xff1a;郝方舟 出品 | Odaily星球日报&#xff08;ID&#xff1a;o-daily&#xff09; 在《加密创投周期进化论&#xff08;上篇&#xff09;&#xff1a;再造新世…

Win 10录屏也能如此专业?2024年还有3款免费工具,让你大开眼界

无论你是想捕捉游戏中的精彩瞬间&#xff0c;还是打算制作专业的教学视频&#xff0c;或者需要录制在线会议&#xff0c;Win 10都自带了很强的屏幕录制功能。今天我会告诉你怎么用Win 10自带的录屏工具&#xff0c;还会给你推荐三个好用的录屏软件&#xff0c;并且告诉你它们各…

【区块链+金融服务】农业大宗供应链线上融资平台 | FISCO BCOS应用案例

释放数据要素价值&#xff0c;FISCO BCOS 2024 应用案例征集 粮食贸易受季节性影响显著。每年的粮收季节&#xff0c;粮食收储企业会根据下游订单需求&#xff0c;从上游粮食贸易商或粮农手 里大量采购粮食&#xff0c;并分批销售给下游粮食加工企业&#xff08;面粉厂、饲料厂…

HTML—css

css概述 C S S 是 C a s c a d i n g S t y l e S h e e t s &#xff08; 级 联 样 式 表 &#xff09; 。 C S S 是 一 种 样 式 表 语 言 &#xff0c; 用 于 为 H T M L 文 档 控 制 外 观 &#xff0c; 定 义 布 局 。 例 如 &#xff0c; C S S 涉 及 字 体 、 颜 色 、…

社区帮扶对象管理系统pf

TOC springboot419社区帮扶对象管理系统pf 第1章 绪论 1.1 课题背景 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。所以各…

谷歌的高级指令有哪些

今天会分享一些组合用法&#xff0c;这样就能节省许多时间可以放在跟进客户上面&#xff08;本文只介绍谷歌的搜索指令&#xff0c;并无推广&#xff09; part one 谷歌常用的搜索引擎指令&#xff1a; 1、Inurl&#xff0c;在网址中 2、Intext&#xff0c;在网页内容中 3、…

Python使用BeautifulSoup进行网页爬虫技术详解

目录 一、BeautifulSoup简介 1.1 安装BeautifulSoup 1.2 引入BeautifulSoup 二、基本使用 2.1 实例化BeautifulSoup对象 2.2 解析HTML文档 2.2.1 查找标签 2.2.2 获取标签属性和内容 2.3 异常处理 三、进阶使用 3.1 复杂标签查找 3.1.1 CSS选择器 3.1.2 正则表达式…