基于element ui 2.x版本下的多选下拉框组件
在做项目时,遇到需求不仅要适配于 pc 端,同时需要适配于 ipad ,由于项目中,一直引用的 element ui,但是其中包含的组件 el-select 中,发现在 ui 设计的设计图中不仅样式不太符合(调整样式不叫耗时),同时在苹果的 iPad 中测试,发现点击下拉选项 option 的时候,会出现需要点击两下,因为此项目为 c 端,这样给用户造成了非常不好的体验,怎么办,功能还得实现,同时也需要完美还原设计图,于是自己便封装了此组件,方便日后项目再用(样式可根据实际情况自行调整,此处仅仅做个大概框架及逻辑记录)
效果:
代码如下:
<template> <div> <div class="bg" v-if="showOption" @click.stop="showOption = false"></div> <div class="select-checkbox"> <div class="model-val" @click.stop="showOption = true" :class="{ active: showOption }" > <span class="model-val-item" v-for="(item, index) in valueList" :key="index" > <span>{{ item.name }}</span> <i class="el-icon-circle-close" @click.stop="valueItemClickHandle(item)" ></i ></span> </div> <ul class="model-option" v-if="showOption"> <li class="flex-between" v-for="(item, index) in optionsList" :key="index" @click.stop="clickOption(item)" > <span>{{ item.name }}</span> <i v-if="item.checked" class="el-icon-check"></i> </li> </ul> </div> </div> </template> <script> // 模拟父组件传递过来的option const optionsList = [ { name: 123, id: 1, checked: false, }, { name: 1234, id: 2, checked: false, }, { name: 12345, id: 3, checked: false, }, { name: 123456, id: 4, checked: false, }, { name: 1234567, id: 5, checked: false, }, { name: 12345678, id: 6, checked: false, }, { name: 123456789, id: 7, checked: false, }, { name: 1234567890, id: 8, checked: false, }, { name: 12345678901, id: 9, checked: false, }, ] export default { data() { return { showOption: false, // 是否显示option valueList: [], // 选中option的展示值 optionsList // option列表 }; }, methods: { clickOption(optionInfo) { optionInfo.checked = !optionInfo.checked; if (optionInfo.checked) this.valueList.push(optionInfo); else this.valueItemClickHandle(optionInfo, true); }, valueItemClickHandle(item, isOption = false) { if (!isOption) item.checked = !item.checked; const index = this.valueList.findIndex((el) => el.id === item.id); this.valueList.splice(index, 1); }, }, }; </script> <style scoped> ul, li { margin: 0; padding: 0; list-style: none; } .bg { position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; z-index: 9; } .model-val { position: relative; z-index: 9; width: 100%; min-height: 40px; border: 1px solid #ccc; border-radius: 4px; text-align: left; padding: 0 10px; box-sizing: border-box; cursor: pointer; } .model-val.active { border-color: #09f; } .model-val i { cursor: pointer; } .model-val-item { margin-right: 4px; padding: 4px; height: 30px; border: 1px solid #ccc; white-space: nowrap; } .flex-between { display: flex; justify-content: space-between; align-items: center; } .model-option { position: absolute; top: 100%; left: 0; z-index: 9; width: 100%; max-height: 300px; border: 1px solid #ccc; overflow-y: auto; } .model-option li { padding: 2px 14px; box-sizing: border-box; cursor: pointer; } .model-option li:hover { background-color: #eee; } </style>