仿el-select组件

时间: 2023-07-13 13:30:47 浏览: 26
好的,下面是一个仿 Element UI 中 el-select 组件的实现方案。 首先,我们可以创建一个 Select 组件,包含以下几个部分: 1. 输入框:用于显示当前选中的选项或输入搜索关键词。 2. 下拉菜单:用于展示所有可选项。 3. 多选/单选按钮:用于切换多选和单选模式。 4. 清除按钮:用于清除已选中的选项。 下面是 Select 组件的基本代码: ```html <template> <div class="select" :class="{ 'is-multiple': isMultiple, 'is-focus': isFocus }"> <div class="input-container" @click="toggleMenu"> <div class="input" :class="{ 'is-placeholder': !selectedOptions.length }"> <span class="selected-label" v-if="selectedOptions.length"> <span v-for="(option, index) in selectedOptions" :key="index" class="el-tag el-tag--info">{{ option.label }}</span> </span> <input type="text" class="input-field" v-model="searchKeyword" :placeholder="placeholder" :readonly="!filterable" @focus="isFocus = true" @blur="isFocus = false"> </div> <i class="el-select__caret el-input__icon el-icon-arrow-up" :class="{ 'el-icon-arrow-down': !isMenuOpen }"></i> </div> <transition name="el-zoom-in-top"> <ul class="options" v-show="isMenuOpen"> <li v-for="(option, index) in filteredOptions" :key="index" @click="selectOption(option)"> <span class="option-label">{{ option.label }}</span> <i class="el-icon-check" v-if="isSelected(option)"></i> </li> <li v-if="!filteredOptions.length" class="no-data">{{ noDataText }}</li> </ul> </transition> <div class="el-select__tags" v-if="isMultiple"> <span v-for="(option, index) in selectedOptions" :key="index" class="el-tag el-tag--info"> {{ option.label }} <i class="el-tag__close el-icon-close" @click.stop="removeOption(option)"></i> </span> </div> <div class="el-select__actions" v-if="isMultiple && allowClear"> <span class="el-select__clear" @click="clearSelection"> <i class="el-select__clear-icon el-icon-circle-close"></i> </span> </div> </div> </template> <script> export default { name: 'Select', props: { options: { type: Array, required: true }, value: { type: [Object, Array], default: null }, placeholder: { type: String, default: '请选择' }, multiple: { type: Boolean, default: false }, filterable: { type: Boolean, default: false }, allowClear: { type: Boolean, default: false }, noDataText: { type: String, default: '无匹配数据' } }, data () { return { selectedOptions: [], searchKeyword: '', isMenuOpen: false, isFocus: false } }, computed: { isMultiple () { return this.multiple || Array.isArray(this.value) }, filteredOptions () { return this.options.filter(option => option.label.includes(this.searchKeyword)) }, selectedValues () { return this.selectedOptions.map(option => option.value) } }, watch: { value (newValue) { if (!this.isMultiple) { const selectedOption = this.options.find(option => option.value === newValue) this.selectedOptions = selectedOption ? [selectedOption] : [] } else { this.selectedOptions = this.options.filter(option => newValue.indexOf(option.value) !== -1) } }, selectedOptions (newSelectedOptions) { if (!this.isMultiple) { const newValue = newSelectedOptions.length ? newSelectedOptions[0].value : null this.$emit('input', newValue) this.$emit('change', newValue) } else { const newValue = newSelectedOptions.map(option => option.value) this.$emit('input', newValue) this.$emit('change', newValue) } } }, methods: { toggleMenu () { if (!this.disabled) { this.isMenuOpen = !this.isMenuOpen } }, selectOption (option) { if (!this.isMultiple) { this.selectedOptions = [option] this.isMenuOpen = false } else { const index = this.selectedOptions.indexOf(option) if (index !== -1) { this.selectedOptions.splice(index, 1) } else { this.selectedOptions.push(option) } } }, removeOption (option) { const index = this.selectedOptions.indexOf(option) if (index !== -1) { this.selectedOptions.splice(index, 1) } }, clearSelection () { this.selectedOptions = [] }, isSelected (option) { return this.selectedValues.indexOf(option.value) !== -1 } } } </script> <style scoped> .select { position: relative; display: inline-block; width: 200px; font-size: 14px; color: #606266; background-color: #fff; border: 1px solid #dcdfe6; border-radius: 4px; cursor: pointer; } .select.is-multiple .input { display: flex; flex-wrap: wrap; align-items: center; padding: 0 10px; } .select.is-multiple .el-select__tags { display: flex; flex-wrap: wrap; padding: 5px 0; } .select.is-multiple .el-tag { margin-right: 10px; margin-bottom: 5px; font-size: 12px; line-height: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .select.is-multiple .el-tag__close { margin-left: 5px; cursor: pointer; } .select.is-multiple .el-select__actions { display: flex; align-items: center; height: 34px; padding-right: 10px; } .select.is-multiple .el-select__clear { margin-right: 5px; font-size: 12px; color: #c0c4cc; cursor: pointer; } .select.is-multiple .el-select__clear:hover { color: #909399; } .select.is-focus { border-color: #409EFF; box-shadow: 0 2px 6px rgba(0,0,0,.2); } .select.is-focus .el-select__caret { color: #409EFF; } .select .input-container { display: flex; align-items: center; height: 34px; padding: 0 10px; } .select .input { display: flex; align-items: center; height: 100%; flex: 1; overflow: hidden; } .select .input.is-placeholder .input-field { color: #c0c4cc; } .select .input .selected-label { display: flex; flex-wrap: wrap; align-items: center; margin-right: 5px; } .select .input .selected-label .el-tag { margin-right: 5px; margin-bottom: 5px; font-size: 12px; line-height: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .select .input .input-field { flex: 1; border: none; outline: none; margin-right: 5px; font-size: 14px; line-height: 1; background-color: transparent; } .select .el-select__caret { color: #dcdfe6; font-size: 12px; transition: all .3s; } .select .el-select__caret.el-icon-arrow-up { transform: rotate(-180deg); } .select .options { position: absolute; top: 100%; left: 0; z-index: 99; width: 100%; max-height: 250px; margin: 0; padding: 6px 0; background-color: #fff; border: 1px solid #dcdfe6; border-top: none; border-radius: 0 0 4px 4px; box-shadow: 0 2px 6px rgba(0,0,0,.2); overflow-y: auto; } .select .options::-webkit-scrollbar { width: 6px; } .select .options::-webkit-scrollbar-thumb { background-color: rgba(0,0,0,.2); border-radius: 3px; } .select .options li { padding: 6px 12px; font-size: 14px; color: #606266; white-space: nowrap; cursor: pointer; } .select .options li:hover { background-color: #f5f5f5; } .select .options li .option-label { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; } .select .options li .el-icon-check { margin-left: 5px; color: #409EFF; } .select .options li .el-icon-check.disabled { color: #c0c4cc; } .select .options li.no-data { text-align: center; color: #c0c4cc; } </style> ``` 上面的代码中,props 中的 options 数组包含了所有可选项,每个选项由 label 和 value 两个属性组成。搜索关键词通过 v-model 绑定到 input 输入框中,并且通过 @focus 和 @blur 事件实现了输入框的聚焦和失焦效果。下拉菜单的显示和隐藏通过 v-show 和 isMenuOpen 控制。选中的选项通过 selectedOptions 数组保存,selectOption 方法用于切换选项的选中状态。 如果您需要支持多选功能,可以将 multiple 属性设置为 true。此时,Select 组件会显示一个 el-select__tags 区域,用于展示已选中的选项。同时,也会显示一个 el-select__actions 区域,用于实现清除已选中的选项功能。如果您需要支持清除已选中的选项功能,可以将 allowClear 属性设置为 true。 希望这个仿 Element UI 中 el-select 组件的实现方案可以帮助到您。

