vue3组件篇 Select
文章目录
- 组件介绍
- 何时使用
- 基本功能
- 组件代码
- 参数说明
- 事件
- 关于dxui组件库
组件介绍
何时使用
弹出一个下拉菜单给用户选择操作,用于代替原生的选择器,或者需要一个更优雅的多选器时。
当选项少时(少于 5 项),建议直接将选项平铺,使用 Radio 是更好的选择。
基本功能
满足用户在多个选项中选择一个或者多个选项,添加了搜索模式,和tag模式,也可以预设被选中的选项,用户也可以直接按删除键删除掉最后一个选中的选项。
组件代码
<template><divclass="dx-select-warpper":class="selectDisabled ? 'dx-select-warpper-disabled' : ''"@keydown.delete="deleteSlectedOptions"><div @click="toggleSelectStatus"><div class="dx-select-input"><!-- 当有选中的内容时 --><div class="dx-select-has-content" v-show="selectInputDataArray.length && !showSearchInput"><div class="dx-select-tag-warpper" v-if="isTag"><Tag@closeClick="closeTagClick(item)"closablev-for="item in selectInputDataArray":key="item.value">{{ item.name }}</Tag></div><span v-else>{{ selectInputValue }}</span><!-- <input type="text" class="dx-select-input-focus" ref="inputFocus" /> --></div><inputtype="text"class="dx-select-input-focus":class="showSearchInput ? 'dx-select-input-search' : ''"ref="inputFocus"v-model="selectSearchInputValue"@input="SearchInputValueChange"placeholder="请输入筛选条件"/><!-- 当没有选中的内容时 --><span v-show="!selectInputDataArray.length" class="dx-select-placeholder">{{placeholder}}</span></div><span class="dx-select-icon" :class="showSearchInput ? 'dx-select-search-icon' : ''"></span></div><div class="dx-select-options-warpper" v-show="selectStatus === 'focus'"><divclass="dx-select-options-item"v-for="item in selectOptions.list":class="selectInputDataArray.some((selectedItem) => {return selectedItem.value === item.value})? 'dx-options-item-active': ''":key="item.name + item.value"@click="toggleOptions(item, $event)">{{ item.name }}</div></div></div>
</template><script lang="ts">
import { ref, SetupContext, reactive, watch, onMounted, toRaw } from 'vue'
import { Data, OptionItem } from './types/index'
// import { useRouter } from 'vue-router'
import Tag from '@/components/tag/Tag.vue'export default {components: {Tag},props: {// 配置options的可选项options: {required: false,type: Array,default: function () {return []}},placeholder: {required: false,default: '请选择'},// 单选或者多选 multiple | singletype: {required: false,default: 'single',type: String},// 是否支持搜索search: {required: false,default: false,type: Boolean},// 是否禁用disabled: {required: false,default: false,type: Boolean},// 是否启用标签模式mode: {required: false,default: 'normal',type: String}},setup(props: Data, context: SetupContext) {// const currentInstance: ComponentInternalInstance | null = getCurrentInstance()// input字符串的值const selectInputValue = ref('')const inputFocus = ref<any>(null)// 当前的状态,fcous或者blurconst selectStatus = ref('')// 可选的配置项optionsconst selectOptions = reactive<{ list: OptionItem[] }>({list: props?.options})const showSearchInputKey = ref(false)// 是否展示searchInput框const showSearchInput = ref<boolean>(props.search && selectStatus.value === 'focus' && showSearchInputKey.value)// 是否禁用const selectDisabled = ref(props.disabled)// 是否是tag模式const isTag = ref(props.mode === 'tag')// 用户输入的select search字段const selectSearchInputValue = ref('')// 被选中的参数的保存值const selectInputDataArray = reactive<OptionItem[]>(props?.options?.filter((item: OptionItem) => {return item.selected === true}) as OptionItem[])// 监测用户输入的search变化const SearchInputValueChange = (e: any) => {if (!showSearchInput.value) {selectSearchInputValue.value = ''} else {const result = props.options.filter((item: any) => {return item.name.includes(e.target.value)})console.log(result)// selectOptions = resultselectOptions.list = result}}// const changeSelectStatus = () => {// selectStatus.value = 'focus'// }// 改变select的聚焦状态const toggleSelectStatus = (e: Event) => {if (props.disabled) {return}showSearchInputKey.value = truee.stopPropagation()if (selectStatus.value === 'focus') {selectStatus.value = 'blur'} else {selectStatus.value = 'focus'}}// 改变选项的选中状态const toggleOptions = (item: OptionItem, e: Event) => {if (props.disabled) {return}showSearchInputKey.value = falsee.stopPropagation()inputFocus.value?.focus()if (props.type === 'single') {selectStatus.value = 'blur'if (selectInputDataArray[0] && selectInputDataArray[0].value === item.value) {selectInputDataArray.shift()} else {selectInputDataArray[0] = item}} else {const selectedIndex = selectInputDataArray.findIndex((selectItem) => {return selectItem.value === item.value})if (selectedIndex > -1) {selectInputDataArray.splice(selectedIndex, 1)} else {selectInputDataArray.push(item)}}context.emit('changeSelect', toRaw(selectInputDataArray))}// 删除被选中的optionconst deleteSlectedOptions = () => {inputFocus.value?.focus()if (showSearchInput.value) {return}if (selectStatus.value === 'focus' && selectInputDataArray.length > 0) {selectInputDataArray.pop()context.emit('changeSelect', toRaw(selectInputDataArray))}}// 点击tag的删除,关闭选中项const closeTagClick = (item: OptionItem) => {inputFocus.value?.focus()const findIndex = selectInputDataArray.findIndex((selectItem) => {return selectItem.value === item.value})selectInputDataArray.splice(findIndex, 1)context.emit('changeSelect', toRaw(selectInputDataArray))}watch(showSearchInputKey,(val) => {showSearchInput.value = props.search && selectStatus.value === 'focus' && val},{ immediate: true, deep: true })watch(selectInputDataArray,(a) => {selectInputValue.value = a.map((item) => {return item?.name}).join(',')},{ immediate: true, deep: true })onMounted(() => {watch(selectStatus, (val) => {if (val === 'focus') {inputFocus.value?.focus()} else {inputFocus.value?.blur()}showSearchInput.value = props.search && val === 'focus' && showSearchInputKey})})document.body.addEventListener('click', () => {selectStatus.value = 'blur'})return {selectInputValue,selectSearchInputValue,inputFocus,isTag,showSearchInput,// changeSelectStatus,toggleSelectStatus,selectOptions,toggleOptions,selectStatus,selectInputDataArray,selectDisabled,deleteSlectedOptions,closeTagClick,SearchInputValueChange}}
}
</script><style lang="scss" scoped>
@import '@/scss/layout.scss';
.dx-select-warpper {// display: inline-block;border: $border;padding: 0 12px;height: 32px;border-radius: 4px;cursor: pointer;position: relative;// min-width: 120px;&:hover {border: 1px solid $blue-middle-color;}.dx-select-placeholder {display: inline-block;height: 100%;vertical-align: top;cursor: pointer;line-height: 30px;font-size: 14px;padding-right: 6px;width: calc(100% - 12px);}.dx-select-input {display: inline-block;height: 100%;vertical-align: top;cursor: pointer;line-height: 30px;font-size: 14px;margin-right: 6px;width: calc(100% - 24px);}.dx-select-has-content {display: inline-block;}.dx-select-tag-warpper {display: inline-block;line-height: initial;}.dx-select-input-focus {outline: none;border: none;width: 1px;font-size: 14px;line-height: 30px;overflow: hidden;}.dx-select-input-search {width: 100% !important;}.dx-select-placeholder {color: $grey-color;}.dx-select-icon {display: inline-block;height: 100%;line-height: 30px;font-size: 22px;color: $grey-color;&::before {content: '\2228';}}.dx-select-search-icon {display: inline-block;height: 100%;line-height: 30px;font-size: 12px;&::before {content: '\1F50D' !important;}}// 改变滚动条的盒子::-webkit-scrollbar {width: 6px;background-color: #fff;}// 改变滚动条轨道::-webkit-scrollbar-track {// border-radius: 10px;display: none;}// 改变滚动条的内容::-webkit-scrollbar-thumb {border-radius: 6px;background-color: $grey-color;}/*定义最上方和最下方的按钮*/::-webkit-scrollbar-button {display: none;}.dx-select-options-warpper {width: 100%;position: absolute;left: 0;top: calc(100% + 4px);padding: 4px 0;background: $white-color;box-shadow: 2px 2px 20px rgb(0 0 0 / 29%);border-radius: 4px;z-index: 1000;max-height: 120px;overflow-y: auto;.dx-select-options-item {line-height: 28px;padding: 0 12px;&:hover {background: $background-color;}overflow: hidden;}.dx-select-options-item.dx-options-item-active {background: $blue-light-color;}}
}.dx-select-warpper-disabled {cursor: not-allowed !important;background: $border-color !important;&:hover {border: $border;}.dx-select-input-focus {background: transparent !important;cursor: not-allowed !important;}.dx-select-input,.dx-select-placeholder {background: transparent !important;cursor: not-allowed !important;}
}::v-deep .dx-tag-warpper {margin: 0 8px 0 0;
}
</style>
参数说明
参数名称 | 说明 |
---|---|
options | 配置options的可选项 |
placeholder | select的placeholder |
type | 单选或者多选 multiple or single |
search | 是否支持搜索 boolean |
disabled | 是否禁用整个select |
mode | 是否启用标签模式 normal or tag |
事件
事件名称 | 说明 |
---|---|
changeSelect | 监听select组件被选中改变的回调,会返回当前被选中的options |
关于dxui组件库
如果你有任何疑问,欢迎发送你的问题至我的邮箱757363985@qq.com.
你也可以前往dxui的线上网站,体验一下实际使用的效果. http://www.dxyx-together.cn/#/home/select
后面等时机成熟的时候,我会将源码github库与大家一同分享.
相关文章:
vue3组件篇 Select
文章目录组件介绍何时使用基本功能组件代码参数说明事件关于dxui组件库组件介绍 何时使用 弹出一个下拉菜单给用户选择操作,用于代替原生的选择器,或者需要一个更优雅的多选器时。 当选项少时(少于 5 项),建议直接将…...
华为OD机试 - 员工出勤(Python) | 机试题+算法思路+考点+代码解析 【2023】
员工出勤 题目 公司用一个字符串来标识员工的出勤信息 absent: 缺勤 late: 迟到 leaveearly:早退 present: 正常上班 现需根据员工出勤信息,判断本次是否能获得出勤奖, 能获得出勤奖的条件如下: 缺勤不超过1次没有连续的迟到/早退任意连续7次考勤,缺勤/迟到/早退,不超过3次…...
力扣:27. 移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面…...
华为OD机试 - 剩余可用字符集(Python) | 机试题+算法思路+考点+代码解析 【2023】
剩余可用字符集 题目 给定两个字符集合 一个是全量字符集 一个是已占用字符集 已占用字符集中的字符不能再使用 要求输出剩余可用字符集 输入 输入一个字符串 一定包含@ @前为全量字符集 @后的为已占用字符集已占用字符集中的字符 一定是全量字符集中的字符 字符集中的字符跟…...

金三银四丨黑蛋老师带你剖析-安全开发岗
作者丨黑蛋在之前呢,我们聊了二进制这块的病毒岗位,漏洞岗位,逆向岗位以及CTF这块的岗位。今天我们就来聊一聊安全开发类的工作岗位。首先网络安全方向中安全开发岗位都有哪些,安全开发主要指安全研发工程师或安全开发工程师&…...
isNaN、Number.isNaN、isFinite、Number.isFinite
isNaN和Number.isNaN这两者都是为了判断参数是否为NaN类型。isNaN的实现原理是:通过Number()方法,尝试将参数转换成Number类型,如果成功返回false,如果失败返回true。isNaN只是判断传入的参数是否能转换成数字,并不是严…...

MyBatis分页插件
目录 分页插件 Mybatis插件典型适用场景 实现思考 第一个问题 第二个问题 自定义分页插件 分页插件使用 添加pom依赖 插件注册 调用 代理和拦截是怎么实现的 PageHelper 原理 分页插件 MyBatis 通过提供插件机制,让我们可以根据自己的需要去增强MyBati…...

Vue组件间通信的四种方式(函数回调,自定义事件,事件总线,消息订阅与发布)
目录 概述 props配置项-回调函数实现 自定义事件实现 事件总线实现 消息订阅与发布实现(pubsub-js库) 概述 在组件化编程中,组件间的通信是重要的,我们可以有四种方式实现组件间的通信。 分别是:函数回调&…...
华为OD机试真题Python实现【求字符串中所有整数的最小和】真题+解题思路+代码(20222023)
求字符串中所有整数的最小和 题目 说明 字符串 s,只包含 a-z A-Z + - ;合法的整数包括 1) 正整数 一个或者多个0-9组成,如 0 2 3 002 102 2)负整数 负号 - 开头,数字部分由一个或者多个0-9组成,如 -0 -012 -23 -00023🔥🔥🔥🔥🔥👉👉👉👉👉👉 华…...

