UploaderField.vue 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. <template>
  2. <Uploader
  3. ref="uploaderRef"
  4. v-bind="props"
  5. :maxUploadCount="single ? 1 : maxUploadCount"
  6. @updateList="handleListChange"
  7. />
  8. </template>
  9. <script setup lang="ts">
  10. import { onMounted, ref, toRef } from 'vue';
  11. import { useFieldChildValueInjector } from './FormContext';
  12. import type { UploaderInstance, UploaderProps } from './Uploader.vue';
  13. import { stringUrlToUploaderItem, type UploaderItem } from './Uploader';
  14. import Uploader from './Uploader.vue';
  15. export interface UploaderFieldProps extends Omit<UploaderProps, 'value'> {
  16. modelValue?: string[]|string;
  17. single?: boolean;
  18. }
  19. const uploaderRef = ref<UploaderInstance>();
  20. const emit = defineEmits([ 'update:modelValue' ]);
  21. const props = withDefaults(defineProps<UploaderFieldProps>(), {
  22. modelValue: undefined,
  23. showDelete: true,
  24. showUpload: true,
  25. uploadWhenAdded: true,
  26. });
  27. const {
  28. value,
  29. updateValue,
  30. } = useFieldChildValueInjector(
  31. toRef(props, 'modelValue'),
  32. (v) => emit('update:modelValue', v),
  33. undefined,
  34. //() => { /*uploaderRef.value?.pick()*/ },
  35. );
  36. function handleListChange(list: UploaderItem[]) {
  37. updateValue(list.map((item) => item.uploadedPath).filter((item) => item) as string[]);
  38. }
  39. onMounted(() => {
  40. setTimeout(() => {
  41. uploaderRef.value?.setList(props.single || typeof value.value === 'string'
  42. ? (value.value ? [ stringUrlToUploaderItem(value.value as any as string) ] : [])
  43. : value.value?.map((item) => stringUrlToUploaderItem(item)) ?? []
  44. )
  45. }, 200);
  46. });
  47. defineExpose({
  48. getUploaderRef: () => uploaderRef.value,
  49. })
  50. export interface UploaderFieldInstance {
  51. getUploaderRef: () => UploaderInstance;
  52. }
  53. defineOptions({
  54. options: {
  55. styleIsolation: "shared",
  56. virtualHost: true,
  57. }
  58. })
  59. </script>