option.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <template>
  2. <li
  3. @mouseenter="hoverItem"
  4. @click.stop="selectOptionClick"
  5. class="el-select-dropdown__item"
  6. v-show="visible"
  7. :class="{ 'selected': itemSelected, 'is-disabled': disabled || groupDisabled, 'hover': parent.hoverIndex === index }">
  8. <slot>
  9. <span>{{ currentLabel }}</span>
  10. </slot>
  11. </li>
  12. </template>
  13. <script type="text/babel">
  14. import Emitter from 'element-ui/src/mixins/emitter';
  15. export default {
  16. mixins: [Emitter],
  17. name: 'el-option',
  18. componentName: 'option',
  19. props: {
  20. value: {
  21. required: true
  22. },
  23. label: [String, Number],
  24. selected: {
  25. type: Boolean,
  26. default: false
  27. },
  28. disabled: {
  29. type: Boolean,
  30. default: false
  31. }
  32. },
  33. data() {
  34. return {
  35. index: -1,
  36. groupDisabled: false,
  37. visible: true,
  38. hitState: false
  39. };
  40. },
  41. computed: {
  42. currentLabel() {
  43. return this.label || ((typeof this.value === 'string' || typeof this.value === 'number') ? this.value : '');
  44. },
  45. parent() {
  46. let result = this.$parent;
  47. while (!result.isSelect) {
  48. result = result.$parent;
  49. }
  50. return result;
  51. },
  52. itemSelected() {
  53. if (Object.prototype.toString.call(this.parent.selected) === '[object Object]') {
  54. return this === this.parent.selected;
  55. } else if (Array.isArray(this.parent.selected)) {
  56. return this.parent.value.indexOf(this.value) > -1;
  57. }
  58. },
  59. currentSelected() {
  60. return this.selected || (this.parent.multiple ? this.parent.value.indexOf(this.value) > -1 : this.parent.value === this.value);
  61. }
  62. },
  63. watch: {
  64. currentSelected(val) {
  65. if (val === true) {
  66. this.dispatch('select', 'addOptionToValue', this);
  67. }
  68. }
  69. },
  70. methods: {
  71. handleGroupDisabled(val) {
  72. this.groupDisabled = val;
  73. },
  74. hoverItem() {
  75. if (!this.disabled && !this.groupDisabled) {
  76. this.parent.hoverIndex = this.parent.options.indexOf(this);
  77. }
  78. },
  79. selectOptionClick() {
  80. if (this.disabled !== true && this.groupDisabled !== true) {
  81. this.dispatch('select', 'handleOptionClick', this);
  82. }
  83. },
  84. queryChange(query) {
  85. // query 里如果有正则中的特殊字符,需要先将这些字符转义
  86. let parsedQuery = query.replace(/(\^|\(|\)|\[|\]|\$|\*|\+|\.|\?|\\|\{|\}|\|)/g, '\\$1');
  87. this.visible = new RegExp(parsedQuery, 'i').test(this.currentLabel);
  88. if (!this.visible) {
  89. this.parent.filteredOptionsCount--;
  90. }
  91. },
  92. resetIndex() {
  93. this.$nextTick(() => {
  94. this.index = this.parent.options.indexOf(this);
  95. });
  96. }
  97. },
  98. created() {
  99. this.parent.options.push(this);
  100. this.parent.optionsCount++;
  101. this.parent.filteredOptionsCount++;
  102. this.index = this.parent.options.indexOf(this);
  103. if (this.currentSelected === true) {
  104. this.dispatch('select', 'addOptionToValue', [this, true]);
  105. }
  106. this.$on('queryChange', this.queryChange);
  107. this.$on('handleGroupDisabled', this.handleGroupDisabled);
  108. this.$on('resetIndex', this.resetIndex);
  109. },
  110. beforeDestroy() {
  111. this.dispatch('select', 'onOptionDestroy', this);
  112. }
  113. };
  114. </script>