行为型设计模式之中介者模式
中介者模式 中介者模式又称为调解者模式或调停者模式,属于行为型模式。它用一个中介对象封装系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 中介者模式包装了一系列对…...

JDK8增加的特性
Java知识点总结:想看的可以从这里进入 目录13、JDK8增加的特性13.1、Lambda表达式13.2、方法的引用13.3、时间处理类13.4、接口增加方法13.5、注解新增13.6、Optional类13.7、Stream13、JDK8增加的特性 13.1、Lambda表达式 Lambda表达式和方法的引用 13.2、方法的…...
华为OD机试 - 求数组中最大n个数和最小n个数的和(Python) | 机试题+算法思路+考点+代码解析 【2023】
求数组中最大n个数和最小n个数的和 给定一个数组,编写一个函数, 计算他的最大N个数和最小N个数的和, 需要对数组进行去重。 输入 第一行输入M,M表示数组大小 第二行输入M个数,表示数组内容 第三行输入N表示需要计算的最大最小N的个数 输出 输出最大N个数和最小N个数的…...

如何写出更加契合浙大MBA项目提面申请资料?
现在已经是2月中旬了,最近看到上海很多院校都已经公布了提前面批次相应时间了,等浙大复试工作结束,马上提前面批次时间也会出来。本人2023浙大提面也拿到了优秀,结合本人经验,今天给大家分享下申请材料该如何撰写&…...
华为OD机试真题Java实现【比赛评分】真题+解题思路+代码(20222023)
比赛评分 题目 一个有N个选手参加比赛,选手编号为1~N(3<=N<=100),有M(3<=M<=10)个评委对选手进行打分。打分规则为每个评委对选手打分,最高分10分,最低分1分。 请计算得分最多的3位选手的编号。如果得分相同,则得分高分值最多的选手排名靠前(10分数量相…...

【linux】——gcc/g++,make/makefile的简单使用
目录 1.gcc的基本使用 2.Linux下的静态库和动态库的理解 3.Linux项目自动化构建工具——make/makefile 1.gcc的基本使用 gcc是专门用来编译c语言的 g是专门用来编译c的,但是g也能够用来编译c语言 预处理(进行宏替换) 预处理功能主要包括宏…...

追梦之旅【数据结构篇】——详解C语言动态实现带头结点的双向循环链表结构
详解C语言动态实现带头结点的双向循环链表结构~😎前言🙌预备小知识💞链表的概念及结构🙌预备小知识💞链表的概念及结构🙌带头结点的双向循环链表结构🙌整体实现内容分析💞1.头文件编…...
华为OD机试真题Python实现【水仙花数 2】真题+解题思路+代码(20222023)
水仙花数 2 题目 给定非空字符串 s,将该字符串分割成一些子串 使每个子串的 ASCII 码值的和均为水仙花数 若分割不成功则返回 0若分割成功且分割结果不唯一 则返回-1若分割成功且分割结果唯一 则返回分割后子串的数目 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机…...

【原创】java+swing+txt学生学籍管理系统设计与实现
今天我们来介绍如何使用javaswingtxt来开发一个学籍管理系统。对的,你没看错,我们今天不用mysql,我们使用txt这个文本来进行数据存储,主要考察对文件读写的操作。 功能分析: 我们系统不要求做的很复杂,只…...

GCN项目实战1-SimGNN
文章目录SimGNN:快速图相似度计算的神经网络方法1. 数据2. 模型2.1 python文件功能介绍2.2 重要函数和类的实现SimGNN:快速图相似度计算的神经网络方法 原论文名称:SimGNN: A Neural Network Approach to Fast Graph Similarity Computation…...

经过深思熟虑后的接口测试自动化的总结与思考
序近期看到阿里云性能测试 PTS 接口测试开启免费公测,本着以和大家交流如何实现高效的接口测试为出发点,本文包含了我在接口测试领域的一些方法和心得,希望大家一起讨论和分享,内容包括但不仅限于:服务端接口测试介绍接…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

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

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...