option.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <template>
  2. <li
  3. @mouseenter="hoverItem"
  4. @click.stop="selectOptionClick"
  5. class="el-select-dropdown__item"
  6. v-show="visible"
  7. :class="{
  8. 'selected': itemSelected,
  9. 'is-disabled': disabled || groupDisabled || limitReached,
  10. 'hover': hover
  11. }">
  12. <slot>
  13. <span>{{ currentLabel }}</span>
  14. </slot>
  15. </li>
  16. </template>
  17. <script type="text/babel">
  18. import Emitter from 'element-ui/src/mixins/emitter';
  19. import { getValueByPath, escapeRegexpString } from 'element-ui/src/utils/util';
  20. export default {
  21. mixins: [Emitter],
  22. name: 'ElOption',
  23. componentName: 'ElOption',
  24. inject: ['select'],
  25. props: {
  26. value: {
  27. required: true
  28. },
  29. label: [String, Number],
  30. created: Boolean,
  31. disabled: {
  32. type: Boolean,
  33. default: false
  34. }
  35. },
  36. data() {
  37. return {
  38. index: -1,
  39. groupDisabled: false,
  40. visible: true,
  41. hitState: false,
  42. hover: false
  43. };
  44. },
  45. computed: {
  46. isObject() {
  47. return Object.prototype.toString.call(this.value).toLowerCase() === '[object object]';
  48. },
  49. currentLabel() {
  50. return this.label || (this.isObject ? '' : this.value);
  51. },
  52. currentValue() {
  53. return this.value || this.label || '';
  54. },
  55. itemSelected() {
  56. if (!this.select.multiple) {
  57. return this.isEqual(this.value, this.select.value);
  58. } else {
  59. return this.contains(this.select.value, this.value);
  60. }
  61. },
  62. limitReached() {
  63. if (this.select.multiple) {
  64. return !this.itemSelected &&
  65. (this.select.value || []).length >= this.select.multipleLimit &&
  66. this.select.multipleLimit > 0;
  67. } else {
  68. return false;
  69. }
  70. }
  71. },
  72. watch: {
  73. currentLabel() {
  74. if (!this.created && !this.select.remote) this.dispatch('ElSelect', 'setSelected');
  75. },
  76. value(val, oldVal) {
  77. const { remote, valueKey } = this.select;
  78. if (!this.created && !remote) {
  79. if (valueKey && typeof val === 'object' && typeof oldVal === 'object' && val[valueKey] === oldVal[valueKey]) {
  80. return;
  81. }
  82. this.dispatch('ElSelect', 'setSelected');
  83. }
  84. }
  85. },
  86. methods: {
  87. isEqual(a, b) {
  88. if (!this.isObject) {
  89. return a === b;
  90. } else {
  91. const valueKey = this.select.valueKey;
  92. return getValueByPath(a, valueKey) === getValueByPath(b, valueKey);
  93. }
  94. },
  95. contains(arr = [], target) {
  96. if (!this.isObject) {
  97. return arr && arr.indexOf(target) > -1;
  98. } else {
  99. const valueKey = this.select.valueKey;
  100. return arr && arr.some(item => {
  101. return getValueByPath(item, valueKey) === getValueByPath(target, valueKey);
  102. });
  103. }
  104. },
  105. handleGroupDisabled(val) {
  106. this.groupDisabled = val;
  107. },
  108. hoverItem() {
  109. if (!this.disabled && !this.groupDisabled) {
  110. this.select.hoverIndex = this.select.options.indexOf(this);
  111. }
  112. },
  113. selectOptionClick() {
  114. if (this.disabled !== true && this.groupDisabled !== true) {
  115. this.dispatch('ElSelect', 'handleOptionClick', [this, true]);
  116. }
  117. },
  118. queryChange(query) {
  119. this.visible = new RegExp(escapeRegexpString(query), 'i').test(this.currentLabel) || this.created;
  120. if (!this.visible) {
  121. this.select.filteredOptionsCount--;
  122. }
  123. }
  124. },
  125. created() {
  126. this.select.options.push(this);
  127. this.select.cachedOptions.push(this);
  128. this.select.optionsCount++;
  129. this.select.filteredOptionsCount++;
  130. this.$on('queryChange', this.queryChange);
  131. this.$on('handleGroupDisabled', this.handleGroupDisabled);
  132. },
  133. beforeDestroy() {
  134. const { selected, multiple } = this.select;
  135. let selectedOptions = multiple ? selected : [selected];
  136. let index = this.select.cachedOptions.indexOf(this);
  137. let selectedIndex = selectedOptions.indexOf(this);
  138. // if option is not selected, remove it from cache
  139. if (index > -1 && selectedIndex < 0) {
  140. this.select.cachedOptions.splice(index, 1);
  141. }
  142. this.select.onOptionDestroy(this.select.options.indexOf(this));
  143. }
  144. };
  145. </script>