【问题标题】:How to bypass a input file when is not uploaded in VueJS/Axios未在 VueJS/Axios 中上传时如何绕过输入文件
【发布时间】:2021-07-04 00:18:05
【问题描述】:

我正在制作一个 VueJS 博客;我正在使用更新页面,除了输入文件字段外,一切正常:它仅在您上传文件时才有效,如果您不上传,控制台会返回此错误:

未捕获的类型错误:无法在“FormData”上执行“附加”: 参数 2 不是“Blob”类型。

否则,我尝试使用变量和布尔字段创建一个 if 状态,但是这样图像永远不会上传(但它不会在控制台中给出任何错误,并且如果您不上传它会使表单工作一个图像)。我将在带有和不带有 if 语句的代码下方放置。后端由 Django 和 Django Rest 框架组成。

不带 If 语句的 VueJS(第一个示例)

<template>
    <main>
        <SideBar></SideBar>
        <section>
            <h3>Edit {{ form.title }}</h3>
            <form @submit.prevent = "onSubmit" enctype="multipart/form-data">
                <input type="text" name="title" placeholder="Titolo" v-model="form.title">
                <input type="text" name="category" v-model="form.category">
                <textarea type="text" name="desc" placeholder="Descrizione" v-model="form.desc"> </textarea>
                <textarea name="text" v-model="form.text"></textarea>
                <input type="file" name="image" @change="EditImage">
                <input type="text" name="author" v-model="form.author">
                <input type="text" name="author" v-model="form.slug">
                <button type="submit">Edit</button>
            </form>
        </section>
    </main>
</template>
<script>
import axios from 'axios';
import { getAPI } from '../api'
import SideBar from '../components/Admin/Sidebar.vue';
import swal from 'sweetalert'
export default {
    components: { 
        'SideBar': SideBar
    },
    data () {
        return{
            Postslug: this.$route.params.Postslug,
            form: {
                title:"",
                desc:"",
                text:"",
                category:"",
                date:"",
                author:"",
                image:"",
                slug:"",
            },
        }
    },
    methods: {
        EditImage(event){
            this.form.image = event.target.files[0]
        },
        // Form method
        onSubmit(event, imageSelection){
            console.log(imageSelection);
            const fd = new FormData();

            fd.append('title', this.form.title)
            fd.append('desc', this.form.desc)
            fd.append('text', this.form.text)
            fd.append('category', this.form.category)
            fd.append('date', this.form.date)
            fd.append('author', this.form.author)
            fd.append('image', this.form.image, this.form.image.name)   
            fd.append('slug', this.form.slug)

            // event.preventDefault();     
            axios.patch(`http://127.0.0.1:8000/blog/api/edit/${this.Postslug}`, fd).then(response => {
              this.form.title = response.data.title
              this.form.desc = response.data.desc
              this.form.text = response.data.text
              this.form.image = response.data.image
              this.form.category = response.data.category
              this.form.author = response.data.author
              this.form.slug = response.data.slug
              
              this.$router.push({ name: 'AdminEditArticle', params: {Postslug: this.form.slug } });
              
              swal("Articolo editato", "", "success")
              .then(() => {
                  window.location.reload()
                })
                .catch(() => {
                    swal("Problema", "", "warning")
                });
              })

            .catch(err => {
            })
        },
    },
    
    created() {
        getAPI.get(`blog/api/edit/${this.Postslug}`)
            .then(response => {
              this.form.title = response.data.title
              this.form.desc = response.data.desc
              this.form.text = response.data.text
              this.form.date = response.data.date
              this.form.image = response.data.image
              this.form.category = response.data.category
              this.form.author = response.data.author
              this.form.slug = response.data.slug
            })
            .catch(err => {
              console.log(err)
            })
        },
    name: 'AdminEditArticle',
}

</script>
<style lang="sass" scoped>
stuff...
</style>

带有 if 语句的代码(第二个示例)

<template>
    <main>
        <SideBar></SideBar>
        <section>
            <h3>Edit {{ form.title }}</h3>
            <form @submit.prevent = "onSubmit" enctype="multipart/form-data">
                <input type="text" name="title" placeholder="Titolo" v-model="form.title">
                <input type="text" name="category" v-model="form.category">
                <textarea type="text" name="desc" placeholder="Descrizione" v-model="form.desc"> </textarea>
                <textarea name="text" v-model="form.text"></textarea>
                <input type="file" name="image" @change="EditImage">
                <input type="text" name="author" v-model="form.author">
                <input type="text" name="author" v-model="form.slug">
                <button type="submit">Edit</button>
            </form>
        </section>
    </main>
