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 接口测试开启免费公测,本着以和大家交流如何实现高效的接口测试为出发点,本文包含了我在接口测试领域的一些方法和心得,希望大家一起讨论和分享,内容包括但不仅限于:服务端接口测试介绍接…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
