拼音搜索功能
前言:由于项目需要,且elementUI中的el-select只支持中文或英文匹配,不支持全拼音匹配或拼音首字母匹配,故封装该功能。
-
代码依赖
第三方包:pinyin-match
地址:
https://github.com/xmflswood/pinyin-match
-
代码支持:
- 全拼音匹配 当输入beijing 可以匹配如下:“北京” “背景” “北京烤鸭”
- 拼音首字母匹配 当输入bj时 可以匹配如下:“北京烤鸭” “布局” “编辑” “有背景”,即并不是从第一个汉字进行匹配,但需要首字母的汉字前后顺序符合。
- 全拼音但最后一个汉字拼音非完整 当输入beijin 可以匹配如下:“被禁” “北京”
- 当输入拼音退格时,动态更新options的label(这个功能实现起来比较麻烦,大概多用了80%的代码)
-
代码实现
-
el-select添加属性
<el-select filterable :filter-method="(val)=>{$handleMatch(val,'deptList','name')}" @click.native="$resetOpts('deptList')"> <el-option v-for="item in deptList" :key="item.dictId" :label="item.name" :value="item.dictId"></el-option> </el-select>
-
创建拼音搜索相关方法
import store from '@/store' import PinyinMatch from 'pinyin-match/es/traditional.js'; // 方法在filter-method绑定的箭头函数中调用,需要三个参数: // 1. el-options的value // 2. option元素需要遍历的数组名 // 3. 要进行拼音匹配的options的属性 export function handleMatch(val, arrName, attr){ let res = this.$pyMatch(val, this[arrName], attr) if(res.length !== 0){ this[arrName] = res } } // 该方法接收三个参数: // 1. el-options的value // 2. 需要遍历的options选项 // 3. 要进行拼音匹配的options的属性 // 备注:需要在页面销毁生命周期函数当中调用 this.$store.commit('resetTemp') export function pyMatch(val,options,attr){ let res = [] store.commit('copyOpts',options) store.commit('pushValArr',val) let sVal = store.state.tempSelect.valArr.slice(-2)[0] // 当options中的val的长度为1或小于上一次val的值时,重新将options的备份赋值给options if(val.length < sVal.length || val.length ===1) { options = store.state.tempSelect.tempOptsArr[0]; } options.forEach(item => { let m = PinyinMatch.match(item[attr], val) if(m){ res.push(item) } }) // 如果没有匹配到结果,就重新将options的备份赋值给options if(res.length === 0) return options return res } // 该方法接收一个参数: // 1. option元素需要遍历的数组名 export function resetOpts(arrName){ if(Array.isArray(this[arrName])){ if(this[arrName].length <= 1){ this[arrName] = this.$store.getters.getOriginalSelect } } }
-
方法挂载到Vue实例
// 引入拼音搜索方法 import { handleMatch, pyMatch, resetOpts } from './utils/pinyinMatch' // 拼音搜索功能方法挂载到原型 Vue.prototype.$handleMatch = handleMatch Vue.prototype.$pyMatch = pyMatch Vue.prototype.$resetOpts = resetOpts
-
store中创建存储options备份的对象及操作方法
// options备份 state:{ tempSelect:{ tempOptsArr:[], valArr:[] } }, mutations:{ copyOpts(state,payload){ // 存储匹配到的options,原始的options存储在该数组的第0位 if(Array.isArray(payload)){ state.tempSelect.tempOptsArr.push(payload) } }, pushValArr(state,val){ // 存储每次input变化时的value if(typeof val === 'string'){ state.tempSelect.valArr.push(val) } }, resetTemp(state){ // 清空state中的tempSelect,每次路由跳转时调用 state.tempSelect.tempOptsArr = [] state.tempSelect.valArr = [] } }, getters:{ getOriginalSelect(state){ return state.tempSelect.tempOptsArr[0] } }
-
在router全局导航守卫中调用清空options备份的方法
import store from '@/store' router.beforeEach((to, from, next) => { // 此处省略其他全局导航守卫中的内容 if(store.state.tempSelect.tempOptsArr.length !== 0 || store.state.tempSelect.valArr.length !== 0){ // 当临时存储options备份的数组不为空时,在页面跳转之前清空 store.commit('resetTemp') } next() })
-
注意事项
需要遍历的options 绑定的key不能绑定index 因为每一次搜索后 options数组会发生变化,如果绑定index,index则不能与options一一对应,应当绑定唯一的id或其他参数