Vuejs文件上传字段无法重置

发布于 2025-01-23 09:22:05 字数 8713 浏览 3 评论 0原文

在我的VUEJS应用程序中,我有一种模式,可以将一些用户数据插入文件上传。

当用户成功上传任何内容时,我应该能够清除所有表单字段。

我所有的字段都将重置除了文件上传字段。

它将保持原样。

在我的form.vue中,对于文件上传

<div class="mb-1">
            <dashboard-input-label
              identifier="document"
              :settings="{ help: true, helpDirection: 'left' }"
            >
              Upload document
              <template slot="helpText">
                Maximum filesize is 5 MB. The default allowed file extensions
                are: pdf, jpeg and png.
              </template>
            </dashboard-input-label>
            <validator-v2
              :identifier="identifier"
              name="document_file"
              :rules="{ required: { message: 'Document is required.' } }"
            >
              <custom-file-upload
                ref="documentDocument"
                v-model="documentFile"
                :max-upload-file-size="5"
                name="document_file"
              ></custom-file-upload>
            </validator-v2>
          </div>

和关注我的按钮

<loading-button ref="submitBtn" size="normal">
              Save & Add new
            </loading-button> 

,这是我的submitbtn方法,

storeDocumentAndAddNew() {
      this.isAddNew = true
      const loader = this.$refs.submitBtn
      this.storeDocument(loader)
    },

对于字段重置,我进行了遵循,

reset() {
      this.documentName= null
      this.dateOfIssue= null
      this.expiryDate= null
      this.documentNumber = null
      this.doesNotHaveDocumentNumber = false
      this.doesNotExpire = false
      this.documentFile = null
      this.doesOptIn = false
      this.isAddNew = false
      this.documentFile = ''
      this.$refs.documentDocument.value = null
    },

一旦我击中提交,每个字段都会重置除此之外。文件上传字段。

以下是我的自定义file-upload.vue组件

<template>
    <div>

        <div class="flex items-center flex-wrap">

            <div @click="selectFile" class="flex items-center cursor-pointer w-full form-input custom-file-upload ">

                <p class="flex justify-between items-center w-full overflow-hidden">
                    <span class="font-regular text-base flex items-center justify-center">
                        <span v-if="filename !== null">{{ filename | limitString }} </span>
                        <span class="cs--file-upload-current-file overflow-hidden inline-block" v-else><slot
                            name="currentFile"></slot></span>
                    </span>

                    <span class="text-certstyle-text-light ">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
                             stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
                             class="feather feather-upload"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline
                            points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
                    </span>

                </p>

                <input @change="showFileName" ref="fileInput" type="file" :name="name">
                <div class="flex flex-col fixed top-0 right-0 z-50">
                    <toastr-alert @hidden="resetToastrMessage" v-if="message !== ''" :message="message"
                                  :type="type"></toastr-alert>
                </div>
            </div>
        </div>

    </div>

</template> 

,即使我使用过,this。$ refs.documentDocument.value = null它没有清除我的文件上传字段。 ...

更新

我已经使用了 @wendt88的 答案,然后删除了文件。但是先前已上传的文档名称将保留在此处。例如,如果我尝试上传一个名为dummy.pdf的文档,即使在成功提交后,它也会显示dummy.pdf文本...

现在我的重置看起来喜欢这个,

reset() {
      this.documentName= null
      this.dateOfIssue= null
      this.expiryDate= null
      this.documentNumber = null
      this.doesNotHaveDocumentNumber = false
      this.doesNotExpire = false
      this.documentFile = null
      this.doesOptIn = false
      this.isAddNew = false
      this.$refs.documentDocument.$refs.fileInput.value = null
    },

以下是我的完整custom-file-upload.vue

<template>
    <div>

        <div class="flex items-center flex-wrap">

            <div @click="selectFile" class="flex items-center cursor-pointer w-full form-input custom-file-upload ">

                <p class="flex justify-between items-center w-full overflow-hidden">
                    <span class="font-regular text-base flex items-center justify-center">
                        <span v-if="filename !== null">{{ filename | limitString }} </span>
                        <span class="cs--file-upload-current-file overflow-hidden inline-block" v-else><slot
                            name="currentFile"></slot></span>
                    </span>

                    <span class="text-certstyle-text-light ">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
                             stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
                             class="feather feather-upload"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline
                            points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
                    </span>

                </p>

                <input @change="showFileName" ref="fileInput" type="file" :name="name">
                <div class="flex flex-col fixed top-0 right-0 z-50">
                    <toastr-alert @hidden="resetToastrMessage" v-if="message !== ''" :message="message"
                                  :type="type"></toastr-alert>
                </div>
            </div>
        </div>

    </div>

