Element组件 el-select设置滚动条+滚动加载(两种写法: 原生Js和自定义指令)

系列文章目录


提示:下面是简单的功能实现(时间紧迫,大晚上赶工)

el-select滚动条相关功能

  • 系列文章目录
  • 背景与展望
  • 一、使用原生的js实现触底加载
    • 1.效果图如下:
    • 2.HTML如下
    • 3.JS代码如下
  • 二、使用自定义指令解决问题(已补全-2024-05-19)
    • 1.效果图如下:
    • 2.新增功能如下:
    • 3.后续可以优化功能如下:
    • 4.HTML代码如下:
    • 4.Js代码如下:
  • 总结


背景与展望

这次的功能甚至可以说一点也不复杂,但是作为一名前端开发.感觉这种交互行为其实出现在我们这个及其简易的功能场景中,就很离谱。需求做了又砍掉,纯纯的浪费时间,唉

本次的功能主要如下:

  1. 给el-select添加滚动条(设置样式)
  2. 给el-select的滚动条注册scroll事件(记得一定要移除scroll
  3. 体验感优化方法如下:
    添加节流或防抖功能
    添加loading交互
  4. 场景优化:
    不要污染全局的select框
    缓存选择的options(回显)
    采用footer插槽改变现有交互
    拓展远端搜索供能
    usehooks的提取(后面更新)
    自定义指令的的声明(后面更新)

一、使用原生的js实现触底加载

1.效果图如下:

请添加图片描述

2.HTML如下

// 此处使用的是高版本的 el-Select(具体的版本使用的方法都是类似的,下面会提到)
<body>
    <div id="app">
        <div style="margin: 50px 0px;"><el-text class="mx-1" type="primary">初始化的options数据条数如下:{{optionsLength}}</el-text></div>
        <el-select multiple   v-model="value" placeholder="Select" style="width: 160px;    height: 180px;" @visible-change="handleScroll">
            <el-option
                v-for="item in options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            >
            </el-option>
        </el-select>

    </div>
</body>

3.JS代码如下

//因为是使用的HTML文档 所以此处的代码风格是Vue2的
//(我上手还是蛮快的,哈哈哈哈哈哈,都3年多不写Vue2的代码了)
<script>
    const mockData1=[{label:"ceshi ",value:"sele1ct1"},{label:"ce2shi ",value:"sele12ct1"},{label:"cesh2i ",value:"sele3ct1"},{label:"ceshi3 ",value:"select1"},{label:"ceshi4 ",value:"sel1ec23t1"}]
    const { ElMessage } = ElementPlus;
    const App = {
        data() {
            return {
                message: "Hello Element Plus",
                options:[],
                value:"",
                mockOptions:[]
            };
        },
        computed:{
            optionsLength:function(){
                return this.options.length
            }
        },
        methods: {
            createNewOptionsData:function(){
                const str="测试dflklsadj我f的k京东数科了解阿ghjghjgj卡丽打飞gjghj机考拉激发lajfdkl"
                const randomNumber = Math.floor(Math.random()*(str.length-2))
                const result =str.split("")[randomNumber] + str.split("")[randomNumber+1]
                this.options.push({label:"随机生成:"+result,value:result})
            },
            scrollEvent(event){
                const domTarget =event.target
                const translateY = domTarget.scrollTop
                const viewheight =domTarget.clientHeight
                const allHeight = domTarget.scrollHeight
                if(allHeight-translateY<=viewheight){
                    this.createNewOptionsData()
                    // 添加一个数据
                    ElMessage({
                        message: `在Options中添加了一条数据,当前的条数为${this.options.length}`,
                        type: 'success',
                    })
 
                }
            }
            ,
            handleScroll:function(val){
            //这里注释的三个类,主要是抓的弹窗中的popover类,
            //一般情况下都可以使用,我这里使用的是 [el-scrollbar__wrap]
                // el-select-dropdown__wrap el-scrollbar__wrap el-scrollbar__wrap--hidden-default
                const dom = document.querySelector(".el-scrollbar__wrap")
                if(!val){
                    dom.removeEventListener("scroll",this.scrollEvent)
                }
               
                dom.addEventListener("scroll",this.scrollEvent)

            }
        },
        mounted() {
           	//此处都是为了mock数据
            this.options =mockData1
            this.createNewOptionsData()
        },
    };
    const app = Vue.createApp(App);
    app.mount("#app");
</script>



二、使用自定义指令解决问题(已补全-2024-05-19)

敬请期待(2024-05-16 23:55)

1.效果图如下:

请添加图片描述

2.新增功能如下:

  1. JavaScript原生写法 ===> 自定义指令触发
  2. 给触发事件添加节流效果
  3. 将事件缓存到节点上

3.后续可以优化功能如下:

  1. 拓展响应式数据的池子(支持更多功能)
  2. 拓展使用场景。不单单作用el-select组件
  3. 拓展方法的配置

4.HTML代码如下:

// 结构如下
<body>
    <div id="app">
        <div style="margin: 50px 0px;">
            <el-text class="mx-1" type="primary">初始化的options数据条数如下:{{optionsLength}}</el-text>
        </div>
        <el-select v-if="boolen" v-selectscroll="options" multiple popper-class="select-scroll" v-model="value"
            placeholder="Select" style="width: 160px; height: 180px;">
            <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
        </el-select>

    </div>
</body>

4.Js代码如下:

    const { ElMessage } = ElementPlus;
    const { createApp, ref, watchEffect, watch } = Vue;
    const mockData1 = [{ label: "ceshi ", value: "sele1ct1" }, { label: "ce2shi ", value: "sele12ct1" }, { label: "cesh2i ", value: "sele3ct1" }, { label: "ceshi3 ", value: "select1" }, { label: "ceshi4 ", value: "sel1ec23t1" }]
    const App = {
        data() {
            return {
                options: [],
                value: "",
            };
        },
        computed: {
            optionsLength: function () {
                return this.options.length
            }
        },
    };
    const app = createApp(App);
    app.directive("selectscroll", {
        created: function (el, binding) {
            el.__flag = false
            const getCurrentTimer = () => {
                const now = new Date();
                const year = now.getFullYear();
                const month = (now.getMonth() + 1).toString().padStart(2, '0');
                const day = now.getDate().toString().padStart(2, '0');
                const hours = now.getHours().toString().padStart(2, '0');
                const minutes = now.getMinutes().toString().padStart(2, '0');
                const seconds = now.getSeconds().toString().padStart(2, '0');
                const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
                return formattedDate
            }
            el.__curentTimer = getCurrentTimer
            console.log("自定义指令created");
        },
        mounted: (el, binding) => {
            console.log("自定义指令mounted");
            mockData1.forEach(item => {
                binding.value.push(item)
            })

            const createNewOptionsData = async function () {
                const str = "测试dflklsadj我f的k京东数科了解阿ghjghjgj卡丽打飞gjghj机考拉激发lajfdkl"
                const randomNumber = Math.floor(Math.random() * (str.length - 2))
                const result = str.split("")[randomNumber] + str.split("")[randomNumber + 1]
                binding.value.push({ label: "随机生成:" + result, value: result })
                const node = document.createElement('p')
                node.innerText = `生成数据的时间是:${el.__curentTimer()}`
                document.body.appendChild(node)
            }
            const handleScroll = async function (event) {

                clearTimeout(el.__flag)
                el.__flag = setTimeout(async () => {
                    const domTarget = event.target
                    const translateY = domTarget.scrollTop
                    const viewheight = domTarget.clientHeight
                    const allHeight = domTarget.scrollHeight
                    if (allHeight - translateY <= viewheight + 2) {

                        await createNewOptionsData()
                        // 添加一个数据
                        ElMessage({
                            message: `在Options中添加了一条数据,当前的条数为${binding.value.length}`,
                            type: 'success',
                        })

                    }
                }, 1500);



            }
            const dom = document.querySelector(".select-scroll .el-scrollbar__wrap")
            dom.addEventListener("scroll", handleScroll)
            el.__handleScroll = handleScroll
            el.__scrollDom = dom

        },
        unmounted(el, binding) {
            // const dom = document.querySelector(".select-scroll .el-scrollbar__wrap")
            el.__scrollDom.removeEventListener("scroll", el.__handleScroll)
            console.log("成功注销了");
        }

    })


总结

希望自己的写法可以帮助到遇到问题的人。有不足之处,或者可以优化的地方,欢迎大家给出自己的建议,会从大家的建议中汲取营养,提升自己!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何提交网站到谷歌网站收录?

其实就那么几个步骤&#xff0c;要做谷歌那肯定是需要一个谷歌账号的&#xff0c;然后找到Google Search Console这个谷歌的官方平台&#xff0c;这是最权威的可以统计来自谷歌流量的平台了&#xff0c;毕竟是谷歌自家的&#xff0c;肯定也不可能作假&#xff0c;然后就是跟着平…

使用DockerFile 编写 指令来构建镜像

文章目录 前言使用DockerFile 编写 指令来构建镜像1. 构建2. 验证 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖的话&#x…

二进制部署k8s集群 部署高可用master节点

目录 本次部署的环境 一、master02 节点部署 二、负载均衡部署 安装nginx服务 部署keepalive服务 修改node节点上的配置文件 在master节点上创建pod 三、部署 Dashboard 二进制部署k8s集群部署的步骤总结 &#xff08;1&#xff09;k8s的数据存储中中心的搭建 etcd &…

UNION的使用

UNION的使用 给出将多条查询语句组合成单个结果集&#xff0c;两个表对应的列数和数据类型必须相同 UNION操作符&#xff1a; 返回两个查询结果集的并集&#xff0c;并去除重复记录 UNION ALL操作符 返回两个查询的结果集的并集。不去掉两个结果集的重复部分&#xff0c;重…

【Linux】Linux信号产生,接受与处理机制

理解Linux信号产生&#xff0c;接受与处理机制 信号是Linux操作系统中一种用于进程间通信和异步事件处理的机制。在本文中&#xff0c;我们将结合Linux的源码&#xff0c;深入分析信号的产生、发送、接收和处理的底层原理。 文章目录 理解Linux信号产生&#xff0c;接受与处理…

一、QGroundControl地面站使用介绍

文章目录 环境功能介绍飞行视图规划视图飞机设置分析工具程序设置 连接飞机飞机设置分析工具飞行视图规划任务 总结参考 环境 QGroundControl V4.2.0PX4-Autopilot V1.3.0devGazebo 模拟无人机 功能介绍 飞行视图规划视图飞机设置分析工具程序设置 飞行视图 软件打开后为飞…

跟着鲁sir学CV_Opencv(10)卡尔曼滤波

简介 卡尔曼滤波器由鲁道夫卡尔曼&#xff08;Rudolf E. Klmn&#xff09;在1960年提出&#xff0c;广泛应用于导航系统、信号处理、机器人定位、金融等多个领域。 主要分为两阶段&#xff1a;预测与更新 贝叶斯滤波器 贝叶斯框架下&#xff1a;预测&#xff08;先验&#x…

楼道堆积物视觉识别监控系统

楼道堆积物视觉识别监控系统采用了AI神经网络和深度学习算法&#xff0c;楼道堆积物视觉识别监控系统通过摄像头实时监测楼道的情况&#xff0c;通过图像处理、物体识别和目标跟踪算法&#xff0c;系统能够精确地识别楼道通道是否被堆积物阻塞。楼道堆积物视觉识别监控系统检测…

K210的MicroPython扩展例程——自动驾驶例程(视觉循迹)

前言 该例程实现的功能是循迹功能&#xff0c;可为想拿K210做视觉循迹开发作为参考 例程使用前需要搭建好MicroPython的开发环境 K210开发板MicroPython开发环境搭建 一、将K210连接好后打开CanMV IDE&#xff0c;连接成功后&#xff0c;三角形变成绿色 二、然后要把小车驱动…

接口测试怎么测?为什么要做接口测试?

一、前言 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间及内部各个子系统之间的交互点。测试的重点是检查数据的交换、传递和控制管理过程&#xff0c;以及系统间的逻辑依赖关系等。 简单地说&#xff0c;接口测试就是通过URL向服务器或者…

leetCode-hot100-数组专题之区间问题

数组专题之区间问题 知识点&#xff1a;解决思路&#xff1a;例题56.合并区间57.插入区间253.会议室 Ⅱ485.无重叠区间 数组区间问题是算法中常见的一类问题&#xff0c;它们通常涉及对数组中的区间进行排序、合并、插入或删除操作。无论是合并区间、插入区间还是删除重复空间&…

azure gpt 技术教程教学 | 在Azure OpenAI 上部署GPT-4o

Azure OpenAI GPT-4o是OpenAI推出的最新旗舰级人工智能模型。GPT-4o模型设计为能够实时对音频、视觉和文本进行推理&#xff0c;这是迈向更自然人机交互的重要一步。该模型的一大特点是能够处理多种类型的数据输入和输出&#xff0c;包括文本、音频和图像&#xff0c;实现了跨模…

适用于Windows 电脑的最佳视频恢复软件和方法

毫无疑问&#xff0c;丢失您的基本数据总是有压力的&#xff0c;尤其是当这些是您为捕捉最美好回忆而收集的重要视频文件时。要恢复丢失或损坏的视频文件&#xff0c;您可以借助视频恢复工具。但是&#xff0c;在选择最佳视频恢复工具时&#xff0c;您必须考虑多个扫描选项&…

Windows10安装python3.8.2

1、下载与安装 下载地址&#xff1a;https://www.python.org/downloads/release/python-382/ 滑动到页面底部 下载好的安装包安装到合适的位置&#xff08;默认安装到C盘&#xff09; 安装的时候&#xff0c;见到Add Python 3.8 to PATH 记得勾选. 2、检测安装是否成功 cm…

Facebook隐私保护:数据安全的前沿挑战

在数字化时代&#xff0c;随着社交媒体的普及和应用&#xff0c;个人数据的隐私保护问题日益受到关注。作为全球最大的社交平台之一&#xff0c;Facebook承载了数十亿用户的社交活动和信息交流&#xff0c;但与此同时&#xff0c;也面临着来自内外部的数据安全挑战。本文将深入…

Flask Response 对象

文章目录 创建 Response 对象设置响应内容设置响应状态码设置响应头完整的示例拓展设置响应的 cookie重定向响应发送文件作为响应 总结 Flask 是一个 Python Web 框架&#xff0c;用于快速开发 Web 应用程序。在 Flask 中&#xff0c;我们使用 Response 对象来构建 HTTP 响应。…

汽车IVI中控开发入门及进阶(十九):监控视频图像分割处理

图像分割是一种计算机视觉技术,可将数字图像分成离散的像素组(图像分段),为对象检测和相关任务提供信息。通过将图像的复杂视觉数据解析为特定形状的片段,图像分割可以实现更快、更先进的图像处理。 图像分割技术的范围很广,从简单直观的启发式分析到最前沿的深度学习实…

【论文笔记】advPattern

【论文题目】 advPattern: Physical-World Attacks on Deep Person Re-Identification via Adversarially Transformable Patterns Abstract 本文首次尝试对深度reID实施鲁棒的物理世界攻击。提出了一种新颖的攻击算法&#xff0c;称为advPattern&#xff0c;用于在衣服上生成…

CR80清洁卡都能用在什么地方?

CR80清洁卡&#xff08;也被称为ISO 7810 ID-1清洁卡&#xff09;的规格确实使其在各种需要读取磁条或接触式智能卡的设备中都有广泛的用途。这些设备包括但不限于&#xff1a; ATM自动终端机&#xff1a;当ATM机的磁条读卡器出现故障或读卡不灵敏时&#xff0c;可以使用CR80清…

H800基础能力测试

H800基础能力测试 参考链接A100、A800、H100、H800差异H100详细规格H100 TensorCore FP16 理论算力计算公式锁频安装依赖pytorch FP16算力测试cublas FP16算力测试运行cuda-samples 本文记录了H800基础测试步骤及测试结果 参考链接 NVIDIA H100 Tensor Core GPU Architecture…