vue自定义穿梭框支持远程滚动加载
分享-2023年资深前端进阶:前端登顶之巅-最全面的前端知识点梳理总结,前端之巅
*分享一个使用比较久的🪜
技术框架公司的选型(老项目):vue2 + iview-ui
方案的实现思路是共性的,展现UI样式需要你们自定义进行更改;因为iview是全局注入,基本使用原先的类名进行二次创建公共组件,修改基础js实现逻辑;
需求分析:实现远程滚动加载数据的穿梭框
1、创建自定义穿梭框,分左侧和右侧数据
2、依赖后端接口,左侧是左侧数据,右侧是右侧数据
3、定义好出入参数,支持回显内容及选中内容的去重处理
4、绑定对应的v-model数据响应
5、滚动加载数据,区分左右区域;添加自定义指令进行监听
6、滚动加载数据,不丢失已选中的数据,或去重已选中数据
7、支持左右侧的远程搜索功能,左右互不影响,检索数据放组件外部进行
1、代码信息
创建ivu-transfer.vue文件;依赖iviewUI请依据自己的样式进行拷贝;
1.1 自定义滚动监听指令
/** 远程滚动加载 */
import Vue from 'vue'Vue.directive("loadTransfer", {bind(el, binding) {const select_dom = el.querySelectorAll('.ivu-transfer-list .ivu-transfer-list-content');select_dom.forEach((item, index) => {item.addEventListener('scroll', function () {const height = this.scrollHeight - this.scrollTop - 1 <= this.clientHeight;if (height) {binding.value(index)}})})}
})
1.2 自定义穿梭框代码
<template><div class="ivu-transfer"><divclass="ivu-transfer-list":style="{width: listStyle.width,height: listStyle.height}"><div class="ivu-transfer-list-header"><Checkbox:value="checkLeftAll"@on-change="handleAllLeftCheck"></Checkbox><span class="ivu-transfer-list-header-title">源列表</span><span class="ivu-transfer-list-header-count">{{ leftDataSource.length }}</span></div><div class="ivu-transfer-list-body"><div class="ivu-transfer-list-content"><CheckboxGroup v-model="checkLeftAllGroup"><Checkbox:key="index":label="item.value"class="ivu-transfer-list-content-item"v-for="(item, index) in leftDataSource">{{item.label +`${item.description ? ` - ${item.description}` : ""}`}}</Checkbox></CheckboxGroup><divv-if="!leftDataSource.length"class="ivu-transfer-list-content-not-found">列表为空</div></div></div></div><div class="ivu-transfer-operation"><Buttonsize="small"type="primary"icon="ios-arrow-back"@click="handleClickArrowBack":disabled="!checkRightAllGroup.length"></Button><Buttonsize="small"type="primary"icon="ios-arrow-forward"@click="handleClickArrowForward":disabled="!checkLeftAllGroup.length"></Button></div><divclass="ivu-transfer-list":style="{width: listStyle.width,height: listStyle.height}"><div class="ivu-transfer-list-header"><Checkbox:value="checkRightAll"@on-change="handleAllRightCheck"></Checkbox><span class="ivu-transfer-list-header-title">目的列表</span><span class="ivu-transfer-list-header-count">{{ rightDataSource.length }}</span></div><div class="ivu-transfer-list-body"><div class="ivu-transfer-list-content"><CheckboxGroup v-model="checkRightAllGroup"><Checkbox:key="index":label="item.value"class="ivu-transfer-list-content-item"v-for="(item, index) in rightDataSource">{{item.label +`${item.description ? ` - ${item.description}` : ""}`}}</Checkbox></CheckboxGroup><divv-if="!rightDataSource.length"class="ivu-transfer-list-content-not-found">列表为空</div></div></div></div></div>
</template><script>
const methods = {// 点击左侧全选handleAllLeftCheck() {this.checkLeftAll = !this.checkLeftAll;if (this.checkLeftAll) {this.checkLeftAllGroup = this.leftDataSource.map(item => item.value);} else {this.checkLeftAllGroup = [];}},// 点击右侧全选handleAllRightCheck() {this.checkRightAll = !this.checkRightAll;if (this.checkRightAll) {this.checkRightAllGroup = this.rightDataSource.map(item => item.value);} else {this.checkRightAllGroup = [];}},// 点击向右数据handleClickArrowBack() {this.moveCheckedData("left");},// 点击向左数据handleClickArrowForward() {this.moveCheckedData("right");},moveCheckedData(direction) {const newLeftDataSource = [];const newRightDataSource = [];const dataSource =direction === "left" ? this.rightDataSource : this.leftDataSource;dataSource.forEach(item => {const index =direction === "left"? this.checkRightAllGroup.indexOf(item.value): this.checkLeftAllGroup.indexOf(item.value);if (index !== -1) {direction === "left"? newLeftDataSource.push(item): newRightDataSource.push(item);} else {direction === "left"? newRightDataSource.push(item): newLeftDataSource.push(item);}});this.leftDataSource =direction === "left"? [...this.leftDataSource, ...newLeftDataSource]: newLeftDataSource;this.rightDataSource =direction === "left"? newRightDataSource: [...this.rightDataSource, ...newRightDataSource];this.checkLeftAll = false;this.checkRightAll = false;this.checkLeftAllGroup = [];this.checkRightAllGroup = [];this.$emit("on-change", this.leftDataSource, this.rightDataSource, direction);},filterDataMethods() {const rightValues = new Set(this.rightDataSource.map(opt => opt.value));this.leftDataSource = this.leftDataSource.filter(item => !rightValues.has(item.value));this.$nextTick(() => {const leftValues = new Set(this.leftDataSource.map(opt => opt.value));this.rightDataSource = this.rightDataSource.filter(opt => !leftValues.has(opt.value));});}
};export default {props: {listStyle: {type: Object,default: () => ({width: "250px",height: "380px"})},leftData: {type: Array,require: true,default: () => []},rightData: {type: Array,require: true,default: () => []}},data() {return {checkLeftAll: false,checkRightAll: false,checkRightAllGroup: [],checkLeftAllGroup: [],leftDataSource: [],rightDataSource: []};},watch: {leftData(newVal) {this.leftDataSource = newVal;this.filterDataMethods();},rightData(newVal) {this.rightDataSource = newVal || [];this.filterDataMethods();}},mounted() {this.$nextTick(() => {this.$emit("on-change", this.leftDataSource, this.rightDataSource);})},methods
};
</script><style lang="less" scoped>
.ivu-transfer-list-content-item {width: 100%;margin-left: -0.3em;
}.ivu-transfer-list-content-not-found {display: block;
}
</style>
2、内容使用api介绍
1、树形结构入参:
dataSource=[{label: '测试',value: 1, description: '拼接内容' }]
,
2、标签引用:<IvuTransfer :leftData="dataSource" :rightData="targetKeys" @on-change="handleChange" v-loadTransfer="handleLoadMore" />
3、相关api说明文档在文章底部
<template><div class="customSearch"><Inputsearchclearablev-model="formLeftInput"placeholder="请输入搜索内容"@on-clear="handleOnLeftInput"@on-search="handleOnLeftInput"/><div style="width: 50px"></div><Inputsearchclearablev-model="formRightInput"placeholder="请输入搜索内容"@on-clear="handleOnRightInput"@on-search="handleOnRightInput"/></div><IvuTransfer:leftData="dataSource":rightData="targetKeys"@on-change="handleChange"v-loadTransfer="handleLoadMore"/></template>
// 远程滚动加载handleLoadMore(index) {if (index === 0 && this.dataLeftHasMore && !this.isShowLoading) {this.curLeftPage++;this.getLeftMockData();}if (index === 1 && this.dataRightHasMore && !this.rightLoading) {this.curRightPage++;this.getRightTargetKeys();}},// 触发选中移动handleChange(newLeftTargetData, newRightTargetKeys, direction) {this.dataSource = [...newLeftTargetData];this.targetKeys = [...newRightTargetKeys];if (direction === "right") {return this.remoteCheckPage();}if (direction === "left") {return this.remoteRightCheckPage();}},getLeftData() {},
getRightData() {}
参数 | 说明 | 类型 | 默认值 | 必填项 |
---|---|---|---|---|
leftData | [{}]-label,value结构 | Array[] | [] | 是 |
rightData | [{}]-label,value结构 | Array[] | [] | 是 |
on-change | 数据变更触发 | newLeft,newRight, direction | 无 | 否 |
相关文章:

