加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

element-ui select组件中复选时以字符串形式显示

发布时间:2020-12-16 23:26:35 所属栏目:百科 来源:网络整理
导读:我使用的element-ui的版本是1.4.13。 如上图所示,使用el-select组件,要实现可搜索、可复

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

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

(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;
    width: 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)多选时,可搜索。按照组件现在的,搜索框会在选项的下面出现,这样会撑开输入框的高度。

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

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

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

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

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

2、handleOptionSelect方法中处理数据

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

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

以下附源码:


<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','');
this.broadcast('ElOptionGroup','queryChange');
}
this.broadcast('ElInput','inputSelect');
}
}
}
this.$emit('visible-change',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-inputicon');
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,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 &amp;&amp; !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 &amp;&amp; this.emptyText !== false) {
        this.broadcast('ElSelectDropdown','updatePopper');
          //multiple、noTag、filterable 同时存在时,判断当前下拉框是否在初始位置,不在则调整下拉框位置
          if(this.multiple &amp;&amp; this.noTag &amp;&amp; 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 &amp;&amp; option.optcreated &amp;&amp; this.noTag){
              if(this.mulOptions &amp;&amp; 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 &amp;&amp; this.noTag &amp;&amp; !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' &amp;&amp; type !== 'number' &amp;&amp; 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 &amp;&amp; this.query === '' &amp;&amp; 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 &amp;&amp; !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 &amp;&amp; !option.groupDisabled &amp;&amp; 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 &amp;&amp; !Array.isArray(this.value)) {
    this.$emit('input',[]);
  }
  if (!this.multiple &amp;&amp; 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 &amp;&amp; Array.isArray(this.value) &amp;&amp; this.value.length > 0) {
    this.currentPlaceholder = '';
  }
  addResizeListener(this.$el,this.handleResize);
  if (this.remote &amp;&amp; this.multiple) {
    this.resetInputHeight();
  }
  this.$nextTick(() => {
    if (this.$refs.reference &amp;&amp; this.$refs.reference.$el) {
      this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
    }
  });
},beforeDestroy() {
  if (this.$el &amp;&amp; this.handleResize) removeResizeListener(this.$el,this.handleResize);
}

};
// dialog_ref

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读