</template>
<style lang="scss" scoped>
.custom-file-upload input {
    position: absolute;
    cursor: pointer;
    height: 0;
    width: 0;
    opacity: 0;
}

.cs--file-upload-current-file {
    max-width: 220px;
}

label {
    font-weight: 400 !important;
}


</style>
<script>
// Mixins
import HasToastrMessage from '@/Mixins/HasToastrMessage.js';

// Helper
import Helper from '@/Support/Helper.js';

export default {
    mixins: [HasToastrMessage],
    props: ['name', 'value', 'maxUploadFileSize'],

    data() {
        return {
            file: null,
            filename: null,
            message: "",
            type: "",
            fileSize: 0,
            maxFileSize: 10,
            validFileTypes: [
                'application/pdf',
                'image/jpeg',
                'image/png'
            ]
        }
    },

    mounted() {
        if (Helper.isset(this.maxUploadFileSize)) {
            this.maxFileSize = this.maxUploadFileSize;
        }
    },

    methods: {


        showFileName(e) {
            this.filename = collect(e.target.value.split('\\')).last();
            let file = e.target.files[0];
            let fileSize = file.size / 1000000;

            if (fileSize > this.maxFileSize) {
                this.showToastrErrorMessage(`The uploaded file is too big. Max size: ${this.maxFileSize} MB.`);
                this.$refs.fileInput.value = null
                this.filename = null
            } else if (!this.validFileTypes.includes(file.type)) {
                this.showToastrErrorMessage(`The uploaded file is invalid. Please upload valid type.`);
                this.$refs.fileInput.value = null
                this.filename = null
            } else if (this.filename) {
                this.file = file
                this.showToastrSuccessMessage(`Your file is successfully uploaded.`);
                this.$emit('uploaded')
            } else {
                this.showToastrErrorMessage(`Your file could not be uploaded. Please try again.`);
            }
        },

        resetToastrMessage() {
            this.message = "";
            this.type = "";
        },

        selectFile() {
            this.$refs.fileInput.click();
        },
    }

}

</script>

In my vuejs application, I have a modal to insert some user data with a file upload.

I should be able to clear all the form fields once when an user successfully upload any content.

All my fields get reset apart from the file upload field.

It will remained as it is.

Inside my form.vue, for the file upload I have

<div class="mb-1">
            <dashboard-input-label
              identifier="document"
              :settings="{ help: true, helpDirection: 'left' }"
            >
              Upload document
              <template slot="helpText">
                Maximum filesize is 5 MB. The default allowed file extensions
                are: pdf, jpeg and png.
              </template>
            </dashboard-input-label>
            <validator-v2
              :identifier="identifier"
              name="document_file"
              :rules="{ required: { message: 'Document is required.' } }"
            >
              <custom-file-upload
                ref="documentDocument"
                v-model="documentFile"
                :max-upload-file-size="5"
                name="document_file"
              ></custom-file-upload>
            </validator-v2>
          </div>

and following is my button

<loading-button ref="submitBtn" size="normal">
              Save & Add new
            </loading-button> 

This is my submitBtn method,

storeDocumentAndAddNew() {
      this.isAddNew = true
      const loader = this.$refs.submitBtn
      this.storeDocument(loader)
    },

And for the field reset I have followings,

reset() {
      this.documentName= null
      this.dateOfIssue= null
      this.expiryDate= null
      this.documentNumber = null
      this.doesNotHaveDocumentNumber = false
      this.doesNotExpire = false
      this.documentFile = null
      this.doesOptIn = false
      this.isAddNew = false
      this.documentFile = ''
      this.$refs.documentDocument.value = null
    },

Once I hit submit, every field get reset except this file upload field.

Following is my custom-file-upload.vue component

<template>
    <div>

        <div class="flex items-center flex-wrap">

            <div @click="selectFile" class="flex items-center cursor-pointer w-full form-input custom-file-upload ">

                <p class="flex justify-between items-center w-full overflow-hidden">
                    <span class="font-regular text-base flex items-center justify-center">
                        <span v-if="filename !== null">{{ filename | limitString }} </span>
                        <span class="cs--file-upload-current-file overflow-hidden inline-block" v-else><slot
                            name="currentFile"></slot></span>
                    </span>

                    <span class="text-certstyle-text-light ">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
                             stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
                             class="feather feather-upload"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline
                            points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
                    </span>

                </p>

                <input @change="showFileName" ref="fileInput" type="file" :name="name">
                <div class="flex flex-col fixed top-0 right-0 z-50">
                    <toastr-alert @hidden="resetToastrMessage" v-if="message !== ''" :message="message"
                                  :type="type"></toastr-alert>
                </div>
            </div>
        </div>

    </div>

</template> 

Even though I've used, this.$refs.documentDocument.value = null it's not clearing my file upload field....

