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

输入搜索、分组展示选项、下拉选取,el-select 实现:即输入关键字检索,返回分组选项,选取跳转到相应内容页 —— VUE 项目-全局模糊检索

后端数据代码写于下一篇:输入搜索、分组展示选项、下拉选取,全局跳转页,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 实现 —— 后端数据处理代码,抛砖引玉展思路 


http://www.kler.cn/a/555079.html

相关文章:

  • 如何发起http的请求,在系统中集成
  • 深度学习-122-大语言模型LLM之基于langchian自定义国内联网查询工具并创建智能代理
  • 开源的 LLM 应用开发平台-Dify 部署和使用
  • Redis存在线程安全问题吗?
  • 250217-数据结构
  • Py2学习笔记
  • 基于开源Odoo模块、SKF Phoenix API与IMAX-8数采网关的资产密集型企业设备智慧运维实施方案
  • RIP路由协议的知识要点
  • GitCode 助力至善云学:构建智慧教育平台
  • 文 章 索 引
  • 23种设计模式 - 组合模式
  • armv7l
  • 基于cppzmq和MsgPack封装的Publisher Subscriber - 发布订阅模式
  • css之display:grid布局改块级元素布局
  • CF292C Beautiful IP Addresses 题解
  • Redis-缓存过期和内存淘汰
  • 机器学习和深度神经网络 参数调参数 太麻烦,非常费时间怎么办,用自动化超参数优化方法
  • IPv6报头40字节具体怎么分配的?
  • 前端面试题---循环渲染里面key的作用(vue)
  • [Android]文本多的时候让TextView的字体自动变小