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

Posted

技术标签:

【中文标题】使用 Composition API (vuejs3) 制作文件上传组件【英文标题】:Making file upload component using Composition API (vuejs3) 【发布时间】:2021-12-16 13:59:00 【问题描述】:

我正在尝试在我的应用程序上全局使用“文件选择器”组件并获取“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>

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

【问题讨论】:

【参考方案1】:

您必须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>

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

不要在setup() 中使用this 我建议对引用使用const,以防止意外覆盖它们并失去响应性。 您可以像普通参考一样定义模板参考: https://v3.vuejs.org/guide/composition-api-template-refs.html#template-refs

【讨论】:

好的,我放了一个“发射”,但我怎样才能在我的父亲组件上获得这个“发射值”?在我的应用程序中,我结束了使用存储变量,但似乎更好地将这些信息保留在组件上。 你可以在组件上添加@imageloaded="someHandler"并实现这个处理程序:v3.vuejs.org/guide/component-custom-events.html

以上是关于使用 Composition API (vuejs3) 制作文件上传组件的主要内容,如果未能解决你的问题,请参考以下文章

VueJS v3、Vuex 和 Composition API 以及输入字段上的 v-model

如何正确重置 Vue Composition Api 反应值

vue3常用 Composition API

Vue 3 Composition API 提供/注入在单个文件组件中不起作用

JEST @vue/composition-api + Jest 测试套件无法运行 [vue-composition-api] 在使用任何函数之前必须调用 Vue.use(VueComposition

在 uni-app 中使用 composition-api 组合API开发