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

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的可选项
placeholderselect的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组件库组件介绍 何时使用 弹出一个下拉菜单给用户选择操作&#xff0c;用于代替原生的选择器&#xff0c;或者需要一个更优雅的多选器时。 当选项少时&#xff08;少于 5 项&#xff09;&#xff0c;建议直接将…...

华为OD机试 - 员工出勤(Python) | 机试题+算法思路+考点+代码解析 【2023】

员工出勤 题目 公司用一个字符串来标识员工的出勤信息 absent: 缺勤 late: 迟到 leaveearly:早退 present: 正常上班 现需根据员工出勤信息,判断本次是否能获得出勤奖, 能获得出勤奖的条件如下: 缺勤不超过1次没有连续的迟到/早退任意连续7次考勤,缺勤/迟到/早退,不超过3次…...

力扣:27. 移除元素

给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面…...

华为OD机试 - 剩余可用字符集(Python) | 机试题+算法思路+考点+代码解析 【2023】

剩余可用字符集 题目 给定两个字符集合 一个是全量字符集 一个是已占用字符集 已占用字符集中的字符不能再使用 要求输出剩余可用字符集 输入 输入一个字符串 一定包含@ @前为全量字符集 @后的为已占用字符集已占用字符集中的字符 一定是全量字符集中的字符 字符集中的字符跟…...

金三银四丨黑蛋老师带你剖析-安全开发岗

作者丨黑蛋在之前呢&#xff0c;我们聊了二进制这块的病毒岗位&#xff0c;漏洞岗位&#xff0c;逆向岗位以及CTF这块的岗位。今天我们就来聊一聊安全开发类的工作岗位。首先网络安全方向中安全开发岗位都有哪些&#xff0c;安全开发主要指安全研发工程师或安全开发工程师&…...

isNaN、Number.isNaN、isFinite、Number.isFinite

isNaN和Number.isNaN这两者都是为了判断参数是否为NaN类型。isNaN的实现原理是&#xff1a;通过Number()方法&#xff0c;尝试将参数转换成Number类型&#xff0c;如果成功返回false&#xff0c;如果失败返回true。isNaN只是判断传入的参数是否能转换成数字&#xff0c;并不是严…...

MyBatis分页插件

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

Vue组件间通信的四种方式(函数回调,自定义事件,事件总线,消息订阅与发布)

目录 概述 props配置项-回调函数实现 自定义事件实现 事件总线实现 消息订阅与发布实现&#xff08;pubsub-js库&#xff09; 概述 在组件化编程中&#xff0c;组件间的通信是重要的&#xff0c;我们可以有四种方式实现组件间的通信。 分别是&#xff1a;函数回调&…...

华为OD机试真题Python实现【求字符串中所有整数的最小和】真题+解题思路+代码(20222023)

求字符串中所有整数的最小和 题目 说明 字符串 s,只包含 a-z A-Z + - ;合法的整数包括 1) 正整数 一个或者多个0-9组成,如 0 2 3 002 102 2)负整数 负号 - 开头,数字部分由一个或者多个0-9组成,如 -0 -012 -23 -00023🔥🔥🔥🔥🔥👉👉👉👉👉👉 华…...

行为型设计模式之中介者模式

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

JDK8增加的特性

Java知识点总结&#xff1a;想看的可以从这里进入 目录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月中旬了&#xff0c;最近看到上海很多院校都已经公布了提前面批次相应时间了&#xff0c;等浙大复试工作结束&#xff0c;马上提前面批次时间也会出来。本人2023浙大提面也拿到了优秀&#xff0c;结合本人经验&#xff0c;今天给大家分享下申请材料该如何撰写&…...

华为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的&#xff0c;但是g也能够用来编译c语言 预处理&#xff08;进行宏替换&#xff09; 预处理功能主要包括宏…...

追梦之旅【数据结构篇】——详解C语言动态实现带头结点的双向循环链表结构

详解C语言动态实现带头结点的双向循环链表结构~&#x1f60e;前言&#x1f64c;预备小知识&#x1f49e;链表的概念及结构&#x1f64c;预备小知识&#x1f49e;链表的概念及结构&#x1f64c;带头结点的双向循环链表结构&#x1f64c;整体实现内容分析&#x1f49e;1.头文件编…...

华为OD机试真题Python实现【水仙花数 2】真题+解题思路+代码(20222023)

水仙花数 2 题目 给定非空字符串 s,将该字符串分割成一些子串 使每个子串的 ASCII 码值的和均为水仙花数 若分割不成功则返回 0若分割成功且分割结果不唯一 则返回-1若分割成功且分割结果唯一 则返回分割后子串的数目 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机…...

【原创】java+swing+txt学生学籍管理系统设计与实现

今天我们来介绍如何使用javaswingtxt来开发一个学籍管理系统。对的&#xff0c;你没看错&#xff0c;我们今天不用mysql&#xff0c;我们使用txt这个文本来进行数据存储&#xff0c;主要考察对文件读写的操作。 功能分析&#xff1a; 我们系统不要求做的很复杂&#xff0c;只…...

GCN项目实战1-SimGNN

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

经过深思熟虑后的接口测试自动化的总结与思考

序近期看到阿里云性能测试 PTS 接口测试开启免费公测&#xff0c;本着以和大家交流如何实现高效的接口测试为出发点&#xff0c;本文包含了我在接口测试领域的一些方法和心得&#xff0c;希望大家一起讨论和分享&#xff0c;内容包括但不仅限于&#xff1a;服务端接口测试介绍接…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究

摘要&#xff1a;在消费市场竞争日益激烈的当下&#xff0c;传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序&#xff0c;探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式&#xff0c;分析沉浸式体验的优势与价值…...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...

Qt的学习(二)

1. 创建Hello Word 两种方式&#xff0c;实现helloworld&#xff1a; 1.通过图形化的方式&#xff0c;在界面上创建出一个控件&#xff0c;显示helloworld 2.通过纯代码的方式&#xff0c;通过编写代码&#xff0c;在界面上创建控件&#xff0c; 显示hello world&#xff1b; …...

k8s从入门到放弃之Pod的容器探针检测

k8s从入门到放弃之Pod的容器探针检测 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;容器探测是指kubelet对容器执行定期诊断的过程&#xff0c;以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...