Update

I have used @wendt88's answer and then the file is removed. But the previously uploaded, document's name will be remained there as it is..As an example, if I tried to upload a document called, dummy.pdf, it'll show the dummy.pdf text even after a successful submission...

Now my reset looks likes this,

reset() {
      this.documentName= null
      this.dateOfIssue= null
      this.expiryDate= null
      this.documentNumber = null
      this.doesNotHaveDocumentNumber = false
      this.doesNotExpire = false
      this.documentFile = null
      this.doesOptIn = false
      this.isAddNew = false
      this.$refs.documentDocument.$refs.fileInput.value = null
    },

Following is my complete custom-file-upload.vue

<template>
    <div>

        <div class="flex items-center flex-wrap">

            <div @click="selectFile" class="flex items-center cursor-pointer w-full form-input custom-file-upload ">

                <p class="flex justify-between items-center w-full overflow-hidden">
                    <span class="font-regular text-base flex items-center justify-center">
                        <span v-if="filename !== null">{{ filename | limitString }} </span>
                        <span class="cs--file-upload-current-file overflow-hidden inline-block" v-else><slot
                            name="currentFile"></slot></span>
                    </span>

                    <span class="text-certstyle-text-light ">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
                             stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
                             class="feather feather-upload"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline
                            points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
                    </span>

                </p>

                <input @change="showFileName" ref="fileInput" type="file" :name="name">
                <div class="flex flex-col fixed top-0 right-0 z-50">
                    <toastr-alert @hidden="resetToastrMessage" v-if="message !== ''" :message="message"
                                  :type="type"></toastr-alert>
                </div>
            </div>
        </div>

    </div>

</template>
<style lang="scss" scoped>
.custom-file-upload input {
    position: absolute;
    cursor: pointer;
    height: 0;
    width: 0;
    opacity: 0;
}

.cs--file-upload-current-file {
    max-width: 220px;
}

label {
    font-weight: 400 !important;
}


</style>
<script>
// Mixins
import HasToastrMessage from '@/Mixins/HasToastrMessage.js';

// Helper
import Helper from '@/Support/Helper.js';

export default {
    mixins: [HasToastrMessage],
    props: ['name', 'value', 'maxUploadFileSize'],

    data() {
        return {
            file: null,
            filename: null,
            message: "",
            type: "",
            fileSize: 0,
            maxFileSize: 10,
            validFileTypes: [
                'application/pdf',
                'image/jpeg',
                'image/png'
            ]
        }
    },

    mounted() {
        if (Helper.isset(this.maxUploadFileSize)) {
            this.maxFileSize = this.maxUploadFileSize;
        }
    },

    methods: {


        showFileName(e) {
            this.filename = collect(e.target.value.split('\\')).last();
            let file = e.target.files[0];
            let fileSize = file.size / 1000000;

            if (fileSize > this.maxFileSize) {
                this.showToastrErrorMessage(`The uploaded file is too big. Max size: ${this.maxFileSize} MB.`);
                this.$refs.fileInput.value = null
                this.filename = null
            } else if (!this.validFileTypes.includes(file.type)) {
                this.showToastrErrorMessage(`The uploaded file is invalid. Please upload valid type.`);
                this.$refs.fileInput.value = null
                this.filename = null
            } else if (this.filename) {
                this.file = file
                this.showToastrSuccessMessage(`Your file is successfully uploaded.`);
                this.$emit('uploaded')
            } else {
                this.showToastrErrorMessage(`Your file could not be uploaded. Please try again.`);
            }
        },

        resetToastrMessage() {
            this.message = "";
            this.type = "";
        },

        selectFile() {
            this.$refs.fileInput.click();
        },
    }

}

</script>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

季末如歌 2025-01-30 09:22:05

this。$ refs.documentDocument是一个vue组件,可以清除其值的属性属性使用this。$ set。 > - &gt; https://v2.vuejs.org/v2/guide/guide/Reactivity.reactivity.html
否则,document document不知道您已经更改了其值

,但是如果要清除文件输入值,请运行( https:// https:// https:/// stackoverflow.com/a/16222877/1826106 ):

this.$refs.documentDocument.$refs.fileInput.value = null;
this.$set(this.$refs.documentDocument, 'filename', null);

this.$refs.documentDocument is a vue component, to clear it´s value property use this.$set(this.$refs.documentDocument, 'value', null) -> https://v2.vuejs.org/v2/guide/reactivity.html
otherwise documentDocument does not know that you have changed it´s value

but if you want to clear the file input value, run (https://stackoverflow.com/a/16222877/1826106):

this.$refs.documentDocument.$refs.fileInput.value = null;
this.$set(this.$refs.documentDocument, 'filename', null);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文