Vue项目中 实现ElementUi框架el-select拼音搜索功能

拼音搜索功能

前言:由于项目需要,且elementUI中的el-select只支持中文或英文匹配,不支持全拼音匹配或拼音首字母匹配,故封装该功能。


  1. 代码依赖

    ​ 第三方包:pinyin-match

    ​ 地址: https://github.com/xmflswood/pinyin-match

  2. 代码支持:

    1. 全拼音匹配 当输入beijing 可以匹配如下:“北京” “背景” “北京烤鸭”
    2. 拼音首字母匹配 当输入bj时 可以匹配如下:“北京烤鸭” “布局” “编辑” “有背景”,即并不是从第一个汉字进行匹配,但需要首字母的汉字前后顺序符合。
    3. 全拼音但最后一个汉字拼音非完整 当输入beijin 可以匹配如下:“被禁” “北京”
    4. 当输入拼音退格时,动态更新options的label(这个功能实现起来比较麻烦,大概多用了80%的代码)
  3. 代码实现

    1. 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>
      
    2. 创建拼音搜索相关方法

      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
              }
          }
      }
      
    3. 方法挂载到Vue实例

      // 引入拼音搜索方法
      import { handleMatch, pyMatch, resetOpts } from './utils/pinyinMatch'
      
      // 拼音搜索功能方法挂载到原型
      Vue.prototype.$handleMatch = handleMatch
      Vue.prototype.$pyMatch = pyMatch
      Vue.prototype.$resetOpts = resetOpts
      
    4. 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]
          }
      }
      
    5. 在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或其他参数

Logo

前往低代码交流专区

更多推荐