最简单的方法教你如何使用vue3的el-upload组件上传头像到本地后端(axios的post请求),使用koa-multer把图片存储到自定义位置并且返回图片地址(附带源码)

   研究了好一阵子,踩了无数的坑,查阅了很多的博客,ai也用了,最后做出来了,保准清晰明了的告诉你你需要什么就可以实现这个功能。

前端方面

1.首先是组件的使用

  这里建议使用组件库里的代码,这一篇主要讲最关键的点,下一篇会讲el-upload怎么调整

<!-- 上传头像 -->
        <el-upload
          action="#"  //自定义请求
          :before-upload="beforeUpload"  //请求之前做的事
          :http-request="uploadFile"  //请求方法
        >
        </el-upload>

  最关键的就是这三个,可以说组件这里设置好了这三个,前端就可以了

2.内容方面

//上传用户头像涉及的变量
let FormDatas = reactive(""); //上传给后端的变量

// 上传之前,这里差不多照抄即可
const beforeUpload = (rawFile) => {
  //这里设置上传图片类型和限制大小
  if (rawFile.type !== "image/jpeg" && rawFile.type !== "image/png") {
    ElMessage.error("头像必须是jpg或png格式!");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 5) {
    ElMessage.error("头像过大!");
    return false;
  }
  return true;
};

// 上传头像
const uploadFile = async (item) => {
  //上传头像的处理
  FormDatas = new FormData();
  FormDatas.append("file", item.file);
};

  这里讲一下上传头像,需要转换成FormData格式,这一点很关键,然后这个FormDatas就是我要传给后端的东西,就是上传的内个文件,这里是全局变量

  还有注意一下这里的这个append的键“file”

3.发送请求和一些逻辑
//这里是我的表单点击提交之后的逻辑
//先请求
let uploadMsg = await proxy.$api.upload(FormDatas);
//拿到数据之后给表单里的avatar赋值成链接,这部分之后是更新用户信息的请求
if (uploadMsg) {
  userForm.avatar = uploadMsg.data;
}

//上传头像的请求(可能不需要设置headers,但是我加上了)
  upload(params) {
    return request({
      headers: { "Content-Type": "multipart/form-data" },
      url: "/upload/img",
      method: "post",
      data: params,
    });
  },

这部分是大家自己的逻辑代码,就是带着这个数据去请求然后能拿回来一个图片地址

后端方面

  这里比较关键,因为我对后端不了解,所以基本查阅的资料都是关于后端koa框架的,真的踩了很多坑!

1.首先是app.js里面
const bodyparser = require("koa-bodyparser");

// middlewares
app.use(
  bodyparser({
    enableTypes: ["json", "form", "text"],
  })
);

  这里其实用这个中间件就可以解析,不需要加任何额外的中间件,尤其是koa-body!!!

  尤其是koa-body!!!一查博客全都告诉你加koa-body解析formdata数据,确实能解析了,但是存到了ctx.request.files里面!你的koa-multer就不生效了!真的很坑!

2.upload.js文件
//这里没什么好说的,照抄即可,是根据日期创建文件夹和文件名称
let storage = multer.diskStorage({
  //设置文件存储位置
  destination: function (req, file, cb) {
    let date = new Date();
    let year = date.getFullYear();
    let month = date.getMonth() + 1;
    let day = date.getDate();
    let dir = "./public/uploads" + year + month + day;

    //如果没有文件夹就创建文件夹
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, {
        recursive: true,
      });
    }

    cb(null, dir);
  },

  filename: function (req, file, cb) {
    //设置文件名称
    let filename = Date.now() + path.extname(file.originalname);
    cb(null, filename);
  },
});

let upload = multer({ storage });

//上传图片的接口
router.post("/img", upload.single("file"), async (ctx) => {
  let path = ctx.req.file.path;
  path = ctx.origin + "" + path.replace("public", "");
  if (path) {
    ctx.body = {
      code: 200,
      msg: "上传成功!",
      data: path,
    };
  } else {
    ctx.body = {
      code: 400,
      msg: "上传出现异常!",
    };
  }
});

  注意一下上传图片接口里的upload.single("file"),这里要和前端append的名字对上,然后你就可以从ctx.req里面拿到file,大家可以自行打印,然后这里是把图片存到了后端项目的一个文件里面,启动后端之后就可以通过后端服务器的地址访问这个图片,然后数据库存的是这个地址(后面有图)

  还有req和request不是一个东西!

  所以我可能是这个地方没对上(当时某一个用的myfile),绕了一大圈子(痛!太痛了!)

  下一篇讲一下设置el-upload

附带的加强理解的点

  1.前端根据后端返回的path放图的代码
<img :src="picture" alt="" />

// 头像,如果上传了就从store里面拿,没上传就是默认的
const picture = computed(() => {
  return userMsgStore.userMsg.avatar == ""
    ? "src/assets/imgs/defaultImg.png"
    : userMsgStore.userMsg.avatar;
});
  2.上传到数据库的地址

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 `el-upload` 组件上传文件,然后在上传成功的回调函数中获取到文件对象,并将其传递给后端。 以下是一个基本的示例: ```vue <template> <el-upload action="/api/upload" :on-success="handleSuccess" :before-upload="beforeUpload" > <el-button>上传文件</el-button> </el-upload> </template> <script> export default { methods: { handleSuccess(response, file) { console.log('上传成功', response, file) }, beforeUpload(file) { // 如果需要限制上传的文件类型,可以在这里进行判断 console.log('准备上传', file) } } } </script> ``` 在以上示例中,`action` 属性指定了上传文件的接口地址,`on-success` 属性指定了上传成功后的回调函数,`before-upload` 属性指定了上传前的回调函数。你需要根据自己的需求修改这些属性的值。 在 `handleSuccess` 回调函数中,你可以获取到后端返回的数据和上传的文件对象。你可以将文件对象传递给后端,例如使用 `axios` 发送 POST 请求: ```js import axios from 'axios' handleSuccess(response, file) { console.log('上传成功', response, file) const formData = new FormData() formData.append('file', file) axios.post('/api/upload-file', formData) .then(res => { console.log('后端返回数据', res.data) }) } ``` 在以上代码中,我们将文件对象添加到 `FormData` 对象中,并使用 `axios` 发送 POST 请求,将该 `FormData` 对象作为参数传递给后端接口 `/api/upload-file`。你需要根据自己的接口地址请求方式进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值