FileInput.vue 886 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. <template>
  2. <div class="file-input" @click="handleClick()">
  3. <slot></slot>
  4. <input
  5. class="input"
  6. type="file"
  7. name="upload"
  8. ref="inputRef"
  9. :accept="accept"
  10. @change="$event => handleChange($event)"
  11. @click.stop
  12. >
  13. </div>
  14. </template>
  15. <script lang="ts" setup>
  16. import { useTemplateRef } from 'vue'
  17. withDefaults(defineProps<{
  18. accept?: string
  19. }>(), {
  20. accept: 'image/*',
  21. })
  22. const emit = defineEmits<{
  23. (event: 'change', payload: FileList): void
  24. }>()
  25. const inputRef = useTemplateRef<HTMLInputElement>('inputRef')
  26. const handleClick = () => {
  27. if (!inputRef.value) return
  28. inputRef.value.value = ''
  29. inputRef.value.click()
  30. }
  31. const handleChange = (e: Event) => {
  32. const files = (e.target as HTMLInputElement).files
  33. if (files) emit('change', files)
  34. }
  35. </script>
  36. <style lang="scss" scoped>
  37. .input {
  38. display: none;
  39. }
  40. </style>