zoukankan      html  css  js  c++  java
  • element-ui select组件中复选时以字符串形式显示

    我使用的element-ui的版本是1.4.13。

    如上图所示,使用el-select组件,要实现可搜索、可复选、可创建条目时,展示样式是如上图所示,输入框的高度会撑开,影响页面布局,按照产品的需求,要调整为以下样式:

    1、复选时,输入框中不以标签的形式展示,而是以字符串的形式展示。

    2、超出部分显示省略号,并且鼠标移入显示提示框,用来展示全选的内容。

    下面是源码修改部分:

    (1)在select的props中添加了一个参数noTag用来控制是否以字符串形式显示输入框中的数据。添加了上面的el-popover标签,主要是文字超出时显示,这个后面再讲。底下的span标签就是在noTag参数为true时显示,data中添加currentSelLabel,用来显示处理后的多选数据,将数组转成字符串。

    (2)在这里加了一个类,主要是方便后面加span标签的css样式。在select.css文件中的css样式如下面代码所示:

    .el-select__tags.noTags .noTagSpan{
        display: inline-block;
        font-size: 12px;
         100%;
        padding:0 6px;
        overflow: hidden; /*自动隐藏文字*/
        text-overflow: ellipsis; /*文字隐藏后添加省略号*/
        white-space: nowrap; /*强制不换行*/
    }
    

    (3)在noTag参数为true时显示class="noTagSpan"的span标签时,对应的el-tag标签就不再显示,如图所示,也需要在el-tag标签中添加noTag控制

    (4)在setSelected方法中处理多选时的数据,将数组转成字符串,如下图所示:

    (5)文字超出时显示提示框,效果如下:

    需要在methods中添加如下方法:

     //当复选时文字超出输入框,出现提示框
            showSpanTooltip: function (event) {
                if(!this.showpop) return;
                var ev = event || window.event;
                var eventName = ev.target.className;
                if (eventName.indexOf('noTagSpan') != -1) {
                    if (ev.target.offsetWidth < ev.target.scrollWidth) {
                        var tooltip = this.$refs.textTooltip;
                        tooltip.referenceElm = ev.target;
                        tooltip.$refs.popper.style.display = 'none';
                        tooltip.doDestroy();
                        tooltip.showPopper = true;
                    }
                }
            },
            //当复选时文字超出输入框,隐藏提示框
            hiddenSpanTooltip: function () {
                if(!this.showpop) return;
                const tooltip = this.$refs.textTooltip;
                if (tooltip) {
                    tooltip.doClose() ;
                    tooltip.doDestroy();
                }
            }
    

    (6)多选时,可搜索。按照组件现在的,搜索框会在选项的下面出现,这样会撑开输入框的高度。

    这里需要调整,将输入框放在下面的下拉菜单中,如图所示:

    代码如下:

    避免跟element原有的搜索框冲突,加了参数控制:

    需要在select.css加入如下样式:

    .noTagInputDiv{
        border: 1px solid rgb(191, 193, 217);
        margin-left: -1px;
        margin-top:-30px;
         100%;
        max- 185px;
        padding-right: 30px;
        overflow: hidden; /*自动隐藏文字*/
        text-overflow: ellipsis; /*文字隐藏后添加省略号*/
        white-space: nowrap; /*强制不换行*/
    }
    

    这个时候需要在下拉出现的时候调整整个下拉菜单的位置,具体修改代码的地方如下:
    在data中加入initPopperTop,用来记录初始时下拉菜单的位置:
    1、在watch中的visible中

    2、在watch中的query中

    3、methods的resetInputHeight方法中

    (7)多选时并且可搜索时,如果条目不存在时,创建条目,并且显示在下拉菜单中,这样可以通过反选删除选中的数据。
    1、添加el-option标签,用来显示创建的条目。在data中添加mulOptions数组,用来记录创建的条目。

    2、handleOptionSelect方法中处理数据

    3、在option.vue的props中添加optcreated

    ok,所有的就改完了,效果如图所示:

    以下附源码:

    <template>
      <div
        class="el-select"
        v-clickoutside="handleClose">
        <div
          class="el-select__tags"
          :class="{'noTags':noTag}"
          v-if="multiple"
          @click.stop="toggleMenu"
          ref="tags"
          :style="{ 'max-width': inputWidth - 32 + 'px' }">
          <transition-group @after-leave="resetInputHeight">
            <el-tag
              v-if="!noTag"
              v-for="item in selected"
              :key="getValueKey(item)"
              closable
              :hit="item.hitState"
              type="primary"
              @close="deleteTag($event, item)"
              close-transition>
              <span class="el-select__tags-text">{{ item.currentLabel }}</span>
            </el-tag>
          </transition-group>
    
            <el-popover
                 ref="textTooltip"
                 placement="top-start"
                 width="200"
                 trigger="hover"
                 :content="currentSelLabel">
            </el-popover>
            <span v-if="noTag" class="noTagSpan"
                  @mouseenter="showSpanTooltip($event)" @mouseleave="hiddenSpanTooltip($event)">
                {{currentSelLabel}}
            </span>
          <input
            type="text"
            class="el-select__input"
            :class="`is-${ size }`"
            @focus="visible = true"
            :disabled="disabled"
            @keyup="managePlaceholder"
            @keydown="resetInputState"
            @keydown.down.prevent="navigateOptions('next')"
            @keydown.up.prevent="navigateOptions('prev')"
            @keydown.enter.prevent="selectOption"
            @keydown.esc.stop.prevent="visible = false"
            @keydown.delete="deletePrevTag"
            v-model="query"
            :debounce="remote ? 300 : 0"
            v-if="filterable && !noTag"
            :style="{  inputLength + 'px', 'max-width': inputWidth - 42 + 'px' }"
            ref="input">
        </div>
        <el-input
          ref="reference"
          v-model="selectedLabel"
          type="text"
          :placeholder="currentPlaceholder"
          :name="name"
          :size="size"
          :disabled="disabled"
          :readonly="!filterable || multiple"
          :validate-event="false"
          @focus="handleFocus"
          @click="handleIconClick"
          @mousedown.native="handleMouseDown"
          @keyup.native="debouncedOnInputChange"
          @keydown.native.down.prevent="navigateOptions('next')"
          @keydown.native.up.prevent="navigateOptions('prev')"
          @keydown.native.enter.prevent="selectOption"
          @keydown.native.esc.stop.prevent="visible = false"
          @keydown.native.tab="visible = false"
          @paste.native="debouncedOnInputChange"
          @mouseenter.native="inputHovering = true"
          @mouseleave.native="inputHovering = false"
          :icon="iconClass">
        </el-input>
        <transition
          name="el-zoom-in-top"
          @before-enter="handleMenuEnter"
          @after-leave="doDestroy">
          <el-select-menu
            ref="popper"
            v-show="visible && emptyText !== false">
              <!--有noTag时搜索框在下面显示-->
              <div  v-if="filterable && noTag && multiple" :class="{'noTagInputDiv':noTag}">
                  <input
                      type="text"
                      class="el-select__input"
                      :class="`is-${ size }`"
                      @focus="visible = true"
                      :disabled="disabled"
                      @keyup="managePlaceholder"
                      @keydown="resetInputState"
                      @keydown.down.prevent="navigateOptions('next')"
                      @keydown.up.prevent="navigateOptions('prev')"
                      @keydown.enter.prevent="selectOption"
                      @keydown.esc.stop.prevent="visible = false"
                      @keydown.delete="deletePrevTag"
                      v-model="query"
                      :debounce="remote ? 300 : 0"
                      v-if="filterable && noTag && multiple"
                      :style="{  inputLength + 'px', 'max-width': inputWidth - 42 + 'px' }"
                      ref="input">
                </div>
            <el-input v-model="search" @focus="visible = true" v-if="searchable"></el-input>
            <el-scrollbar
              tag="ul"
              wrap-class="el-select-dropdown__wrap"
              view-class="el-select-dropdown__list"
              :class="{ 'is-empty': !allowCreate && filteredOptionsCount === 0 }"
              v-show="options.length > 0 && !loading">
              <el-option
                :value="query"
                created
                v-if="showNewOption">
              </el-option>
               <el-option
                      v-if="noTag && multiple && allowCreate"
                      v-for="item in mulOptions"
                      :key="item.currentLabel"
                      :optcreated="item.optcreated"
                      :value="item.currentLabel">
               </el-option>
              <slot></slot>
            </el-scrollbar>
            <p class="el-select-dropdown__empty" v-if="emptyText && (allowCreate && options.length === 0 || !allowCreate)">{{ emptyText }}</p>
          </el-select-menu>
        </transition>
      </div>
    </template>
    
    <script type="text/babel">
      import Emitter from 'element-ui/src/mixins/emitter';
      import Locale from 'element-ui/src/mixins/locale';
      import ElInput from 'element-ui/packages/input';
      import ElSelectMenu from './select-dropdown.vue';
      import ElOption from './option.vue';
      import ElTag from 'element-ui/packages/tag';
      import ElScrollbar from 'element-ui/packages/scrollbar';
      import debounce from 'throttle-debounce/debounce';
      import Clickoutside from 'element-ui/src/utils/clickoutside';
      import { addClass, removeClass, hasClass } from 'element-ui/src/utils/dom';
      import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
      import { t } from 'element-ui/src/locale';
      import scrollIntoView from 'element-ui/src/utils/scroll-into-view';
      import { getValueByPath } from 'element-ui/src/utils/util';
    
      const sizeMap = {
        'large': 42,
        'small': 30,
        'mini': 22
      };
    
      export default {
        mixins: [Emitter, Locale],
    
        name: 'ElSelect',
    
        componentName: 'ElSelect',
    
        computed: {
          iconClass() {
            let criteria = this.clearable &&
              !this.disabled &&
              this.inputHovering &&
              !this.multiple &&
              this.value !== undefined &&
              this.value !== '';
            return criteria ? 'circle-close is-show-close' : (this.remote && this.filterable ? '' : 'caret-top');
          },
    
          debounce() {
            return this.remote ? 300 : 0;
          },
    
          emptyText() {
            if (this.loading) {
              return this.loadingText || this.t('el.select.loading');
            } else {
              if (this.remote && this.query === '' && this.options.length === 0) return false;
              if (this.filterable && this.options.length > 0 && this.filteredOptionsCount === 0) {
                return this.noMatchText || this.t('el.select.noMatch');
              }
              if (this.options.length === 0) {
                return this.noDataText || this.t('el.select.noData');
              }
            }
            return null;
          },
    
          showNewOption() {
            let hasExistingOption = this.options.filter(option => !option.created)
              .some(option => option.currentLabel === this.query);
            return this.filterable && this.allowCreate && this.query !== '' && !hasExistingOption;
          }
        },
    
        components: {
          ElInput,
          ElSelectMenu,
          ElOption,
          ElTag,
          ElScrollbar
        },
    
        directives: { Clickoutside },
    
        props: {
          name: String,
          value: {
            required: true
          },
          size: String,
          disabled: Boolean,
          clearable: Boolean,
          filterable: Boolean,
          searchable: Boolean,
          allowCreate: Boolean,
          noTag:Boolean,  //多选的时候是否以字符串形式展示 f
          showpop: {  //是否在文字超出span标签的时候显示提示 f
             type: Boolean,
             default: true
          },
          loading: Boolean,
          popperClass: String,
          remote: Boolean,
          loadingText: String,
          noMatchText: String,
          noDataText: String,
          remoteMethod: Function,
          filterMethod: Function,
          multiple: Boolean,
          multipleLimit: {
            type: Number,
            default: 0
          },
          placeholder: {
            type: String,
            default() {
              return t('el.select.placeholder');
            }
          },
          defaultFirstOption: Boolean,
          valueKey: {
            type: String,
            default: 'value'
          }
        },
    
        data() {
          return {
            options: [],
            cachedOptions: [],
            createdLabel: null,
            createdSelected: false,
            selected: this.multiple ? [] : {},
            isSelect: true,
            inputLength: 20,
            inputWidth: 0,
            cachedPlaceHolder: '',
            optionsCount: 0,
            filteredOptionsCount: 0,
            visible: false,
            selectedLabel: '',
            hoverIndex: -1,
            query: '',
            search: '',
            optionsAllDisabled: false,
            inputHovering: false,
            currentPlaceholder: '',
            currentSelLabel:'', //多选时以字符串形式展示的标签 f
            initPopperTop:0, //初始时下拉框的位置 f
            mulOptions:[]   //多选时添加的数据 f
          };
        },
    
        watch: {
          placeholder(val) {
            this.cachedPlaceHolder = this.currentPlaceholder = val;
          },
    
          value(val) {
            if (this.multiple) {
              this.resetInputHeight();
              if (val.length > 0 || (this.$refs.input && this.query !== '')) {
                this.currentPlaceholder = '';
              } else {
                this.currentPlaceholder = this.cachedPlaceHolder;
              }
            }
            this.setSelected();
            if (this.filterable && !this.multiple) {
              this.inputLength = 20;
            }
            this.$emit('change', val);
            this.dispatch('ElFormItem', 'el.form.change', val);
          },
    
          search(val) {
            if (this.searchable) {
              this.$emit('search-change', val);
            }
          },
          query(val) {
            this.$nextTick(() => {
              if (this.visible) {
                  this.broadcast('ElSelectDropdown', 'updatePopper');
                  //multiple、noTag、filterable 同时存在时,调整下拉框位置
                  if(this.multiple && this.noTag && this.filterable){
                      this.$nextTick(()=>{
                          var popperTop = window.getComputedStyle? window.getComputedStyle(this.$refs.popper.$el).top : this.$refs.popper.$el.currentStyle.top;
                          this.$refs.popper.$el.style.top = parseInt(popperTop)+ 25+'px';
                      })
                  }
              }
            });
            this.hoverIndex = -1;
            if (this.multiple && this.filterable) {
              this.inputLength = this.$refs.input.value.length * 15 + 20;
              this.managePlaceholder();
              this.resetInputHeight();
            }
            if (this.remote && typeof this.remoteMethod === 'function') {
              this.hoverIndex = -1;
              this.remoteMethod(val);
              this.broadcast('ElOption', 'resetIndex');
            } else if (typeof this.filterMethod === 'function') {
              this.filterMethod(val);
              this.broadcast('ElOptionGroup', 'queryChange');
            } else {
              this.filteredOptionsCount = this.optionsCount;
              this.broadcast('ElOption', 'queryChange', val);
              this.broadcast('ElOptionGroup', 'queryChange');
            }
            if (this.defaultFirstOption && (this.filterable || this.remote) && this.filteredOptionsCount) {
              this.checkDefaultFirstOption();
            }
          },
    
          visible(val) {
            if (!val) {
              this.$refs.reference.$el.querySelector('input').blur();
              this.handleIconHide();
              this.broadcast('ElSelectDropdown', 'destroyPopper');
              if (this.$refs.input) {
                this.$refs.input.blur();
              }
              this.query = '';
              this.selectedLabel = '';
              this.inputLength = 20;
              this.resetHoverIndex();
              this.$nextTick(() => {
                if (this.$refs.input &&
                  this.$refs.input.value === '' &&
                  this.selected.length === 0) {
                  this.currentPlaceholder = this.cachedPlaceHolder;
                }
              });
              if (!this.multiple) {
                if (this.selected) {
                  if (this.filterable && this.allowCreate &&
                    this.createdSelected && this.createdLabel) {
                    this.selectedLabel = this.createdLabel;
                  } else {
                    this.selectedLabel = this.selected.currentLabel;
                  }
                  if (this.filterable) this.query = this.selectedLabel;
                }
              }
            } else {
              this.handleIconShow();
              this.broadcast('ElSelectDropdown', 'updatePopper');
               //multiple、noTag、filterable 同时存在时,调整下拉框位置,并记录初始下拉框的位置
              if(this.multiple && this.noTag && this.filterable){
                    this.$nextTick(()=>{
                        this.$refs.input.focus();
                        var popperTop = window.getComputedStyle? window.getComputedStyle(this.$refs.popper.$el).top : this.$refs.popper.$el.currentStyle.top;
                        //记录初始下拉框的位置
                        this.initPopperTop = popperTop;
                        this.$refs.popper.$el.style.top = parseInt(popperTop) + 25 +'px';
                    })
                }
              if (this.filterable) {
                this.query = this.selectedLabel;
                if (this.multiple) {
                  this.$refs.input.focus();
                } else {
                  if (!this.remote) {
                    this.broadcast('ElOption', 'queryChange', '');
                    this.broadcast('ElOptionGroup', 'queryChange');
                  }
                  this.broadcast('ElInput', 'inputSelect');
                }
              }
            }
            this.$emit('visible-change', val);
          },
    
          options(val) {
            if (this.$isServer) return;
            this.optionsAllDisabled = val.length === val.filter(item => item.disabled === true).length;
            if (this.multiple) {
              this.resetInputHeight();
            }
            let inputs = this.$el.querySelectorAll('input');
            if ([].indexOf.call(inputs, document.activeElement) === -1) {
              this.setSelected();
            }
            if (this.defaultFirstOption && (this.filterable || this.remote) && this.filteredOptionsCount) {
              this.checkDefaultFirstOption();
            }
          }
        },
    
        methods: {
            //当复选时文字超出输入框,出现提示框
            showSpanTooltip: function (event) {
                if(!this.showpop) return;
                var ev = event || window.event;
                var eventName = ev.target.className;
                if (eventName.indexOf('noTagSpan') != -1) {
                    if (ev.target.offsetWidth < ev.target.scrollWidth) {
                        var tooltip = this.$refs.textTooltip;
                        tooltip.referenceElm = ev.target;
                        tooltip.$refs.popper.style.display = 'none';
                        tooltip.doDestroy();
                        tooltip.showPopper = true;
                    }
                }
            },
            //当复选时文字超出输入框,隐藏提示框
            hiddenSpanTooltip: function () {
                if(!this.showpop) return;
                const tooltip = this.$refs.textTooltip;
                if (tooltip) {
                    tooltip.doClose() ;
                    tooltip.doDestroy();
                }
            },
          handleIconHide() {
            let icon = this.$el.querySelector('.el-input__icon');
            if (icon) {
              removeClass(icon, 'is-reverse');
            }
          },
    
          handleIconShow() {
            let icon = this.$el.querySelector('.el-input__icon');
            if (icon && !hasClass(icon, 'el-icon-circle-close')) {
              addClass(icon, 'is-reverse');
            }
          },
    
          scrollToOption(className = 'selected') {
            const menu = this.$refs.popper.$el.querySelector('.el-select-dropdown__wrap');
            scrollIntoView(menu, menu.getElementsByClassName(className)[0]);
          },
    
          handleMenuEnter() {
            this.$nextTick(() => this.scrollToOption());
          },
    
          getOption(value) {
            let option;
            const type = typeof value;
            const isObject = type !== 'string' && type !== 'number' && type !== 'boolean';
            for (let i = this.cachedOptions.length - 1; i >= 0; i--) {
              const cachedOption = this.cachedOptions[i];
              const isEqual = isObject
                ? this.getValueByPath(cachedOption.value, this.valueKey) === this.getValueByPath(value, this.valueKey)
                : cachedOption.value === value;
              if (isEqual) {
                option = cachedOption;
                break;
              }
            }
            if (option) return option;
            const label = !isObject
              ? value : '';
            let newOption = {
              value: value,
              currentLabel: label
            };
            if (this.multiple) {
              newOption.hitState = false;
            }
            return newOption;
          },
          getValueByPath(object, prop) {
            prop = prop || '';
            const paths = prop.split('.');
            let current = object;
            let result = null;
            for (let i = 0, j = paths.length; i < j; i++) {
              const path = paths[i];
              if (current !== 0 && !current) break;
              if (i === j - 1) {
                result = current[path];
                break;
              }
              current = current[path];
            }
            return result;
          },
    
          setSelected() {
            if (!this.multiple) {
              let option = this.getOption(this.value);
              if (option.created) {
                this.createdLabel = option.currentLabel;
                this.createdSelected = true;
              } else {
                this.createdSelected = false;
              }
              this.selectedLabel = option.currentLabel;
              this.selected = option;
              if (this.filterable) this.query = this.selectedLabel;
              return;
            }
            let result = [];
            if (Array.isArray(this.value)) {
              this.value.forEach(value => {
                result.push(this.getOption(value));
              });
            }
            this.selected = result;
             //复选时,选项以字符串的形式显示,此处处理显示数据,数组转成字符串
             if(this.noTag && this.multiple){
                  var arr = [];
                  if(this.selected && this.selected.length){
                      this.selected.forEach(function(item){
                          arr.push(item.currentLabel);
                      })
                  }
                  this.currentSelLabel = arr.join(',');
             }
            this.$nextTick(() => {
              this.resetInputHeight();
            });
          },
    
          handleFocus() {
            this.visible = true;
          },
    
          handleIconClick(event) {
            if (this.iconClass.indexOf('circle-close') > -1) {
              this.deleteSelected(event);
            } else {
              this.toggleMenu();
            }
          },
    
          handleMouseDown(event) {
            if (event.target.tagName !== 'INPUT') return;
            if (this.visible) {
              this.handleClose();
              event.preventDefault();
            }
          },
    
          doDestroy() {
            this.$refs.popper && this.$refs.popper.doDestroy();
            this.dropdownUl = null;
          },
    
          handleClose() {
            this.visible = false;
          },
    
          toggleLastOptionHitState(hit) {
            if (!Array.isArray(this.selected)) return;
            const option = this.selected[this.selected.length - 1];
            if (!option) return;
    
            if (hit === true || hit === false) {
              option.hitState = hit;
              return hit;
            }
    
            option.hitState = !option.hitState;
            return option.hitState;
          },
    
          deletePrevTag(e) {
            if (e.target.value.length <= 0 && !this.toggleLastOptionHitState()) {
              const value = this.value.slice();
              value.pop();
              this.$emit('input', value);
            }
          },
    
          managePlaceholder() {
            if (this.currentPlaceholder !== '') {
              this.currentPlaceholder = this.$refs.input.value ? '' : this.cachedPlaceHolder;
            }
          },
    
          resetInputState(e) {
            if (e.keyCode !== 8) this.toggleLastOptionHitState(false);
            this.inputLength = this.$refs.input.value.length * 15 + 20;
            this.resetInputHeight();
          },
    
          resetInputHeight() {
            this.$nextTick(() => {
              if (!this.$refs.reference) return;
              let inputChildNodes = this.$refs.reference.$el.childNodes;
              let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0];
              input.style.height = Math.max(this.$refs.tags.clientHeight + 6, sizeMap[this.size] || 36) + 'px';
              if (this.visible && this.emptyText !== false) {
                this.broadcast('ElSelectDropdown', 'updatePopper');
                  //multiple、noTag、filterable 同时存在时,判断当前下拉框是否在初始位置,不在则调整下拉框位置
                  if(this.multiple && this.noTag && this.filterable){
                      this.$nextTick(()=>{
                          var popperTop = window.getComputedStyle? window.getComputedStyle(this.$refs.popper.$el).top : this.$refs.popper.$el.currentStyle.top;
                          if(popperTop <= this.initPopperTop){
                              this.$refs.popper.$el.style.top = parseInt(popperTop)+ 25+'px';
                          }
                      })
                  }
              }
            });
          },
    
          resetHoverIndex() {
            setTimeout(() => {
              if (!this.multiple) {
                this.hoverIndex = this.options.indexOf(this.selected);
              } else {
                if (this.selected.length > 0) {
                  this.hoverIndex = Math.min.apply(null, this.selected.map(item => this.options.indexOf(item)));
                } else {
                  this.hoverIndex = -1;
                }
              }
            }, 300);
          },
    
          handleOptionSelect(option) {
            if (this.multiple) {
              const value = this.value.slice();
              const optionIndex = this.getValueIndex(value, option.value);
              if (optionIndex > -1) {
                  //multiple、allowCreate存在,复选时可以向下拉列表中删除数据
                  if(this.allowCreate && option.optcreated && this.noTag){
                      if(this.mulOptions && this.mulOptions.length){
                          this.mulOptions.forEach((item,index)=>{
                              if(item.currentValue == option.currentValue){
                                  this.mulOptions.splice(index, 1);
                              }
                          })
                      }
                  }
                value.splice(optionIndex, 1);
              } else if (this.multipleLimit <= 0 || value.length < this.multipleLimit) {
                value.push(option.value);
              }
              this.$emit('input', value);
              if (option.created) {
                 //multiple、allowCreate存在,复选时可以像下拉列表中添加数据
                 if(this.allowCreate && this.noTag && !option.optcreated){
                      var obj = {
                          optcreated:true,
                          created:option.created,
                          currentLabel:option.currentLabel,
                          currentValue:option.currentValue
                      }
                      this.mulOptions.push(obj);
                 }
                this.query = '';
                this.inputLength = 20;
              }
              if (this.filterable) this.$refs.input.focus();
            } else {
              this.$emit('input', option.value);
              this.visible = false;
            }
            this.$nextTick(() => this.scrollToOption());
          },
    
          getValueIndex(arr = [], value) {
            const type = typeof value;
            const isObject = type !== 'string' && type !== 'number' && type !== 'boolean';
            if (!isObject) {
              return arr.indexOf(value);
            } else {
              const valueKey = this.valueKey;
              let index = -1;
              arr.some((item, i) => {
                if (getValueByPath(item, valueKey) === getValueByPath(value, valueKey)) {
                  index = i;
                  return true;
                }
                return false;
              });
              return index;
            }
          },
    
          toggleMenu() {
            if (this.filterable && this.query === '' && this.visible) {
              return;
            }
            if (!this.disabled) {
              this.visible = !this.visible;
            }
          },
    
          navigateOptions(direction) {
            if (!this.visible) {
              this.visible = true;
              return;
            }
            if (this.options.length === 0 || this.filteredOptionsCount === 0) return;
            this.optionsAllDisabled = this.options.length === this.options.filter(item => item.disabled === true).length;
            if (!this.optionsAllDisabled) {
              if (direction === 'next') {
                this.hoverIndex++;
                if (this.hoverIndex === this.options.length) {
                  this.hoverIndex = 0;
                }
                if (this.options[this.hoverIndex].disabled === true ||
                  this.options[this.hoverIndex].groupDisabled === true ||
                  !this.options[this.hoverIndex].visible) {
                  this.navigateOptions('next');
                }
              }
              if (direction === 'prev') {
                this.hoverIndex--;
                if (this.hoverIndex < 0) {
                  this.hoverIndex = this.options.length - 1;
                }
                if (this.options[this.hoverIndex].disabled === true ||
                  this.options[this.hoverIndex].groupDisabled === true ||
                  !this.options[this.hoverIndex].visible) {
                  this.navigateOptions('prev');
                }
              }
            }
            this.$nextTick(() => this.scrollToOption('hover'));
          },
    
          selectOption() {
            if (this.options[this.hoverIndex]) {
              this.handleOptionSelect(this.options[this.hoverIndex]);
            }
          },
    
          deleteSelected(event) {
            event.stopPropagation();
            this.$emit('input', '');
            this.visible = false;
            this.$emit('clear');
          },
    
          deleteTag(event, tag) {
            let index = this.selected.indexOf(tag);
            if (index > -1 && !this.disabled) {
              const value = this.value.slice();
              value.splice(index, 1);
              this.$emit('input', value);
              this.$emit('remove-tag', tag);
            }
            event.stopPropagation();
          },
    
          onInputChange() {
            if (this.filterable) {
              this.query = this.selectedLabel;
            }
          },
    
          onOptionDestroy(option) {
            this.optionsCount--;
            this.filteredOptionsCount--;
            let index = this.options.indexOf(option);
            if (index > -1) {
              this.options.splice(index, 1);
            }
            this.broadcast('ElOption', 'resetIndex');
          },
    
          resetInputWidth() {
            this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
          },
    
          handleResize() {
            this.resetInputWidth();
            if (this.multiple) this.resetInputHeight();
          },
    
          checkDefaultFirstOption() {
            this.hoverIndex = -1;
            for (let i = 0; i !== this.options.length; ++i) {
              const option = this.options[i];
              if (this.query) {
                // pick first options that passes the filter
                if (!option.disabled && !option.groupDisabled && option.visible) {
                  this.hoverIndex = i;
                  break;
                }
              } else {
                // pick currently selected option
                if (option.itemSelected) {
                  this.hoverIndex = i;
                  break;
                }
              }
            }
          },
    
          getValueKey(item) {
            const type = typeof item.value;
            if (type === 'number' || type === 'string') {
              return item.value;
            } else {
              return getValueByPath(item.value, this.valueKey);
            }
          }
        },
    
        created() {
          this.cachedPlaceHolder = this.currentPlaceholder = this.placeholder;
          if (this.multiple && !Array.isArray(this.value)) {
            this.$emit('input', []);
          }
          if (!this.multiple && Array.isArray(this.value)) {
            this.$emit('input', '');
          }
          this.setSelected();
    
          this.debouncedOnInputChange = debounce(this.debounce, () => {
            this.onInputChange();
          });
    
          this.$on('handleOptionClick', this.handleOptionSelect);
          this.$on('onOptionDestroy', this.onOptionDestroy);
          this.$on('setSelected', this.setSelected);
        },
    
        mounted() {
          if (this.multiple && Array.isArray(this.value) && this.value.length > 0) {
            this.currentPlaceholder = '';
          }
          addResizeListener(this.$el, this.handleResize);
          if (this.remote && this.multiple) {
            this.resetInputHeight();
          }
          this.$nextTick(() => {
            if (this.$refs.reference && this.$refs.reference.$el) {
              this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
            }
          });
        },
    
        beforeDestroy() {
          if (this.$el && this.handleResize) removeResizeListener(this.$el, this.handleResize);
        }
      };
      // dialog_ref
    
    </script>
    
    
  • 相关阅读:
    PHP 使用 Redis
    Redis /etc/redis.conf 常用配置
    Redis 常用操作
    Redis 操作哈希数据
    Redis 操作有序集合数据
    Redis 操作集合数据
    Redis 操作列表数据
    Redis 操作字符串数据
    Redis 安装
    Redis 简介
  • 原文地址:https://www.cnblogs.com/fangnianqin/p/10345952.html
Copyright © 2011-2022 走看看