index.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <template>
  2. <div class="selector">
  3. <div class="selector-field">
  4. <a-select
  5. :value="selVal"
  6. :mode="multiple === SELECT_MULTIPLE.MORE ? 'multiple' : undefined"
  7. style="width: 100%"
  8. placeholder="请选择"
  9. :open="false"
  10. :allow-clear="true"
  11. @change="handleChange"
  12. :disabled="disabled"
  13. :options="options"
  14. :max-tag-count="10"
  15. :showArrow="false"
  16. >
  17. <template #tagRender="{ value: val, label, closable, onClose, option }">
  18. <a-tag :closable="closable" style="margin-right: 3px" @close="closeTags(onClose, val, option, label)">
  19. {{ label }}
  20. </a-tag>
  21. </template>
  22. </a-select>
  23. <a-button @click="handleClkSelector">
  24. <template #icon>
  25. <UserOutlined />
  26. </template>
  27. </a-button>
  28. </div>
  29. <modal-selector
  30. ref="modalSelectorRef"
  31. :multiple="multiple"
  32. :selectedOldData="oldSelectedData"
  33. :id-key="idKey"
  34. :label-key="labelKey"
  35. @change="selectChange"
  36. @ok="confirm"
  37. :selected-data="selectedData"
  38. />
  39. </div>
  40. </template>
  41. <script setup>
  42. import { SELECT_MULTIPLE } from '/@/components/BsUi/constant.js';
  43. import ModalSelector from '/@/components/BsUi/OrgUserSelector/components/ModalSelector.vue';
  44. import { onMounted, ref, watch } from 'vue';
  45. import { isArray, isEmpty } from 'lodash';
  46. import { UserOutlined } from '@ant-design/icons-vue';
  47. const oldSelectedData = ref([]);
  48. const selVal = ref([]);
  49. const options = ref([]);
  50. const props = defineProps({
  51. selectedData: {
  52. required: true,
  53. default: undefined,
  54. },
  55. multiple: {
  56. required: false,
  57. default: SELECT_MULTIPLE.ONE,
  58. },
  59. disabled: {
  60. required: false,
  61. default: false,
  62. },
  63. idKey: {
  64. required: false,
  65. default: 'id',
  66. },
  67. labelKey: {
  68. required: false,
  69. default: 'name',
  70. },
  71. });
  72. const emit = defineEmits(['update:selectedData']);
  73. const modalSelectorRef = ref(null);
  74. const selectChange = (value) => {};
  75. const setOptions = (valObj) => {
  76. if (isArray(valObj)) {
  77. options.value = valObj.map((v) => ({
  78. label: v[props.labelKey],
  79. value: v[props.idKey],
  80. }));
  81. } else {
  82. options.value = [
  83. {
  84. label: valObj[props.labelKey],
  85. value: valObj[props.idKey],
  86. },
  87. ];
  88. }
  89. };
  90. const closeTags = (onClose, val, option, label) => {
  91. if (isArray(selVal.value)) {
  92. selVal.value = selVal.value.filter((v) => v !== val);
  93. } else {
  94. selVal.value = undefined;
  95. }
  96. const valObj = oldSelectedData.value.filter((v) => v[props.idKey] !== val);
  97. setOptions(valObj);
  98. emit('update:selectedData', valObj);
  99. };
  100. const handleChange = (value) => {
  101. if (isEmpty(value)) {
  102. selVal.value = undefined;
  103. emit('update:selectedData', []);
  104. }
  105. };
  106. const handleClkSelector = () => {
  107. if (props.disabled) {
  108. return;
  109. }
  110. modalSelectorRef.value.showModal();
  111. };
  112. const confirm = ({ selectedKeys, selectedData }) => {
  113. setOptions(selectedData);
  114. if (props.multiple === SELECT_MULTIPLE.ONE && selectedData.length === 1) {
  115. selVal.value = selectedKeys[0];
  116. emit('update:selectedData', selectedData[0]);
  117. } else {
  118. selVal.value = selectedKeys;
  119. emit('update:selectedData', selectedData);
  120. }
  121. };
  122. watch(
  123. () => props.selectedData,
  124. (val) => {
  125. setOptions(val);
  126. if (isEmpty(val)) {
  127. oldSelectedData.value = [];
  128. selVal.value = [];
  129. } else {
  130. oldSelectedData.value = isArray(val) ? val : [val];
  131. selVal.value = isArray(val) ? val.map((v) => v[props.idKey]) : val[props.idKey];
  132. }
  133. },
  134. { immediate: true }
  135. );
  136. </script>
  137. <style lang="scss" scoped>
  138. .selector {
  139. width: 100%;
  140. .selector-field {
  141. width: 100%;
  142. display: flex;
  143. }
  144. }
  145. </style>