Vue3+node.js实现同时上传图片与文字

实现思路

实现思路: 通过element-plus的upload组件实现上传图片,返回图片的url,然后与文字一起传给后端

使用技术栈: Vue3+mysql+node.js

适用场景: 需要文章和文字搭配的模块,比如美食、足球等新闻类介绍

测试图片

接口文档

http://127.0.0.1:3007/w/upload 上传图片

http://127.0.0.1:3007/w/pullnews 上传文字和图片

http://127.0.0.1:3007/w/getnews 获取文字和图片

前端代码

html部分

<template>
	<!-- action为后端上传图片接口
	 	 on-success为图片(文件)上传成功的钩子,这里用于返回url地址
	 	 :auto-upload="false"为禁止自动上传图片
	 	 ref="uploadRef"用于控制上传图片
	 -->
	<el-upload
	class="upload-demo" 
	action="http://127.0.0.1:3007/w/upload" 
	:on-success="onSuc"
	:auto-upload="false"
	ref="uploadRef"
	>
		<template #trigger>
		      <el-button type="primary">select file</el-button>
		</template>
	</el-upload>
	
	  <el-form :model="form" label-width="120px">
	    <el-form-item label="Activity name">
	      <el-input v-model="form.name" />
	    </el-form-item>
	    <!-- 点击上传文字和图片 -->
	    <el-form-item>
	      <el-button @click="uploadFile">上传</el-button>
	    </el-form-item>
	  </el-form>
	  <!-- 用于最后测试,即显示文字和图片 -->
	  <div v-if="test.name">
		<span>{{test.name}}</span>
		<img :src="test.url" alt="">
	  </div>
</template>
// setup语法糖
<script setup>
	import {
		ref,
		reactive
	} from 'vue'
	import {
		ElMessage,
		ElMessageBox
	} from 'element-plus'
	import axios from 'axios'
	//表单
	const form = reactive({
	  name: '',
	})
	// 图片地址
	const imageurl = ref()
	// 用于控制图片上传
	const uploadRef = ref()
	// 点击上传图片和文字
	// 为什么在这里用了定时器呢,因为点击上传后,图片上传返回url需要时间,拿到url后再与表单的文字一起传到后端
	const uploadFile =  () =>{
		uploadRef.value.submit()
		setTimeout( async ()=>{
			// 如果表单name或者图片地址不存在,上传失败
			if(form.name!== ''&&imageurl.value){
				const res1 = await axios.post("http://127.0.0.1:3007/w/pullnews",{name:form.name,image:imageurl.value})
				console.log(res1)
			}else{
				console.log('上传失败')
			}
		},10)
	}
	// 文件上传成功时的钩子 返回图片路径
	const onSuc = (res) =>{
		console.log(res.url)
		imageurl.value = res.url
	}
	// ----用于展示从后端获取的文字和图片----
	const test = ref({
		name:'',
		url:''
	})
	 const getnew = async () =>{
		const res = await axios.post("http://127.0.0.1:3007/w/getnews")
	 	test.value.name = res.data[0].name
	 	test.value.url = res.data[0].image
	 }
	 getnew()
</script>

后端代码

// app.js

const express = require('express')

const app = express()

const config = require('./config/index')
// 解析token
const expressJWT = require('express-jwt')
// cors跨域
const cors = require('cors')
// Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。
const multer = require("multer");

// 全局挂载 cors
app.use(cors())
// 在server服务端下新建一个public文件,在public文件下新建upload文件用于存放图片
const upload = multer({ dest:'./public/upload' })

app.use(upload.any())
// 静态托管
app.use(express.static("./public"));

const wRouter = require('./wRouter/index')
// 全局挂载
app.use('/w',wRouter)

app.listen(3007, () => {
  console.log('http://127.0.0.1:3007');
})
// --------------------------------------
// wRouter/index.js 放路由的文件
const express = require('express');

const router = express.Router()

const db = require('../db/index')

fs = require("fs");

// ----------------------------------------
// 测试上传图片
// 添加图片至数据库
router.post('/upload', (req, res) => {
  let oldName = req.files[0].filename;//获取名字
  let originalname=req.files[0].originalname;//originnalname其实就是你上传时候文件起的名字
  //给新名字加上原来的后缀
  let newName = req.files[0].originalname;
  //改图片的名字
  fs.renameSync('./public/upload/'+oldName, './public/upload/'+newName);
  // 这段insert操作可有可无
  const sql = 'insert into ima set ? '
  // 为什么返回的图片少了/pubilc?因为是静态托管
  db.query(sql,{image:`http://127.0.0.1:3007/upload/${newName}`},(err,result)=>{
	  if (err) {
	  	return res.send(err)
	  }
	  // 上传成功
	  res.send({
	    err: 0,
	    url:"http://127.0.0.1:3007/upload/" + newName
	  });
  })
})
// 把数据传到news
router.post('/pullnews', (req, res) => {
	const sql = 'insert into news set ? '
	db.query(sql, {name:req.body.name,image:req.body.image},
	(err, result) => {
		if (err) {
			return res.send(err)
		}
			// 添加成功
		res.send("添加成功")
	})
})
// 获取数据进行渲染
router.post('/getnews', (req, res) => {
	const sql = 'select * from news'
	db.query(sql,
	(err, result) => {
		if (err) {
			return res.send(err)
		}
			// 添加成功
		res.send(result)
	})
})

测试结果

news表

测试结果

需求难点

单纯的图片上传和表单上传都简单,难点在于图片和表单内容结合起来,需要用到图片的url,其实有插件可以很好的完成此类需求,这里不做介绍了

参考了nodejs接收图片,以及静态资源托管让前端访问这篇文章在后端的应用,感谢此文的作者

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