vue自定义穿梭框支持远程滚动加载
分享-2023年资深前端进阶:前端登顶之巅-最全面的前端知识点梳理总结,前端之巅 *分享一个使用比较久的🪜 技术框架公司的选型(老项目):vue2 iview-ui 方案的实现思路是共性的,展现UI样式需要你们自定义进行更改&#…...

TCP 协议十大相关特性总结
目录 一、TCP特性 二、报文格式 TCP十大核心特性 1. 确认应答 2. 超时重传 3. 连接管理(三次握手,四次挥手) 三次握手 四次挥手 4. 滑动窗口 情况一:接收方的ACK丢失 情况二:发送方的数据包丢失 5. 流量控制 6. 拥塞控制 7. 延迟应答 8. 捎带应答 9. 字节流粘包问题 10. TCP的…...

文档控件DevExpress Office File API v23.1新版亮点 - 支持.NET MAUI
DevExpress Office File API是一个专为C#, VB.NET 和 ASP.NET等开发人员提供的非可视化.NET库。有了这个库,不用安装Microsoft Office,就可以完全自动处理Excel、Word等文档。开发人员使用一个非常易于操作的API就可以生成XLS, XLSx, DOC, DOCx, RTF, CS…...
分割字符串的最大得分
题目: 给你一个由若干 0 和 1 组成的字符串 s ,请你计算并返回将该字符串分割成两个 非空 子字符串(即 左 子字符串和 右 子字符串)所能获得的最大得分。 「分割字符串的得分」为 左 子字符串中 0 的数量加上 右 子字符串中 1 的…...

