index.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. {{ selectedData }}
  29. </div>
  30. <modal-selector
  31. ref="modalSelectorRef"
  32. :multiple="multiple"
  33. :selectedOldData="oldSelectedData"
  34. :id-key="idKey"
  35. :label-key="labelKey"
  36. @change="selectChange"
  37. @ok="confirm"
  38. :selected-data="selectedData"
  39. />
  40. </div>
  41. </template>
  42. <script setup>
  43. import { SELECT_MULTIPLE } from '/@/components/BsUi/constant.js';
  44. import ModalSelector from '/@/components/BsUi/OrgUserSelector/components/ModalSelector.vue';
  45. import { onMounted, ref, watch } from 'vue';
  46. import { isArray, isEmpty } from 'lodash';
  47. import { UserOutlined } from '@ant-design/icons-vue';
  48. const oldSelectedData = ref([]);
  49. const selVal = ref([]);
  50. const options = ref([]);
  51. const props = defineProps({
  52. selectedData: {
  53. required: true,
  54. default: undefined,
  55. },
  56. multiple: {
  57. required: false,
  58. default: SELECT_MULTIPLE.ONE,
  59. },
  60. disabled: {
  61. required: false,
  62. default: false,
  63. },
  64. idKey: {
  65. required: false,
  66. default: 'id',
  67. },
  68. labelKey: {
  69. required: false,
  70. default: 'name',
  71. },
  72. });
  73. const emit = defineEmits(['update:selectedData']);
  74. const modalSelectorRef = ref(null);
  75. const selectChange = (value) => {};
  76. const setOptions = (valObj) => {
  77. if (isArray(valObj)) {
  78. options.value = valObj.map((v) => ({
  79. label: v[props.labelKey],
  80. value: v[props.idKey],
  81. }));
  82. } else {
  83. options.value = [
  84. {
  85. label: valObj[props.labelKey],
  86. value: valObj[props.idKey],
  87. },
  88. ];
  89. }
  90. };
  91. const closeTags = (onClose, val, option, label) => {
  92. if (isArray(selVal.value)) {
  93. selVal.value = selVal.value.filter((v) => v !== val);
  94. } else {
  95. selVal.value = undefined;
  96. }
  97. const valObj = oldSelectedData.value.filter((v) => v[props.idKey] !== val);
  98. setOptions(valObj);
  99. emit('update:selectedData', valObj);
  100. };
  101. const handleChange = (value) => {
  102. if (isEmpty(value)) {
  103. selVal.value = undefined;
  104. emit('update:selectedData', []);
  105. }
  106. };
  107. const handleClkSelector = () => {
  108. if (props.disabled) {
  109. return;
  110. }
  111. modalSelectorRef.value.showModal();
  112. };
  113. const confirm = ({ selectedKeys, selectedData }) => {
  114. setOptions(selectedData);
  115. if (props.multiple === SELECT_MULTIPLE.ONE && selectedData.length === 1) {
  116. selVal.value = selectedKeys[0];
  117. emit('update:selectedData', selectedData[0]);
  118. } else {
  119. selVal.value = selectedKeys;
  120. emit('update:selectedData', selectedData);
  121. }
  122. };
  123. watch(
  124. () => props.selectedData,
  125. (val) => {
  126. setOptions(val);
  127. if (isEmpty(val)) {
  128. oldSelectedData.value = [];
  129. selVal.value = [];
  130. } else {
  131. oldSelectedData.value = isArray(val) ? val : [val];
  132. selVal.value = isArray(val) ? val.map((v) => v[props.idKey]) : val[props.idKey];
  133. }
  134. },
  135. { immediate: true }
  136. );
  137. </script>
  138. <style lang="scss" scoped>
  139. .selector {
  140. width: 100%;
  141. .selector-field {
  142. width: 100%;
  143. display: flex;
  144. }
  145. }
  146. </style>