相关推荐

要关闭el-select组件的下拉窗,可以通过设置el-select的visible属性为false来实现。在Vue中,可以通过在data中定义一个变量来控制visible属性的值,然后在需要关闭下拉窗的地方修改这个变量的值为false。例如,在上述代码中,可以在data中定义一个名为showDropdown的变量,并将其初始值设置为true。然后,在需要关闭下拉窗的地方,可以通过修改showDropdown的值为false来关闭下拉窗。具体的代码如下所示: javascript export default { data() { return { showDropdown: true, // 控制下拉窗的显示与隐藏 formInline: { // 表单数据 // ... } } }, methods: { // 其他方法 // ... closeDropdown() { this.showDropdown = false; // 关闭下拉窗 } } } 然后,在el-select组件中,可以通过使用v-if指令来根据showDropdown的值来控制下拉窗的显示与隐藏。具体的代码如下所示: html <el-select v-model="formInline.stationName" @change="onTitleChange" v-if="showDropdown"> </el-select> 通过调用closeDropdown方法,可以关闭el-select组件的下拉窗。 #### 引用[.reference_title] - *1* *2* *3* [VUE的el-select下拉框基本用法](https://blog.csdn.net/bbs11007/article/details/125839936)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
el-select和el-tree是ElementUI中的两个组件,可以结合在一起使用。它们提供了在前端实现下拉选择框和树形结构的功能。 要使用el-select和el-tree,您需要先安装el-select-tree的包,并且确保项目中已经安装了element-ui。可以使用npm命令进行安装。例如:npm install --save el-select-tree。 如果您的项目没有使用element-ui,还需要单独引入element-ui包。 在使用el-select和el-tree之前,您可以通过全局注册或局部注册的方式进行注册,具体可以参考官方文档中的示例。 el-select和el-tree组件都有一些属性和事件,可以根据需要进行配置和监听。更多详细的使用方法和API可以参考官方文档。123 #### 引用[.reference_title] - *1* *3* [element-ui 的 el-select 与 el-tree 的功能组合](https://blog.csdn.net/baidu_27769027/article/details/102906967)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [el-select-tree:ElementUI的el-select与el-tree结合](https://download.csdn.net/download/weixin_42135773/18435535)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

最新推荐

基于jsp的酒店管理系统源码数据库论文.doc

基于jsp的酒店管理系统源码数据库论文.doc

5G技术在医疗保健领域的发展和影响:全球疫情COVID-19问题

阵列14(2022)1001785G技术在医疗保健领域不断演变的作用和影响:全球疫情COVID-19问题MdMijanurRahmana,Mh,FatemaKhatunb,SadiaIslamSamia,AshikUzzamanaa孟加拉国,Mymensingh 2224,Trishal,Jatiya Kabi Kazi Nazrul Islam大学,计算机科学与工程系b孟加拉国Gopalganj 8100,Bangabandhu Sheikh Mujibur Rahman科技大学电气和电子工程系A R T I C L E I N F O保留字:2019冠状病毒病疫情电子健康和移动健康平台医疗物联网(IoMT)远程医疗和在线咨询无人驾驶自主系统(UAS)A B S T R A C T最新的5G技术正在引入物联网(IoT)时代。 该研究旨在关注5G技术和当前的医疗挑战,并强调可以在不同领域处理COVID-19问题的基于5G的解决方案。本文全面回顾了5G技术与其他数字技术(如人工智能和机器学习、物联网对象、大数据分析、云计算、机器人技术和其他数字平台)在新兴医疗保健应用中的集成。从文献中

def charlist(): li=[] for i in range('A','Z'+1): li.append(i) return li

这段代码有误,因为 `range()` 函数的第一个参数应该是整数类型而不是字符串类型,应该改为 `range(ord('A'), ord('Z')+1)`。同时,还需要将 `ord()` 函数得到的整数转化为字符类型,可以使用 `chr()` 函数来完成。修改后的代码如下: ``` def charlist(): li = [] for i in range(ord('A'), ord('Z')+1): li.append(chr(i)) return li ``` 这个函数的作用是返回一个包含大写字母 A 到 Z 的列表。

需求规格说明书1

1.引言1.1 编写目的评了么项目旨在提供一个在线评分系统,帮助助教提高作业评分效率,提供比现有方式更好的课堂答辩评审体验,同时减轻助教的工作量并降低助教工作复

人工免疫系统在先进制造系统中的应用

阵列15(2022)100238人工免疫系统在先进制造系统中的应用RuiPinto,Gil GonçalvesCNOEC-系统和技术研究中心,Rua Dr. Roberto Frias,s/n,office i219,4200-465,Porto,Portugal波尔图大学工程学院,Rua Dr. Roberto Frias,s/n 4200-465,Porto,PortugalA R T I C L E I N F O保留字:人工免疫系统自主计算先进制造系统A B S T R A C T近年来,先进制造技术(AMT)在工业过程中的应用代表着不同的先进制造系统(AMS)的引入,促使企业在面对日益增长的个性化产品定制需求时,提高核心竞争力,保持可持续发展。最近,AMT引发了一场新的互联网革命,被称为第四次工业革命。 考虑到人工智能的开发和部署,以实现智能和自我行为的工业系统,自主方法允许系统自我调整,消除了人为干预管理的需要。本文提出了一个系统的文献综述人工免疫系统(AIS)的方法来解决多个AMS问题,需要自治的

DIANA(自顶向下)算法处理鸢尾花数据集,用轮廓系数作为判断依据,其中DIANA算法中有哪些参数,请输出。 对应的参数如何取值,使得其对应的轮廓系数的值最高?针对上述问题给出详细的代码和注释

DIANA(自顶向下)算法是一种聚类算法,它的参数包括: 1. k值:指定聚类簇的数量,需要根据实际问题进行设置。 2. 距离度量方法:指定计算样本之间距离的方法,可以选择欧氏距离、曼哈顿距离等。 3. 聚类合并准则:指定合并聚类簇的准则,可以选择最大类间距离、最小类内距离等。 为了让轮廓系数的值最高,我们可以通过调整这些参数的取值来达到最优化的效果。具体而言,我们可以采用网格搜索的方法,对不同的参数组合进行测试,最终找到最优的参数组合。 以下是使用DIANA算法处理鸢尾花数据集,并用轮廓系数作为判断依据的Python代码和注释: ```python from sklearn impo

System32含义

深入了解System32的含义 对系统文件有新的认识

物联网应用中基于元启发式算法的研究和趋势

阵列14(2022)100164物联网应用Vivek Sharma,Ashish Kumar TripathiMalaviya National Institute of Technology,Jaipur,Rajasthan,印度A R T I C L E I N F O保留字:元启发式算法集群智能无人机A B S T R A C T物联网(IoT)随着大数据分析、区块链、人工智能、机器学习和深度学习等技术的发展而迅速普及。基于物联网的系统为各种任务的有效决策和自动化提供了智能和自动化的框架,使人类生活变得轻松。元启发式算法是一种自组织和分散的算法,用于使用团队智慧解决复杂问题。最近,元启发式算法已被广泛用于解决许多基于物联网的挑战。本文提出了一个系统的审查用于展开基于物联网的应用程序的元启发式算法。现有的基于元启发式算法的广泛分类已经被记录。此外,突出的应用物联网为基础的系统使用的元启发式算法。此外,包括当前的研究问题,以说明新的机会,研

把余弦函数y=cos(x)在定义域[-pi,pi]进行泰勒级数展开,观察不同结果,归纳假设余弦函数幂级数最终形式,然后对假设泰勒级数求和,验证猜想是否正确

余弦函数在定义域[-π,π]上的泰勒级数展开式为: cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + ... 根据泰勒级数的定义,我们可以发现余弦函数的幂级数最终形式为: ∑(-1)^n * x^(2n) / (2n)! 其中,n取遍所有非负整数。 为了验证这个猜想,我们可以将幂级数进行求和: cos(x) = ∑(-1)^n * x^(2n) / (2n)! = 1 - x^2/2! + x^4/4! - x^6/6! + ... 当n=0时,x^(2n)/(2n)! = 1,所以余弦函数的幂级数首项为1,与其泰勒级数展开式中的首项1相同。 当

DataStage安装配置说明(window版本7 5x2)

datastage 安装 windows。