ASR 语音识别接口封装和分析
这个文档主要是介绍一下我自己封装了 6 家厂商的短语音识别和实时流语音识别接口的一个包,以及对这些接口的一个对比。分别是,阿里,快商通,百度,腾讯,科大,字节。 zxmfke/asrfactory (github.c…...

C 语言的 ctype.h 头文件
C 语言的 ctype.h 头文件包含了很多字符函数的函数原型, 可以专门用来处理一个字符, 这些函数都以一个字符作为实参. ctype.h 中的字符测试函数如表所示: 这些测试函数返回 0 或 1, 即 false 或 true. ctype.h 中的字符映射函数如表所示: 字符测试函数不会修改原始实参, 只会…...

Linux系统编程:采用管道的方式实现进程间通信
目录 一. 进程间通信概述 二. 管道的概念 三. 通过管道实现进程间通信 3.1 实现原理 3.2 匿名管道创建系统接口pipe 3.3 管道通信的模拟实现 3.4 管道通信的访问控制规则 3.5 管道通信的特点 四. 通过匿名管道实现进程池 4.1 进程池的概念 4.2 进程池的模拟实现 五…...
网络安全面试题
什么是SQL注入攻击 SQL 注入攻击是一种常见的 Web 应用程序安全漏洞,攻击者通过在 Web 应用程序的输入框、搜索框、登陆框等地方注入恶意的 SQL 语句,从而获取未授权的访问权限或者窃取敏感数据。攻击者利用注入的 SQL 语句执行恶意操作,例如…...
如何成为游戏主程
前言 前段时间有人在知乎上提问,如何成为主程,技术毋庸置疑是最重要的,但很多事情我认为主要是要有思路和品位。 1、技术 1、技术是程序员吃饭的手艺,打磨自己的手艺肯定无可厚非 2、保持对技术的热爱,不断学习&…...

SSM整合(XML方式)
文章目录 SSM整合之后xml方式1 系统环境1.1 软件环境1.2 项目环境1.3 配置web.xml1.4 配置jdbc.properties文件1.5 配置SpringMVC核心文件1.6 配置Spring的核心文件1.7 配置MyBatis的核心文件1.8 配置数据库1.9 配置文件位置 2 编写后端代码2.1 编写实体类2.2 编写Dao接口2.3 编…...
学习Vue:列表渲染(v-for)
在 Vue.js 中,实现动态列表的显示是非常常见的需求。为了达到这个目的,Vue 提供了 v-for 指令,它允许您迭代一个数组或对象,将其元素渲染为列表。然而,在使用 v-for 时,key 属性的设置也非常重要࿰…...

使用巴特沃兹滤波器的1D零相位频率滤波研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

ubuntu18.04安装cuda
卸载之前安装的驱动 sudo apt-get purge nvidia*安装驱动 方法1: 查看显卡适配的NVIDIA的驱动 ubuntu-drivers devices安装recommend推荐的版本 sudo apt-get install nvidia-driver-455方法2: 或者直接使用下面命令安装 sudo ubuntu-drivers au…...
【MFC】09.MFC视图-笔记
MFC视图窗口:CView类 显示数据/画面 我们之前的绘图消息,都是在框架类上画出来的 视图窗口就覆盖在框架窗口上 视图窗口本质上也是窗口,只是和框架窗口风格不同 CView类也继承于CWnd类 CView也能处理消息,因为它继承于CWnd类…...

【字节跳动青训营】后端笔记整理-2 | Go实践记录:猜谜游戏,在线词典,Socks5代理服务器
**本人是第六届字节跳动青训营(后端组)的成员。本文由博主本人整理自该营的日常学习实践,首发于稀土掘金:🔗Go实践记录:猜谜游戏,在线词典,Socks5代理服务器 | 青训营 我的go开发环境…...
GPT的第一个创作
嗨,大家好,我是赖兴泳!今天,我要和大家聊一聊前端开发,就像我用音符创造音乐一样,前端开发也是创造美丽的用户界面的过程。 前端开发是构建网站和应用程序用户界面的关键部分。就像音乐家需要精心编排音符…...
Spring Boot 获取前端参数
Spring Boot 获取前端参数 在开发 Web 应用程序时,前端参数是非常重要的。Spring Boot 提供了多种方法来获取前端参数,本文将介绍其中的一些常用方法。 1. 使用 RequestParam 注解 RequestParam 注解是 Spring MVC 提供的一种常用方式,用于…...
java应用运行在docker,并且其他组件也在docker
docker启动redis容器 # create redis docker run -d --name redis-container -p 6379:6379 redis:latest创建java 应用 dockerfile FROM openjdk:17##Pre-create related directories RUN mkdir -p /data/etax/ms-app WORKDIR /data/etax/ms-appEXPOSE 10133 COPY ./target…...

Java真实面试题,offer已到手
关于学习 在黑马程序员刚刚开始的时候学习尽头非常足,到后面逐渐失去了一些兴趣,以至于后面上课会出现走神等问题,但是毕业时后悔晚矣。等到开始学习项目一的时候,思路总会比别人慢一些,不看讲义写不出来代码。 建议…...
在序列化、反序列化下如何保持单例(Singleton)模式
1、序列化、反序列化 在 Java 中,当一个对象被序列化后再被反序列化,通常情况下会创建一个新的对象实例。这是因为序列化将对象的状态保存到字节流中,而反序列化则是将字节流重新转化为对象。在这个过程中,通常会使用类的构造函数…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...