el-select可输入并且可进行首字母联想输入筛选option

技术选用:vue3
UI框架:element-plus
组件:Select 选择器

首先我们做的第一步就是要让select框允许输入并且支持帅选option,关于这部分element-plus已经为我们提供了现成的属性。
在这里插入图片描述
如果只设置filterable的话,那么筛选的时候只支持中文/英文的筛选,如果想要增加拼音联想的功能的话,我们要做的第一步是先将汉字转换成拼音,这里有很多成熟的npm包可以选用,这里我选择的是
在这里插入图片描述
首先安装

npm install pinyin-pro

在需要的页面进行导入

import {
    
     pinyin } from 'pinyin-pro';

插件官方链接:https://github.com/zh-lx/pinyin-pro
简单使用方法:

import {
    
     pinyin } from 'pinyin-pro';

// 获取带音调拼音
pinyin('汉语拼音'); // 'hàn yǔ pīn yīn'

// 获取数组形式带音调拼音
pinyin('汉语拼音', {
    
     type: 'array' }); // ["hàn", "yǔ", "pīn", "yīn"]

// 获取数组形式不带声调的拼音
pinyin('汉语拼音', {
    
     toneType: 'none', type: 'array' }); // ["han", "yu", "pin", "yin"]

// 获取带音调韵母
pinyin('汉语拼音', {
    
     pattern: 'final' }); // 'àn ǔ īn īn'

有了以上方法后,并没有完结,我们会发现,在中文输入法开始输入的时候并不会自动触发筛选,这时候我们就需要另外一个属性的帮助

compositionupdate

compositionupdate这个方法在中文输入法更新但是还没确定的时候触发,对应的还有compositionend:中文输入法结束,compositionstart:中文输入法开始,而这里我们暂时只用到uopdate,有了这些准备后我们就可以实现我们想要的功能了,以下是一个小demo

<template>
	<div >
		<el-card shadow="hover">
			<el-select
				multiple
				filterable
				:filter-method="filterMethod"
				@compositionupdate="handleCompositionUpdate"
				style="width: 200px"
				v-model="state.keyWord"
				collapse-tags
				collapse-tags-tooltip
			>
				<el-option v-for="(i, index) in state.option" :key="index" :label="i.label" :value="i.label"></el-option>
			</el-select>
		</el-card>
	</div>
</template>

<script setup lang="ts" name="demo">
import { reactive, onMounted } from 'vue';
import { pinyin } from 'pinyin-pro';

const state = reactive<SysUserState>({
	// 下拉菜单原始数据&真实使用的options
	option: [],
	list: [
		{ label: '安信期货', value: '安信期货' },
		{ label: '大地期货', value: '大地期货' },
		{ label: '东证期货', value: '东证期货' },
		{ label: '废钢期货', value: '废钢期货' },
		{ label: '光大期货', value: '光大期货' },
		{ label: '广发期货', value: '广发期货' },
		{ label: '国泰期货', value: '国泰期货' },
		{ label: '国债期货', value: '国债期货' },
		{ label: '广州期货', value: '广州期货' },
		{ label: '股指期货', value: '股指期货' },
		{ label: '恒力期货', value: '恒力期货' },
		{ label: '华泰期货', value: '华泰期货' },
		{ label: '宏源期货', value: '宏源期货' },
		{ label: '君安期货', value: '君安期货' },
		{ label: '金瑞期货', value: '金瑞期货' },
		{ label: '南华期货', value: '南华期货' },
		{ label: '平安期货', value: '平安期货' },
		{ label: '瑞达期货', value: '瑞达期货' },
		{ label: '申万期货', value: '申万期货' },
		{ label: '新湖期货', value: '新湖期货' },
		{ label: '兴证期货', value: '兴证期货' },
		{ label: '一德期货', value: '一德期货' },
		{ label: '银河期货', value: '银河期货' },
		{ label: '中粮期货', value: '中粮期货' },
		{ label: '中泰期货', value: '中泰期货' },
		{ label: '中信期货', value: '中信期货' },
		{ label: '中州期货', value: '中州期货' },
	],
	// model
	keyWord:[]
});

// 中文输入法更新时触发的操作
const handleCompositionUpdate = (e) => {
	filterMethod(e.data.toString());
};

// 匹配首字母
const filterPinyin = (val: any, list: any) => {
	return list.filter((item: any) => {
		const arr = pinyin(`${item.value}`, { toneType: 'num', type: 'array' });
		let str = '';
		arr.forEach((item) => {
			str = str + item.slice(0, 1);
		});
		// 汉字包含/ 首字母包含
		if (item.value.includes(val) || str.toString().includes(val.toLowerCase())) {
			return item;
		}
	});
};

// 筛选方法
const filterMethod = (val: any) => {
	if (val) {
		state.option = filterPinyin(val, state.list);
	} else {
		state.option = state.list;
	}
};

// 页面加载时
onMounted(() => {
	state.option = state.list;
});
</script>

<style scoped lang="scss">

</style>


猜你喜欢

转载自blog.csdn.net/qq_41490563/article/details/130236457