如何在 vue.js 版本 3 中上传文件

Suk*_*and 14 typescript vue.js vuejs3

我想使用 vue.js 版本 3 上传文件。

我可以导入ref,但不确定如何使用它来获取文件数据?

文件上传测试.vue

<template>
<h1>File Upload</h1>
<div class="container">
    <div>
      <label>File
        <input type="file" id="file" ref="file" v-on:change="onChangeFileUpload()"/>
      </label>
        <button v-on:click="submitForm()">Upload</button>
    </div>
  </div>
</template>

<script src="./FileUploadTest.ts" lang="ts"></script>
Run Code Online (Sandbox Code Playgroud)

文件上传测试.ts

import { Options, Vue } from "vue-class-component";
import { ref } from 'vue';
import axios from "../../axios/index";

@Options({})
export default class FileUploadTest extends Vue {

    protected file: any;

    submitForm() {
        const formData = new FormData();
        formData.append('bytes', this.file);

        axios.post('https://localhost:44313/api/app/file/save',
            formData,
            {
                headers: {
                    'Content-Type': 'multipart/form-data'
                }
            }
        ).then(function (data) {
            console.log(data.data);
        })
        .catch(function () {
            console.log('FAILURE!!');
        });
    }

    onChangeFileUpload() {
        debugger;
        this.file = ref(["file"]).value; 
    }
};
Run Code Online (Sandbox Code Playgroud)

实际的文件内容没有存储在 this.file 变量中

this.file = ref(["file"]).value; 
Run Code Online (Sandbox Code Playgroud)

Suk*_*and 19

我可以将答案总结如下。

文件上传.vue

<template>
  <div>
    <input
      type="file"
      @change="onFileChanged($event)"
      accept="image/*"
      capture
    />
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)

文件上传.ts

import { defineComponent, ref } from "vue";

export default defineComponent({

    name: "FileUpload",

    setup() {
        const file = ref<File | null>();
        const form = ref<HTMLFormElement>();

        function onFileChanged($event: Event) {
            const target = $event.target as HTMLInputElement;
            if (target && target.files) {
                file.value = target.files[0];
            }
        }

        async function saveImage() {
            if (file.value) {
                try {
                // save file.value
                } catch (error) {
                    console.error(error);
                    form.value?.reset();
                    file.value = null;
                } finally {
                }
            }
        };

        return {
            saveImage,
            onFileChanged,
        }
    }
});
Run Code Online (Sandbox Code Playgroud)


Muh*_*zad 14

Vue3.js使用composition api上传文件到服务器

<template>
      <input ref="file" v-on:change="handleFileUpload()"  type="file">
</template>
<script>

import { ref} from "vue"

export default{
    name:'Add',

    setup() {
        const file = ref(null)

        const handleFileUpload = async() => {
           // debugger;
            console.log("selected file",file.value.files)
            //Upload to server
        }

        return {
          handleFileUpload,
          file
       }
    }
}

</script>
Run Code Online (Sandbox Code Playgroud)

  • @NavidShad 这不适用于组合 API。您需要使用 ref,然后访问该 ref。例如 `const fileInput = ref()` 和 `fileInput.value.files` (2认同)

Rob*_*Rob 6

这是一个简单的组件,您可以使用 options api 来上传文件。不需要ref

文件上传.vue

<template>
    <input type="file" @change="onChange($event)">
</template>

<script>
export default {
    props: ['modelValue'],
    methods: {
        onChange(event) {
            this.$emit('update:modelValue', event.target.files[0]);
        },
    },
};
</script>
Run Code Online (Sandbox Code Playgroud)

你的组件...

<template>
    <form novalidate @submit.prevent="onSubmit">
        <file-upload v-model="form.file"></file-upload>
    </form>
</template>

<script>
import fileUpload from 'fileUpload';
export default {
    components: { fileUpload },
    data: () => ({ form: { file: null } }),
    methods: {
        onSubmit() {
            console.log(this.form);
            // post the form to the server
        }
    }
}
</script>
Run Code Online (Sandbox Code Playgroud)


Gas*_*ass 6

使用最新语法的 2023 方法

<script setup lang="ts">在 Vuejs 3 中使用组合 API。lang="ts"指定语言是 TypeScript 而不是 JavaScript。

<template>
    <main>
        <input ref="fileInput" type="file" @change="handleFileChange" />
        <button @click="doSomething">do something</button>
    </main>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const fileInput = ref<HTMLInputElement | null>(null)
const files = ref()

function handleFileChange() {
    files.value = fileInput.value?.files
}

function doSomething() {
    const file = files.value[0]
    console.log(file)
    // and do other things...
}
</script>

Run Code Online (Sandbox Code Playgroud)

究竟发生了什么?

ref是一个特殊的属性,允许我们获取对 DOM 元素或子元素的引用。

要访问ref模板中的 a,我们需要ref在脚本中声明具有相同名称的aconst fileInput = ref<HTMLInputElement | null>(null);

files变量是一个可以包含多个文件的对象。要访问第一个或唯一的文件,我们可以像这样访问它:const file = files.value[0]这将提取第一个文件对象files,然后您就可以根据需要使用该文件了。

您可能想获取名称:

file.name
Run Code Online (Sandbox Code Playgroud)

或者扩展名:

file.name.split('.').pop();
Run Code Online (Sandbox Code Playgroud)

或者不带扩展名的名称:

file.name.substring(0, file.name.lastIndexOf('.'))
Run Code Online (Sandbox Code Playgroud)