如何在 Vue 表单中处理图片

Vue.js

我在Vue中有一个form表单,用于上传博客帖子,它有标题、正文、描述、片段和图片等范围。所有的一切都是必需的。我在Express中设置了一个API来处理这个问题。我在Postman中测试正常,但是我不知道如何通过浏览器将文件发送给数据库。我一直收到500错误,并且我将数据打印到控制台,而图片字段为空,所以我确信这就是问题所在,但我就是搞不清楚怎么办。

这是我前端页面的form表单:

<template>
  <div class="container">
    <div id="nav">
      <adminnav/>
    </div>
    <div id="create">
      <h1>Create new post</h1>
    </div>
    <div id="post">
      <body>
        <form>
          <label for="title">Title: </label>
          <textarea v-model=formdata.title rows="5" cols="60" name="title"
            placeholder="Enter text">
          </textarea>
          <br/>
          <label for="body">Body: </label>
          <textarea v-model=formdata.body rows="5" cols="60" name="body"
            placeholder="Enter text">
          </textarea>
          <br/>
          <label for="description">Description: </label>
          <textarea v-model=formdata.description rows="5" cols="60" name="description"
            placeholder="Enter text">
          </textarea>
          <br/>
          <label for="snippet">Snippet: </label>
          <textarea v-model=formdata.snippet rows="5" cols="60" name="snippet"
            placeholder="Enter text">
          </textarea>
          <br/>
          <label for="file">Upload photo: </label>
          <input
            class="form-control-file"
            type="file"
            accept="image/*"
            v-bind="formdata.photo"
          />
          <br/>
          <input id="submit" type="submit" value="submit" @click.prevent="createPost()"/>
        </form>
      </body>
    </div>
  </div>
</template>

<script>
import adminnav from '../components/adminnav.vue';
import PostService from '../service/PostService';

export default {
  name: 'createStory',
  components: {
    adminnav,
  },
  data() {
    return {
      formdata: {
        title: '',
        body: '',
        description: '',
        snippet: '',
        photo: null,
      },
    };
  },
  methods: {
    createPost() {
      console.log(this.formdata);
      /* eslint prefer-destructuring: 0 */
      const formdata = this.formdata;
      PostService.createPost(formdata)
        .then(() => {
          console.log('success');
        });
    },
  },
};
</script>

这是POST请求。

router.post("/add-story", upload.single('photo'), async(req, res) => {
  try{
    let post = new Post();
    post.title = req.body.title;
    post.description = req.body.description;
    post.photo = req.file.location;
    post.body = req.body.body;
    post.snippet = req.body.snippet;

    await post.save();

    res.json({
      status: true,
      message: "Successfully saved."
    });

  } catch(err) {
    res.status(500).json({
      success: false,
      message: err.message
    });
  }
});

noob 回答:

让我们监视文件<input>中的change事件。这样可以确保每次用户的上传行为触发updatePhoto方法并把文件数据储存到this.photo

<input type="file" accept="image/*" class="form-control-file"
    @change="updatePhoto($event.target.name, $event.target.files)"
>

编码去收集所有的数据并发送请求

// vue组件的其他部分
data () {
    return {
        title: '',
        body: '',
        description: '',
        snippet: '',
        photo: {} // 储存文件数据
    };
},
methods: {
    updatePhoto (files) {
        if (!files.length) return;

        // 存储文件数据
        this.photo = {
            name: files[0].name,
            data: files[0]
        };
    },
    createPost() {
        let formData = new FormData();

        formData.append('title', this.title);
        formData.append('body', this.body);
        formData.append('description', this.description);
        formData.append('snippet', this.snippet);
        formData.append('photo', this.photo.data, this.photo.name);

        PostService.createPost(formdata)
        .then(() => {
            console.log('success');
        });
    }
}
// vue组件的其他部分

很明显,我跳过了很多事情,比如整个vue组件结构,我相信它与这个问题无关,还有一些确保在启动请求之前文件数据可用的检查等等。这是一个关于如何获取文件数据的想法,所以希望这个答案能启发您。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://stackoverflow.com/questions/6583...

译文地址:https://learnku.com/vuejs/t/53875

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!