使用 Composition API 制作文件上传组件 (vuejs3)

Making file upload component using Composition API (vuejs3)

我正在尝试在我的应用程序中全局使用 'file picker' 组件并获取 'imageUrl' base64 来操作服务器上的上传。

我的组件上有以下内容:

<template>
      <div class="column" style="width: 300px;">
        <q-btn @click="sendEventImage ()" style="margin-top: 16px; margin-bottom: 32px;" outline color="white" text-color="black" label="Procurar imagem" />
        <input style="display:none" ref="EventfileInput" @change="onEventFilePicked" type="file" name="upload" accept="image/*" />
        <q-img class="w-30 h-30" :src="imageUrl" />
      </div>
</template>

<script>

import { defineComponent, ref } from 'vue'

export default defineComponent({
  name: 'PageIndex',
  setup () {
    let imageUrl = ref('')
    let model = ref(null)
    return {
      sendEventImage () {
        console.log('sendEvent preview')
        this.$refs.EventfileInput.click()
      },
      onEventFilePicked (event) {
        const files = event.target.files
        let image = files[0]
        console.log(image)
        let filename = files[0].name
        if (filename.lastIndexOf('.') <= 0) {
          return alert('Por favor adicione um arquivo válido')
        }
        const fileReader = new FileReader()
        fileReader.addEventListener('load', (event) => {
          this.imageUrl = fileReader.result
          console.log('setimageUrl', this.imageUrl)
        })
        fileReader.readAsDataURL(files[0])
      },
      imageUrl,
      model
    }
  }
})
</script>

如何在我的应用程序的每个组件中使用此组件,并在我的设置 () 中获取“imageUrl”参数以使用此参数?

您必须 emit 一个事件,以便父组件可以对其作出反应: https://v3.vuejs.org/guide/composition-api-setup.html#accessing-component-properties

未测试:

<template>
      <div class="column" style="width: 300px;">
        <q-btn @click="sendEventImage ()" style="margin-top: 16px; margin-bottom: 32px;" outline color="white" text-color="black" label="Procurar imagem" />
        <input style="display:none" ref="EventfileInput" @change="onEventFilePicked" type="file" name="upload" accept="image/*" />
        <q-img class="w-30 h-30" :src="imageUrl" />
      </div>
</template>

<script>

import { defineComponent, ref } from 'vue'

export default defineComponent({
    name: 'FileUpload',
    emits: ['imageloaded'],
    setup (props, { emit }) {
        const imageUrl = ref('');
        const EventfileInput = ref(null);
          
        const onEventFilePicked = (event) => {
            const files = event.target.files
            const image = files[0]
            console.log(image)
            const filename = files[0].name
            if (filename.lastIndexOf('.') <= 0) {
              return alert('Por favor adicione um arquivo válido')
            }
            const fileReader = new FileReader()
            fileReader.addEventListener('load', (event) => {
              imageUrl.value = fileReader.result
              console.log('setimageUrl', imageUrl.value)
              emit('imageloaded',imageUrl.value);
            })
            fileReader.readAsDataURL(files[0])
        };
        const sendEventImage = () => {
            console.log('sendEvent preview')
            EventfileInput.click()
        };
        return {
            imageUrl,
            sendEventImage,
            onEventFilePicked
        }
    }
})
</script>

关于我在示例中更改的代码的几点说明: