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

用vue2+elementUI封装手机端选择器picker组件,支持单选、多选、远程搜索多选

单选注意点:

  1. @touchmove.prevent: 在 touchmove 事件上添加 .prevent 修饰符,以阻止默认的滚动行为。

  2. handleTouchStart: 记录触摸开始的 Y 坐标和当前的 translateY 值。

  3. handleTouchMove: 计算触摸移动的距离,并更新 translateY 值。

  4. handleTouchEnd: 根据 translateY 计算当前选中的索引,并更新 translateY 值。

  5. handleCancel: 触发取消事件。

  6. handleConfirm: 触发确认事件,并传递当前选中的选项。

  7. clampTranslateY: 确保 translateY 值在合理范围内。

多选注意点:

  1. clickItem: 为选中的选项改变样式

  2. handleConfirm: 触发确认事件,并传递当前选中的选项。

远程搜索多选注意点:

     1. 单独给el-popper设置样式,发现无效,原因是el-popper和<div id="app">...</div>组件处于同一层级,解决方法是使用popper-class属性给el-popper定义一个class,另外在style中去掉scoped。

效果如下:

        

单选/多选picker.vue组件:

<template><div><div class="picker-mask"></div><divclass="picker"@touchstart="handleTouchStart"@touchmove="handleTouchMove"@touchmove.prevent="handleTouchMove"@touchend="handleTouchEnd"><div class="picker-actions"><el-button type="text" @click="handleCancel">取消</el-button><el-button type="text" @click="handleConfirm">确认</el-button></div><div class="picker-box" v-if="chooseOptions.length"><divclass="picker-content":style="{ transform: `translateY(${translateY}px)` }"><divv-for="(item, index) in chooseOptions":key="index":class="item.chooseFlag ? 'choose-item' : 'picker-item'"@click="multiple ? clickItem(index) : null">{{ labelKey ? item[labelKey] : item }}</div></div></div><div class="empty" v-else>暂无数据</div><divv-if="chooseOptions.length && !multiple"class="picker-highlight"></div></div></div>
</template><script>
export default {props: {options: {type: Array,default: () => []},labelKey: {type: String,default: ''},selectedOption: {type: [Object, Array],default: () => []},multiple: {type: Boolean,default: false}},data() {return {startY: 0,translateY: 40,currentIndex: 0,startTranslateY: 40,chooseOptions: this.multiple? this.options?.map(v => ({ ...v, chooseFlag: false })) || []: this.options || []};},mounted() {if (this.multiple && this.selectedOption?.length) {console.log('selectedOption', this.selectedOption);console.log(this.options);this.chooseOptions =this.options?.map(v => ({...v,chooseFlag: this.selectedOption?.some(item => item[this.labelKey] === v[this.labelKey])})) || [];}// 根据选项列表和当前选中项,设置当前索引和滚动位置if (!this.multiple && this.options.indexOf(this.selectedOption) !== -1) {this.currentIndex = this.options.indexOf(this.selectedOption);this.translateY = -40 * this.currentIndex + 40;}},methods: {// 记录触摸开始的 Y 坐标和当前的 translateY 值handleTouchStart(event) {this.startY = event.touches[0].clientY;this.startTranslateY = this.translateY ?? 0;},// 计算触摸移动的距离,并更新 translateY 值。handleTouchMove(event) {const deltaY = event.touches[0].clientY - this.startY;this.translateY = this.startTranslateY + deltaY;this.clampTranslateY();},// 根据 translateY 计算当前选中的索引,并更新 translateY 值handleTouchEnd() {const index = Math.round(this.translateY / 40);this.translateY = index * 40;this.currentIndex = -Math.round((this.translateY - 40) / 40);},// 确保 translateY 值在合理范围内clampTranslateY() {const itemHeight = 40;const maxTranslateY = 40;const minTranslateY =maxTranslateY - (this.options.length - 1) * itemHeight;this.translateY = Math.max(minTranslateY,Math.min(maxTranslateY, this.translateY));},clickItem(index) {this.chooseOptions[index].chooseFlag =!this.chooseOptions[index].chooseFlag;},handleCancel() {console.log('cancel');this.$emit('cancel');},handleConfirm() {const result = this.multiple? this.chooseOptions?.filter(v => v.chooseFlag): this.chooseOptions?.[this.currentIndex];this.$emit('confirm', result);}}
};
</script><style scoped>
.picker-mask {z-index: 2014;position: fixed;top: 0;left: 0;width: 100%;height: 100%;background: rgba(0, 0, 0, 0.7);border-radius: 8px;
}
.picker {position: fixed;bottom: 0;left: 0;width: 100%;height: 200px;overflow: hidden;background-color: #fff;z-index: 2014;color: #323233;font-size: 16px;border-radius: 8px;
}
.picker-box {flex: 1;overflow: hidden;
}.picker-content {display: flex;flex-direction: column;align-items: center;transition: transform 0.3s ease;
}.picker-item {height: 40px;line-height: 40px;text-align: center;width: 100%;
}.picker-highlight {position: absolute;top: 60%;left: 0;width: 100%;height: 40px;transform: translateY(-50%);background-color: rgba(255, 255, 255, 0.7);border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;
}.picker-actions {width: 100%;display: flex;justify-content: space-between;padding: 10px 0;z-index: 2024;background-color: #fff;.el-button {margin: 0 8px;}
}.choose-item {height: 40px;line-height: 40px;text-align: center;color: #2c68ff;width: 100%;
}.choose-item::after {position: absolute;right: 20px;font-family: 'element-icons';content: '';font-size: 12px;font-weight: bold;-webkit-font-smoothing: antialiased;
}.empty {text-align: center;
}
</style>

远程搜索多选picker组件,可以增加远程搜索属性,自己改造使用:

<template><div><div class="picker-mask"></div><div class="picker"><div class="picker-actions"><el-button type="text" @click="handleCancel">取消</el-button><el-button type="text" @click="handleConfirm">确认</el-button></div><div class="picker-box"><el-selectcollapse-tagsfilterablemultiplevalue-key="id"default-first-option:clearable="true"v-model="selectList"placeholder="请输入"popper-class="select-popper"@change="handleChange"><el-optionv-for="item in userSuccessorNowList":key="item.id":value="item":label="item.vname"/></el-select></div></div></div>
</template><script>
export default {props: {selectedOption: {type: Array,default: () => []},labelKey: {type: String,default: ''}},data() {return {selectList: [],userSuccessorNowList: [{ id: 1, vname: 'aaa' },{ id: 2, vname: 'bbb' },{ id: 3, vname: 'ccc' },{ id: 4, vname: 'aaa' },{ id: 5, vname: 'bbb' },{ id: 6, vname: 'ccc' }]};},mounted() {if (this.selectedOption?.length) {console.log('selectedOption', this.selectedOption);this.selectList = this.selectedOption;}},methods: {handleChange(val) {this.selectList = val;console.log('selectList', this.selectList);},handleCancel() {this.$emit('cancel');},handleConfirm() {this.$emit('confirm', this.selectList);}}
};
</script>
<style>
.select-popper {width: 100vw !important;z-index: 2014 !important;left: 0 !important;box-shadow: none;height: 120px !important;overflow: auto;.popper__arrow {display: none !important;}.el-scrollbar__view {text-align: center;}
}
</style><style scoped>
.picker-mask {z-index: 1014;position: fixed;top: 0;left: 0;width: 100%;height: 100%;background: rgba(0, 0, 0, 0.7);border-radius: 8px;
}
.picker {position: fixed;bottom: 0;left: 0;width: 100%;height: 250px;overflow: hidden;background-color: #fff;z-index: 1014;color: #323233;font-size: 16px;border-radius: 8px;.el-select {width: 100%;.el-input__suffix {display: none;}}
}.picker-actions {width: 100%;display: flex;justify-content: space-between;padding: 10px 0;z-index: 2024;background-color: #fff;.el-button {margin: 0 8px;}
}.picker-box {flex: 1;overflow: hidden;
}
</style>

选择器父组件:

<template><div><div class="select-box" @click="togglePicker"><div class="select-content"><div class="select-label"><span class="label">{{ label }}<span v-if="required" style="color: rgba(253, 75, 76, 1)"> * </span></span></div><spanclass="select-value":style="{ color: `${!selectedOption ? 'rgba(0,0,0,0.25)' : ''}` }">{{ selectedOption ? showResults(selectedOption) : placeholder }}</span></div><i class="el-icon-arrow-right"></i></div><div v-if="showPicker"><SearchPickerv-if="pickerType === 'search'":options="options":labelKey="labelKey"@confirm="handleConfirm"@cancel="handleCancel":selectedOption="selectedOption"/><Pickerv-else:options="options":labelKey="labelKey"@confirm="handleConfirm"@cancel="handleCancel":selectedOption="selectedOption":multiple="multiple"/></div></div>
</template><script>
import Picker from '../Picker';
import SearchPicker from '../SearchPicker';export default {components: {Picker,SearchPicker},props: {label: {type: String,default: ''},pickerType: {type: String,default: ''},required: {type: Boolean,default: false},options: {type: Array,default: () => []},labelKey: {type: String,default: ''},placeholder: {type: String,default: '请选择'},multiple: {type: Boolean,default: false}},data() {return {selectedOption: null,showPicker: false};},mounted() {this.getResults();},methods: {getResults() {if (this.multiple) {this.selectedOption = this.selectedOption || null;} else {this.selectedOption = this.selectedOption?.[this.labelKey];}},showResults(selectedOption) {if (this.multiple) {return selectedOption.map(v => v[this.labelKey]).join(',');} else {return selectedOption;}},togglePicker() {this.showPicker = !this.showPicker;},handleConfirm(selectedOption) {if (this.multiple) {this.selectedOption = selectedOption?.length ? selectedOption : null;} else {this.selectedOption = selectedOption;}this.showPicker = false;this.getResults();},handleCancel() {this.showPicker = false;}}
};
</script><style lang="scss" scoped>
.select-box {width: 100%;height: 48px;line-height: 40px;text-align: left;background-color: #fff;cursor: pointer;display: flex;justify-content: space-between;align-items: center;.select-content {display: flex;align-items: center;.select-label {width: 90px;}.select-value {@include textElipsis(1);width: calc(100% - 90px);}}span {font-family: PingFangSC, PingFang SC;font-weight: 400;font-size: 16px;color: rgba(0, 0, 0, 0.85);line-height: 24px;text-align: left;font-style: normal;text-transform: none;}i {color: rgba(0, 0, 0, 0.45);}
}
</style>

相关文章:

用vue2+elementUI封装手机端选择器picker组件,支持单选、多选、远程搜索多选

单选注意点&#xff1a; touchmove.prevent: 在 touchmove 事件上添加 .prevent 修饰符&#xff0c;以阻止默认的滚动行为。 handleTouchStart: 记录触摸开始的 Y 坐标和当前的 translateY 值。 handleTouchMove: 计算触摸移动的距离&#xff0c;并更新 translateY 值。 han…...

『古籍自有答案』古风H5案例赏析

「古籍自有答案」&#xff0c;一部由新京报与字节跳动公益联合打造的古风H5&#xff0c;以诗意盎然的开篇引领用户穿梭于千年文脉。 part1. 创意定位 "人生有惑问先贤&#xff0c;先贤答案存古籍"&#xff0c;在这里&#xff0c;每一个灵魂的探问&#xff0c;都能在…...

Laravel模型事件完全指南:触发应用程序的动态行为

标题&#xff1a;Laravel模型事件完全指南&#xff1a;触发应用程序的动态行为 在Laravel框架中&#xff0c;模型事件提供了一种优雅的方式来处理Eloquent模型生命周期中的各种关键时刻。通过监听和响应这些事件&#xff0c;开发者可以自动化许多常见的任务&#xff0c;如日志…...

hot100 |八、二叉树

1-leetcode94. 二叉树的中序遍历 注意&#xff1a;√ 递归方法已经很熟练了&#xff0c;两种不同的递归方式迭代法需要注意&#xff0c;zrm就遇到了要求迭代实现&#xff0c;前序遍历和后续遍历其实不难&#xff0c;中序遍历用的少&#xff0c;注意看一看 // 1.递归方法1Lis…...

Matlab协方差矩阵分解法生成随机场

Matlab协方差矩阵分解法生成随机场 相关系数矩阵 % function outcohesion(x,y,mu,theta) % end % xyload(F:\Research-OUC\基于机器许学习模型的海底斜坡可靠度研究\基于comsol的斜坡稳定性分析\comsol网格操作\grid_operate-matlab.mphtxt); % xxy(:,1); % yxy(:,2); Xlinspac…...

android 在清单文件中配置receiver,系统是何时会注册此广播接收者的?

在 Android 中&#xff0c;通过清单文件&#xff08;AndroidManifest.xml&#xff09;配置的广播接收器&#xff08;BroadcastReceiver&#xff09;&#xff0c;系统会在特定的时机自动注册这些广播接收器。以下是详细的说明&#xff1a; 静态注册的广播接收器 静态注册的广播…...

嵌入式硬件电路常用设计软件

目录 1. Cadence Allegro 2. PADS 3. Altium Designer 4. Multisim 5. Protues 1. Cadence Allegro 功能&#xff1a; Cadence Allegro是Cadence公司推出的先进PCB&#xff08;Printed Circuit Board&#xff0c;印刷电路板&#xff09;设计布线工具&#xff0c;也是目前…...

c#的List<T>的SelectMany 和Select

在C#中&#xff0c;List<T>&#xff08;以及任何实现了IEnumerable<T>的集合&#xff09;的Select和SelectMany扩展方法都是LINQ&#xff08;Language Integrated Query&#xff09;的一部分&#xff0c;用于对集合中的元素进行查询和转换。 尽管它们的作用有些相…...

69.WEB渗透测试-信息收集- WAF、框架组件识别(9)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;68.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;8&#xff09; 有无waf存在&am…...

ASCII码对照表(Matplotlib颜色对照表)

文章目录 1、简介1.1 颜色代码 2、Matplotlib库简介2.1 简介2.2 安装2.3 后端2.4 入门例子 3、Matplotlib库颜色3.1 概述3.2 颜色图的分类3.3 颜色格式表示3.4 内置颜色映射3.5 xkcd 颜色映射3.6 颜色命名表 4、Colorcet库5、颜色对照表结语 1、简介 1.1 颜色代码 颜色代码是…...

Mysql-常用函数及其用法总结

1、字符串函数 测试用例如下&#xff1a; 1.1 CONCAT() 将多个字符串连接成一个字符串。 SELECT CONCAT(first_name, , last_name) AS full_name FROM users; -- 期望结果&#xff1a;John Doe, Jane Smith, Michael Johnson 1.2 SUBSTRING() 提取子字符串 SELECT SUBSTR…...

【c++刷题笔记-数组】day29:452. 用最少数量的箭引爆气球、 435. 无重叠区间 、 763.划分字母区间

452. 用最少数量的箭引爆气球 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;先按照左边界排序&#xff0c;当前的左边界大于前一个的右边界的时候&#xff0c;表示没有覆盖所以需要一根箭&#xff0c;反之则要更新为最小的右边界 重点&#xff1a;是区间覆盖问题…...

【数据结构】链表带环问题分析及顺序表链表对比分析

【C语言】链表带环问题分析及顺序表链表对比分析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C语言学习之路 文章目录 【C语言】链表带环问题分析及顺序表链表对比分析前言一.顺序表和链表对比1.1顺序表和链表的区别1.2缓存利用率&#…...

快速解决找不到krpt.dll,无法继续执行代码问题

对于那些遇到计算机开机出现由于无法找到krpt.dll&#xff0c;进而无法继续执行代码问题的用户。 krpt.dll是计算机系统中与DirectX紧密相关的重要文件&#xff0c;如果它出现问题&#xff0c;可能会对一些特定的软件或游戏的运行产生影响。实际上&#xff0c;我们有多种解决该…...

C# List、LinkedList、Dictionary性能对比

数据结构性能对比 List、LinkedList、Dictionary 1. ArrayList &#xff08;List&#xff1a;前传&#xff09; ArrayList 是一个特殊数组&#xff0c; 通过添加和删除元素就可以动态改变数组的长度。 ArrayList集合相对于数组的优点&#xff1a; 支持…...

【Spring Cloud】微服务的简单搭建

文章目录 &#x1f343;前言&#x1f384;开发环境安装&#x1f333;服务拆分的原则&#x1f6a9;单一职责原则&#x1f6a9;服务自治&#x1f6a9;单向依赖 &#x1f340;搭建案例介绍&#x1f334;数据准备&#x1f38b;工程搭建&#x1f6a9;构建父子工程&#x1f388;创建父…...

全球首款商用,AI为视频自动配音配乐产品上线

近日&#xff0c;海外推出了一款名为Resona V2A的产品&#xff0c;这是全球首款商用视频转音频 (V2A) 技术产品。这项突破性技术利用AI&#xff0c;仅凭视频数据即可自动生成高质量、与上下文相关的音频&#xff0c;包括声音设计、音效、拟音和环境音&#xff0c;为电影制作人、…...

Git管理源代码、git简介,工作区、暂存区和仓库区,git远程仓库github,创建远程仓库、配置SSH,克隆项目

学习目标 能够说出git的作用和管理源代码的特点能够如何创建git仓库并添加忽略文件能够使用add、commit、push、pull等命令实现源代码管理能够使用github远程仓库托管源代码能够说出代码冲突原因和解决办法能够说出 git 标签的作用能够使用使用git实现分支创建&#xff0c;合并…...

【机器学习】机器学习与时间序列分析的融合应用与性能优化新探索

文章目录 引言第一章&#xff1a;机器学习在时间序列分析中的应用1.1 数据预处理1.1.1 数据清洗1.1.2 数据归一化1.1.3 数据增强 1.2 模型选择1.2.1 自回归模型1.2.2 移动平均模型1.2.3 长短期记忆网络1.2.4 卷积神经网络 1.3 模型训练1.3.1 梯度下降1.3.2 随机梯度下降1.3.3 A…...

执行力不足是因为选择模糊

选择模糊&#xff1a;执行力不足的根源 选择模糊是指在面对多个选项时&#xff0c;缺乏明确的目标和方向。这种模糊感会导致犹豫不决&#xff0c;进而影响我们的执行力。 选择模糊的表现&#xff1a; 目标不明确&#xff0c;不知道应该做什么。优先级混乱&#xff0c;不清楚…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

一些实用的chrome扩展0x01

简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序&#xff0c;无论是测试应用程序、搜寻漏洞还是收集情报&#xff0c;它们都能提升工作流程。 FoxyProxy 代理管理工具&#xff0c;此扩展简化了使用代理&#xff08;如 Burp…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...