iview采坑记

1,508 阅读1分钟

简介

在使用iview的Select组件可搜索功能时,如果我输入2,则不光会匹配到2那一项,还会匹配到其它的数据,最后发现,iview内部的validateOption函数不仅会匹配jobName,还会匹配jobId。只要其中有一项匹配,那么这条数据就会被选中

解决方法

我们现在先写一个下拉列表

                <Select v-model="formData.jobId"
                :only-filter-with-text="true"  //此变量是用来控制是否启用自定义的originValidateOption函数。true代表启用
                class="item-input"
                filterable>
                >
                  <Option v-for="job in jobNameSet" :value="job.jobId" :key="job.jobId">{{job.jobName}}</Option>
                </Select>
                
export default {
    data() {
        return {
            formData:{
                jobId:'',
            },
            jobNameSet:[
                {
                    jobId:1,
                    jobName:'3月份'
                },
                {
                    jobId:2,
                    jobName:'1月份'
                },
                {
                    jobId:3,
                    jobName:'2月份'
                }
            ]
        }
    }
}

下拉列表长这样

输入2查询与之匹配的数据时,‘1月份’也会被匹配中,这是因为‘一月份’的jobId为2。

这是因为iview内部的validateOption函数不仅会匹配jobName,还会匹配jobId。只要其中有一项匹配,那么这条数据就会被选中。我们现在重写iview的validateOption函数,让它只匹配jobName。 这是iview内部原始的validateOption函数

validateOption({children, elm, propsData}){
    const value = propsData.value;
    const label = propsData.label || '';
    const textContent = (elm && elm.textContent) || (children || []).reduce((str, node) => {
        const nodeText = node.elm ? node.elm.textContent : node.text;
        return `${str} ${nodeText}`;
    }, '') || '';
    const stringValues = JSON.stringify([value, label, textContent]);
    const query = this.query.toLowerCase().trim();
    return stringValues.toLowerCase().includes(query);
},

这里是对originValidateOption函数的重写

import Vue from 'vue';
import iView from 'iview';

iView.Select.props.onlyFilterWithText = {
  type: Boolean,
  default: false
};
iView.Select.methods.originValidateOption = iView.Select.methods.validateOption;
iView.Select.methods.validateOption = function ({children, elm, propsData}) {
    if (this.onlyFilterWithText) {
      const textContent = (elm && elm.textContent) || (children || []).reduce((str, node) => {
          const nodeText = node.elm ? node.elm.textContent : node.text;
          return `${str} ${nodeText}`;
      }, '') || '';
      const query = this.query.toLowerCase().trim();
      return textContent.toLowerCase().includes(query);
    } else {
      return this.originValidateOption({children, elm, propsData});
    }
};
Vue.use(iView);

此时输入2,因为只匹配jobName,所以只出现‘2月份’。