前端使用element-ui的el-upload组件上传图片

前端使用element-ui的el-upload组件上传图片

el-upload上传图片,当图片上传完成并获得后端传来的图片地址(服务器地址)后,隐藏上传组件并显示图片:

<el-upload
  v-if="!imgUrl"
  class="upload-demo"
  drag
  :action="uploadUrl"
  :on-change="getFile"
  accept=".jpg"
>
  <i class="el-icon-upload"></i>
  <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  <template v-slot:tip>
    <div class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
  </template>
</el-upload>
<img v-else :src="imgUrl" alt="">

getFile (file) {
  const { status, response } = file
  if (status === 'success' && response?.code === 0) {
    const { data } = response
    this.imgUrl = data
  }
}

后端

后端将获取到的图片放到node的静态服务器上,服务器上这张图片的地址也就是前端需要拿到并展示的图片地址——后端项目的/app/public/下

具体流程

  • 前端上传图片发送post请求;
  • egg.js通过router调用controller.home.uploadImg ;
  • 函数通过一系列操作将文件放到 后端项目/app/public 文件夹下;
  • 传递给前端图片地址 后端服务器地址/图片名字(如若后端项目跑在7001端口 则回传的url为 http://127.0.0.1:7001/xxx.jpg)。

前端页面不能直接展示本地电脑里某个位置的图片,会出现 Not allowed to load local resource 的错误:

async uploadImg(ctx) {
	// 添加用户信息
	const part = ctx.multipart({ autoFields: true });
	const stream = await part();
	if (stream) {
	  const fileType = stream.mimeType.split('/')[ 1 ];
	  const filename = Date.now() + '.' + fileType || stream.filename.toLowerCase();
		// UPLOAD_URL为'./app/public/'
	  const target = path.join(UPLOAD_URL, filename);
	  const writeStream = fs.createWriteStream(target);
	  await pump(stream, writeStream);
	  new Result(`http://${ctx.host}/public/${filename}`, '上传成功').success(ctx.response);
	}
}

为什么放到public目录下就能直接访问了呢?

我们来简单看一下egg.js的运行机制

eggjs运行机制

eggjs 是功能更丰富、更规范的koa

使用koa时,你要写一个项目,要往里面加很多中间件,要写脚本加载routes文件夹下面的所有路由以及model文件夹下面的所有sequelize模型,koa仅仅是一个骨架,其他的都是你来完成,自由度高,但集成度低,每创建一个新项目都要做很多重复工作。egg.js是封装了一套koa,可以理解成大礼包版koa,集成度高,可以轻松创建一个项目而不用做很多繁琐的初期工作,解放生产力,更可贵的是有一套现成的规范提供给我们,不需要我们自己再去探索一套规范,比如router放哪里,controller放哪里,需不需要service,哪些放在service等等。

egg.js项目架构

绿色虚线框中的所有组件组成了一个Worker,这就是egg.js中实际执行代码逻辑的进程,是一个node服务器。

  • request进来后,先穿过中间件,自己定义的中间件都放在projectDir/app/middleware下,并在config中启用;
  • egg.js内置了egg-static中间件,将静态资源放在projectDir/app/public中,只会经过egg-static中间件之前的中间件,最后egg-static直接响应给客户端,不会到达其后的中间件以及Router;
  • 如果不是public中的资源,将会穿越所有中间件,到达路由。一般所有的路由都放在router.js中,这个文件没有任何逻辑,而是直接指向一个处理请求的controller,只起到目录和索引的作用;
  • Controller都放在projectDir/app/controller中,不含有具体的业务逻辑,业务逻辑都在Service中,Controller只负责调用并组合Service,最后将响应提交给客户端
  • Service放在projectDir/app/service中,负责调用Model,进行具体业务
  • 除此之外,Worker中还有定时任务,写在projectDir/app/schedule文件夹中;
  • 各个部件的所有可操控行为,都可以在projectDir/config/中的配置文件中定义,配置文件可以同时有很多份,default会被具体环境的配置文件中的同名字段覆盖,具体使用哪份配置,是根据EGG_SERVER_ENV这个环境变量的值。

https://www.jianshu.com/p/6b04330ee4a1

posted @ 2022-03-09 15:04  TRY0929  阅读(1292)  评论(0编辑  收藏  举报