读elementui源码第四天

199 阅读1分钟

select组件的搜索功能

  1. filterable开启时,提供搜索输入框
<input
        type="text"
        class="el-select__input"
        @focus="visible = true"
        @keyup="managePlaceholder"
        @keydown="resetInputState"
        @keydown.down.prevent="navigateOptions('next')"
        @keydown.up.prevent="navigateOptions('prev')"
        @keydown.enter.prevent="selectOption"
        @keydown.esc.prevent="visible = false"
        @keydown.delete="deletePrevTag"
        v-model="query"
        :debounce="remote ? 300 : 0"
        v-if="filterable"
        :style="{ width: inputLength + 'px', 'max-width': inputWidth - 42 + 'px' }"
        ref="input">

2.watch中监听query的值

query(val) {
        this.$nextTick(() => {
          this.broadcast('select-dropdown', 'updatePopper');
        });
        if (this.multiple && this.filterable) {
          this.resetInputHeight();
        }
        /* 如果时远程搜索,执行传入的远程搜索的函数 */
        if (this.remote && typeof this.remoteMethod === 'function') {
          this.hoverIndex = -1;
          this.remoteMethod(val);
          this.voidRemoteQuery = val === '';
          this.broadcast('option', 'resetIndex');
        } else if (typeof this.filterMethod === 'function') {/* 自定义搜索 */
          this.filterMethod(val);
        } else {
          this.filteredOptionsCount = this.optionsCount;
          this.broadcast('option', 'queryChange', val);/* 将搜索事件派发给option组件 */
        }
      },

3.option组件的搜索逻辑

queryChange(query) {
        // query 里如果有正则中的特殊字符,需要先将这些字符转义
        let parsedQuery = query.replace(/(\^|\(|\)|\[|\]|\$|\*|\+|\.|\?|\\|\{|\}|\|)/g, '\\$1');
        /* 检索currentLabel中的parsedQuery字符串,'i':大小写不敏感 */
        this.visible = new RegExp(parsedQuery, 'i').test(this.currentLabel);
        /* 不匹配就将自身隐藏,并告诉父组件选项数量减一 */
        if (!this.visible) {
          this.parent.filteredOptionsCount--;
        }
      },