koa+elementUI实现表单文件图片上传

2 篇文章 0 订阅
我是想要实现表单加上图片的上传
首先前端代码
<template>
  <div>
    <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" enctype='multipart/form-data'>
      <el-form-item label="分类" prop="study_type">
        <el-radio-group v-model="ruleForm.type">
          <el-radio-button label="轻量级框架"></el-radio-button>
          <el-radio-button label="主流前端框架"></el-radio-button>
          <el-radio-button label="工具"></el-radio-button>
          <el-radio-button label="CSS生态"></el-radio-button>
          <el-radio-button label="JS生态"></el-radio-button>
          <el-radio-button label="VUE生态"></el-radio-button>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="名称" prop="name">
        <el-input v-model="ruleForm.name"></el-input>
      </el-form-item>
      <el-form-item label="链接" prop="link">
        <el-input v-model="ruleForm.link"></el-input>
      </el-form-item>
      <el-form-item label="简介" prop="info">
        <el-input type="textarea" v-model="ruleForm.info" :autosize="{ minRows: 4, maxRows: 6}"></el-input>
      </el-form-item>
      <el-form-item>
        <el-upload
          ref="upload"
          action=""
          :auto-upload="false"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-success="uploadSuccess">
          <i class="el-icon-plus"></i>
        </el-upload>
        <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt="">
        </el-dialog>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
  export default {
    props:[''],
    data () {
      return {
        ruleForm: {
          type: '轻量级框架',
          name: '',
          link: '',
          info: '',
        },
        rules: {
          name: [
            { required: true, message: '请输入名称', trigger: 'blur' },
            { min: 1, max: 15, message: '长度在 1 到 15 个字符', trigger: 'blur' }
          ],
          link: [
            { required: true, message: '请输入链接', trigger: 'blur' },
            { min: 1, max: 255, message: '长度在 1 到 255 个字符', trigger: 'blur' }
          ],
          info: [
            { required: true, message: '请填写简介', trigger: 'blur' }
          ]
        },
        dialogImageUrl: '',
        dialogVisible: false,
      };
    },

    methods: {
      submitForm(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
          	//用formdata传递数据
            const formData = new FormData();
            //上传图片
            const file = this.$refs.upload.uploadFiles[0]
            formData.append('file', file.raw);
            formData.append('name', this.ruleForm.name);
            formData.append('type', this.ruleForm.type);
            formData.append('info', this.ruleForm.info);
            formData.append('link', this.ruleForm.link);
            this.$http.post('/study/add',formData).then(res => {
              console.log(res.data)
            })
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      },
      uploadSuccess(response, file){
        console.log(response)
        console.log(file)
      },
    }
</script>
前端页面

在这里插入图片描述

后台很重要

  • 1.首先要获取静态资源,这样就可以通过http://localhost:3000/XXXX.jpg拿到图片
//app.js
const static = require('koa-static')//获取静态资源

app.use(static(
    path.join(__dirname, './upload')//获取static文件夹下的资源,url不加static http://localhost:3000/avatar.png
))
  • 2.需要安装koa-multer,可以单独写个文件导出,我是写在一个文件里,然后写接口
//study.js
const multer = require('koa-multer')//解析上传文件
const path = require('path')

let storage = multer.diskStorage({
	//定义文件保存路径
    destination: path.resolve('upload'),//路径根据具体而定。如果不存在的话会自动创建一个路径
    filename: (ctx, file, cb)=>{
        cb(null, file.originalname);
    },
	//修改文件名
	filename:function(req,file,cb){
            var fileFormat = (file.originalname).split(".");
                cb(null,Date.now() + "." + fileFormat[fileFormat.length - 1]);
        }
});

let upload = multer({ storage: storage});

router.post('/add',passport.authenticate('jwt', { session: false }),upload.single('file'), async ctx => {
    console.log(ctx.req.body)//获取上传的表单数据
    console.log(ctx.req.file)//获取上传的文件图片数据
})

实例

  • 前台post请求
    在这里插入图片描述

  • 获取到的图片
    在这里插入图片描述

  • 后台获取到的数据
    在这里插入图片描述

  • 加上数据库
    在这里插入图片描述

遇到的问题

  1. 如果用elementUI的action属性,将文件用this.$refs.upload.submit()上传,就会发送2次post请求,就会导致提交表单一次,上传图片一次,在后台就会取不到表单数据或者图片数据,所以我采用了formData传递数据的方式。
  2. 我在测试接口的时候一直都没有给返回值,所以一直报404,记得给返回值。
  3. 第一次用formData传递数据,还不是很清楚,我在测试的时候,ctx.request是空的,但是ctx.req却有数据,查找资料。
    (1)ctx.request:是Koa2中context经过封装的请求对象,它用起来更直观和简单。
    (2)ctx.req:是context提供的node.js原生HTTP请求对象。这个虽然不那么直观,但是可以得到更多的内容,适合我们深度编程。
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值