输入搜索、分组展示选项、下拉选取,el-select实现:即输入关键字检索,返回分组选项,选取跳转到相应内容页—
- IT业界
- 2025-08-23 04:51:02

后端数据代码写于下一篇:输入搜索、分组展示选项、下拉选取,全局跳转页,el-select 实现 —— 后端数据处理代码,抛砖引玉展思路 【效果图】:分组展示选项 【去界面操作感受一下】—> 便捷简洁的企业官网 【录制效果视频展示】:
菜单栏-快速检索1
【流程】: (1)读取目标数据,如果是多个,需要多次读取; (2)对数据进行分组,放入特定分组数据结构; (3)各分组,做相应设置; (4)数据组装到 el-select 控件; (5)点击选项,跳转到相应位置。 现将关键代码及结构附于下方: 1. 分组数据结构示例: (1)标准结构示例: groupSelectOptions2: [ { id: 1, label: '超期', options: [ { value: 'cqwbj', label: '超期未办结' }, { value: 'ycq', label: '已超期' } ] }, { id: 2, label: '按天', options: [ { value: 't1', label: '1天' }, { value: 't2', label: '2天' }, { value: 't3', label: '3天' } ] }, { id: 3, label: '按小时', options: [ { value: 'h1', label: '1小时' }, { value: 'h2', label: '2小时' } ] } ] (2)项目数据结构示例:主要的就 label 和 srcPath 这两个属性(其余省略):label,用于显示;srcPath,存储选取跳转的 url 地址。
[ { label:'', options:[ {srcPath: ''} ] }, ] 2. 封装 el-select 成组件: <template> <div style="height: 15px; justify-content: center; align-items: center;"> <template> <el-select v-model="innerValue" filterable :remote="true" :likeQuery="false" @change="changeSelect" :clearable="clearable" :multiple="multiple" :remote-method="fetchOptions" size="small" popper-class="productGroupSelector" :placeholder="placeholder" > <el-option-group class="productGroupSelector-group" v-for="group in localOptions" :key="group.label" :label="group.label"> <div style="" v-if="multiple"> <div style=""> <el-checkbox v-model="group.checked" @change="selectAll($event, group.id)" :indeterminate="group.isIndeterminate"></el-checkbox> </div> <div> <el-option class="productGroupSelector-option" v-for="item in group.options" :key="item.value" :label="item.label" :value="item" ></el-option> </div> </div> <div v-else> <el-option class="productGroupSelector-option" v-for="(item,index) in group.options" :key="index" :label="item.label" :value="item" ></el-option> </div> </el-option-group> </el-select> </template> </div> </template> 3. javascript 和 css <script> import $ from 'jquery'; import {getRequest} from "@/api/api"; export default { name: 'LiloGroupSelect', model: { prop: 'value', event: 'change' }, props: { value: { type: [String, Array], default: () => [] }, options: { type: Array, default: () => [] }, placeholder: { type: String, default: '请选择' }, multiple: { type: Boolean, default: false }, clearable: { type: Boolean, default: false }, collapseTags: { type: Boolean, default: false }, likeQuery: { type: Boolean, default: false }, searchApi: { type: String, default: '' // 后端搜索API地址 } }, data() { return { innerValue: this.value, inputValue: '' ,// 添加这一行来定义 inputValue selectedOption: '', // searchQuery: '', filteredOptions: [], loading: false, allOptions: [], // 存储所有后端返回的选项,用于筛选 localOptions: [...this.options], // 新增属性,用于存储当前选项 groupSelectOptions2: [ { id: 1, label: '超期', options: [ { value: 'cqwbj', label: '超期未办结' }, { value: 'ycq', label: '已超期' } ] }, { id: 2, label: '按天', options: [ { value: 't1', label: '1天' }, { value: 't2', label: '2天' } ] }, { id: 3, label: '按小时', options: [ { value: 'h1', label: '1小时' }, { value: 'h2', label: '2小时' } ] } ], isDropdownVisible: false, // 控制下拉列表的显示状态(默认收起)隐藏 }; }, mounted() { this.innerValue = this.value; this.allOptions = [...this.options, ...this.groupSelectOptions2]; // 初始化所有选项 this.filteredOptions = [...this.options]; // 初始化过滤后的选项 }, watch: { value(newVal, odlVal) { this.innerValue = newVal; console.log("当前输入值或选择值:"+this.innerValue) }, searchQuery(newVal) { console.log("监听查询输入:"+newVal) this.fetchOptions(newVal); } }, methods: { // 模拟后端查询,直接返回 groupSelectOptions2 fetchOptions(queryString) { console.log("调用后端,请求数据....查询条件:【"+queryString+"】查询接口为:"+this.searchApi) if (this.loading) return; this.loading = true; try { // 此处模拟为直接返回 groupSelectOptions2,实际应调用后端API this.allOptions = [...this.options, ...this.groupSelectOptions2]; // 合并原始选项和后端返回的选项(去重应在后端处理或此处额外处理) if(this.likeQuery) queryString = '%'+queryString+'%'; this.getRequest(this.searchApi, {query: queryString}).then(resp =>{ if (resp){ this.localOptions = [...resp]; // console.log("调用后端,返回结果:"+JSON.stringify(resp)) } }); // this.localOptions = [...this.groupSelectOptions2]; // 更新 localOptions 而不是 this.options // this.filteredOptions = this.filterOptionsByQuery(this.allOptions, queryString); console.log("调用后端,数据处理结束。。。") } catch (error) { console.error('搜索失败:', error); } finally { this.loading = false; } }, async query(queryString){ if(this.likeQuery) queryString = '%'+queryString+'%'; this.getRequest(this.searchApi, {query: queryString}).then(resp =>{ if (resp){ this.localOptions = [...resp]; } }); }, filterOptionsByQuery(options, query) { return this.allOptions.reduce((acc, group) => { const filteredGroup = { ...group, options: group.options.filter(option => option.label.toLowerCase().includes(query.toLowerCase())) }; // const filteredGroup = { ...group, options: group.options.filter(option => option.label.includes(query)) }; if (filteredGroup.options.length > 0) { acc.push(filteredGroup); } return acc; }, []); }, selectAll(val, id) { const selectOption = this.options.find(f => f.id === id); const arr = selectOption.options.map(m => m.value); if (val) { if((typeof this.innerValue !== 'object') || this.innerValue.constructor !== Array) { this.innerValue = []; } arr.forEach(item => { if (!this.innerValue.includes(item)) { this.innerValue.push(item); } }); } else { this.innerValue.forEach((item, index) => { if (arr.includes(item)) { this.innerValue.splice(index, 1, ''); } }); } this.innerValue = this.innerValue.filter(f => f !== ''); if (selectOption.checked) { selectOption.isIndeterminate = false; } this.$emit('change', this.innerValue); }, changeSelect(val) { console.log("选项变更值:"+val) if (this.multiple) { this.options.forEach(item => { const arr = item.options.map(m => m.value); item.isIndeterminate = arr.some(v => { return val.some(s => s === v); }); item.checked = arr.every(v => { return val.some(s => s === v); }); if (item.checked) { item.isIndeterminate = false; } }); this.$emit('change', this.innerValue); } else { this.$emit('change', val); } }, } }; </script> <style> .productGroupSelector { min-width: initial !important; width: 415px; } </style> <style lang="scss" scoped> ::v-deep { .el-select-group { width: 400px; display: flex; flex-wrap: wrap; justify-content: start; padding: 0px 10px; } .el-select-group__title { padding-left: 20px; font-size: 12px; } } .productGroupSelector-group { padding-top: 5px; display: flex; // align-items: center; // flex-wrap: wrap; // width: 400px; padding-bottom: 5px; flex-direction: column; margin: 0 5px; // &:not(:last-child) { // border-bottom: 1px solid rgba($color: #000000, $alpha: 0.1); // } &::after { display: none; } } .productGroupSelector-option { display: inline-flex; align-items: center; flex-wrap: wrap; } // .productGroupSelector { // .el-scrollbar__view .el-select-dropdown__list { // display: flex; // flex-wrap: wrap; // justify-content: space-between; // align-items: baseline; // padding-top: 0; // overflow-x: hidden; // } // .el-select-dropdown__wrap .el-scrollbar__wrap { // max-height: 650px; // } // } </style>4. 引用 LiloGroupSelect
<el-row :gutter="20" style="display: flex; border-radius: 5px;" > <el-col style="margin-bottom: 7px;"> <lilo-group-select @change="groupSelectChange" :multiple="false" :likeQuery="true" :searchApi="'/api/list/search'" clearable placeholder="请输入快速搜索" ></lilo-group-select> </el-col> </el-row> <script> import LiloGroupSelect from "@/components/common/help/ElementUIGroupSelect"; export default { name: "***", components: { LiloGroupSelect }, data(){ return{} }, methods: { groupSelectChange(option) { console.log("下拉选项选中:"+JSON.stringify(option)); if(option==''|| option.srcPath=='')return; // this.$router.push(option.srcPath); this.$router.push(option.srcPath).catch(err => { if (err.name !== 'NavigationDuplicated') { // 处理其他可能的错误 console.error(err); } // 对于 NavigationDuplicated 错误,可以选择不做任何处理 }); }, } } 【效果图】:分组展示选项 参考资源:1. Vue【原创】基于elementui的【分组多选下拉框group-select】 2. el-select选择器组件封装 下拉菜单 elementui 3. Vue Element 分组+多选+可搜索Select选择器实现示例 4. 基于Vue和Element-UI自定义分组以及分组全选Select 选择器
【项目实际效果】: 便捷简洁的企业官网 后端数据代码写于下一篇:输入搜索、分组展示选项、下拉选取,全局跳转页,el-select 实现 —— 后端数据处理代码,抛砖引玉展思路输入搜索、分组展示选项、下拉选取,el-select实现:即输入关键字检索,返回分组选项,选取跳转到相应内容页—由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“输入搜索、分组展示选项、下拉选取,el-select实现:即输入关键字检索,返回分组选项,选取跳转到相应内容页—”