</template>
<script>
import axios from 'axios';
import { getAPI } from '../api'
import SideBar from '../components/Admin/Sidebar.vue';
import swal from 'sweetalert'
let imageSelection = false;
export default {
    components: { 
        'SideBar': SideBar
    },
    data () {
        return{
            Postslug: this.$route.params.Postslug,
            form: {
                title:"",
                desc:"",
                text:"",
                category:"",
                date:"",
                author:"",
                image:"",
                slug:"",
            },
        }
    },
    methods: {
        EditImage(event){
            this.form.image = event.target.files[0]
            let imageSelection = true
            return imageSelection
        },
        // Form method
        onSubmit(event, imageSelection){
            console.log(imageSelection);
            const fd = new FormData();

            fd.append('title', this.form.title)
            fd.append('desc', this.form.desc)
            fd.append('text', this.form.text)
            fd.append('category', this.form.category)
            fd.append('date', this.form.date)
            fd.append('author', this.form.author)
            if (imageSelection == true) {
             fd.append('image', this.form.image, this.form.image.name)   
            }
            fd.append('slug', this.form.slug)

            // event.preventDefault();     
            axios.patch(`http://127.0.0.1:8000/blog/api/edit/${this.Postslug}`, fd).then(response => {
              this.form.title = response.data.title
              this.form.desc = response.data.desc
              this.form.text = response.data.text
              this.form.image = response.data.image
              this.form.category = response.data.category
              this.form.author = response.data.author
              this.form.slug = response.data.slug
              
              this.$router.push({ name: 'AdminEditArticle', params: {Postslug: this.form.slug } });
              
              swal("Articolo editato", "", "success")
              .then(() => {
                  window.location.reload()
                })
                .catch(() => {
                    swal("Problema", "", "warning")
                });
              })

            .catch(err => {
            })
        },
    },
    
    created() {
        getAPI.get(`blog/api/edit/${this.Postslug}`)
            .then(response => {
              this.form.title = response.data.title
              this.form.desc = response.data.desc
              this.form.text = response.data.text
              this.form.date = response.data.date
              this.form.image = response.data.image
              this.form.category = response.data.category
              this.form.author = response.data.author
              this.form.slug = response.data.slug
            })
            .catch(err => {
              console.log(err)
            })
        },
    name: 'AdminEditArticle',
}

</script>
<style lang="sass" scoped>
stuff...
</style>

感谢您的帮助

【问题讨论】:

    标签: javascript vue.js ecmascript-6 axios vuejs3


    【解决方案1】:

    问题是您正在尝试使用表单保存图像。 为此,您应该首先上传文件,然后获取 imagePath(上传文件的位置)并将路径保存在表单中。

    因此,在您的提交功能中,您应该发出一个上传请求以上传图像并获取响应,该响应将作为您服务器上的图像路径并将其保存在您的表单对象中。

    例子:

    onSubmit() {
      if(checkIfCreateOrEdit)
           createPost(this.form).then(res => {
                 if (this.form.image instanceof File) {
                     const formData = new FormData()
                     formData.append('imagePhoto', this.form.image)
                return axios.post(url, headers: 'Content-Type':'multipart/form-data', data: formData)
                    
     
              })
              .then(()=> this.$router.push(....) )
              .catch(....)
    } else {
        editPost(this.form, this.post.id){
                 .....the same as above but you make a put request based on the id
                 }
    }
    

    注意事项: 尝试在表单对象上使用解构。 为了在您提交表单后在模板上显示图像,您应该重新创建 imagePath 并将其作为 src 属性传递。

    【讨论】:

    • 我试过了,但我没有让代码工作,怎么做? (对不起,我不擅长 Vue)
    • 我用一个语义示例编辑了我的原始帖子,我希望它能帮助更多
    猜你喜欢
    • 2020-02-20
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 2019-09-01
    • 2017-03-07
    • 1970-01-01
    • 2021-08-21
    • 2018-06-23
    相关资源
    最近更新 更多