<template> <li @mouseenter="hoverItem" @click.stop="selectOptionClick" class="el-select-dropdown__item" v-show="visible" :class="{ 'selected': itemSelected, 'is-disabled': disabled || groupDisabled || limitReached, 'hover': hover }"> <slot> <span>{{ currentLabel }}</span> </slot> </li> </template> <script type="text/babel"> import Emitter from 'element-ui/src/mixins/emitter'; import { getValueByPath, escapeRegexpString } from 'element-ui/src/utils/util'; export default { mixins: [Emitter], name: 'ElOption', componentName: 'ElOption', inject: ['select'], props: { value: { required: true }, label: [String, Number], created: Boolean, disabled: { type: Boolean, default: false } }, data() { return { index: -1, groupDisabled: false, visible: true, hitState: false, hover: false }; }, computed: { isObject() { return Object.prototype.toString.call(this.value).toLowerCase() === '[object object]'; }, currentLabel() { return this.label || (this.isObject ? '' : this.value); }, currentValue() { return this.value || this.label || ''; }, itemSelected() { if (!this.select.multiple) { return this.isEqual(this.value, this.select.value); } else { return this.contains(this.select.value, this.value); } }, limitReached() { if (this.select.multiple) { return !this.itemSelected && (this.select.value || []).length >= this.select.multipleLimit && this.select.multipleLimit > 0; } else { return false; } } }, watch: { currentLabel() { if (!this.created && !this.select.remote) this.dispatch('ElSelect', 'setSelected'); }, value(val, oldVal) { const { remote, valueKey } = this.select; if (!this.created && !remote) { if (valueKey && typeof val === 'object' && typeof oldVal === 'object' && val[valueKey] === oldVal[valueKey]) { return; } this.dispatch('ElSelect', 'setSelected'); } } }, methods: { isEqual(a, b) { if (!this.isObject) { return a === b; } else { const valueKey = this.select.valueKey; return getValueByPath(a, valueKey) === getValueByPath(b, valueKey); } }, contains(arr = [], target) { if (!this.isObject) { return arr && arr.indexOf(target) > -1; } else { const valueKey = this.select.valueKey; return arr && arr.some(item => { return getValueByPath(item, valueKey) === getValueByPath(target, valueKey); }); } }, handleGroupDisabled(val) { this.groupDisabled = val; }, hoverItem() { if (!this.disabled && !this.groupDisabled) { this.select.hoverIndex = this.select.options.indexOf(this); } }, selectOptionClick() { if (this.disabled !== true && this.groupDisabled !== true) { this.dispatch('ElSelect', 'handleOptionClick', [this, true]); } }, queryChange(query) { this.visible = new RegExp(escapeRegexpString(query), 'i').test(this.currentLabel) || this.created; if (!this.visible) { this.select.filteredOptionsCount--; } } }, created() { this.select.options.push(this); this.select.cachedOptions.push(this); this.select.optionsCount++; this.select.filteredOptionsCount++; this.$on('queryChange', this.queryChange); this.$on('handleGroupDisabled', this.handleGroupDisabled); }, beforeDestroy() { const { selected, multiple } = this.select; let selectedOptions = multiple ? selected : [selected]; let index = this.select.cachedOptions.indexOf(this); let selectedIndex = selectedOptions.indexOf(this); // if option is not selected, remove it from cache if (index > -1 && selectedIndex < 0) { this.select.cachedOptions.splice(index, 1); } this.select.onOptionDestroy(this.select.options.indexOf(this)); } }; </script>