需求背景:有多个轮播图需要单独上传,需要用data去区分上传的是哪一个轮播图
添加轮播图页面如下图所示:
实现效果:
实现思路及需要了解一下信息
①每一个轮播图应在数据库中有相对应的字段,如下所示:
需要在数据库初就考虑好,后续进行更新的时候只需找到对应的字段更新url
即可
②upload组件传至后端会返回图片在后端中的url地址,只有url地址而没有对应的轮播图的信息,所以在上传时需携带data
关键点之一在于如何携带data
③在第②步中需要把图片上传至一个类似于中间件
的一个数据表
中,单纯用来存放图片并接收图片在系统中的url
地址
④在第②步执行执行完后,可以接收到图片的url
以及对应的是哪个轮播图
⑤通过第④步得到的数据,及时更新表中的数据
⑥为了减少内存,中间件数据表中的url
数据应该及时清除,所以在第⑤步之后需要调用一个接口删除url
⑦为了实现第⑥步,需要给每一个上传的图片绑定一个uuid
,以便传入uuid找到对应的图片进行删除
⑧获取所有的url
地址进行渲染
为什么使用uuid而不用nanoid呢,这是因为nanoid不支持commonJS方式导入
总结使用了如下4个接口:
①把图片上传至中间件数据表中
②把返回的url和data插入真正的数据表中
③清除中间件数据表中的数据
④调用所有的轮播图数据进行渲染
upload组件在设置页面中的代码如下:
template部分
<div class="spider-wrapped">
<div class="spider-content">轮播图1:</div>
<!-- action 是上传的接口地址
on-success是上传成功的回调,及返回url及轮播图1的信息
auto-upload为自动上传模式
data为携带的数据
-->
<el-upload class="upload-demo"
action="http://127.0.0.1:3007/set/uploadswiper"
:on-success="onSuc" :auto-upload="true" ref="uploadRef" :data='data.l1'
:show-file-list='false'>
<template #trigger>
<!-- 为上传之前用了个雪碧图代替 -->
<img :src="swiperData.swiper1" alt="" class="swiper" v-if="!swiperData.swiper1==''">
<img src="@/assets/雪碧图.png" alt="" v-else>
</template>
</el-upload>
</div>
script部分 (组件式setup TS)
// 携带的data
const data = {
l1: '轮播图1',
}
// 轮播图地址
const swiperData = ref({
swiper1: '',
})
const onSuc = async (res) => {
// 因为返回的数据是一个对象,类型如{0: '轮', 1: '播', 2: '图', 3: '1'} 需要转化成字符串进行传参
let str = "";
for (let i = 0; i < 4; i++) {
str += res.data[i];
}
const onlyId = res.onlyId
const res1 = await addSwiper(str, res.url)
if (res1 == '添加图片成功') {
ElMessage({
message: '添加轮播图片成功',
type: 'success',
})
// 传入uuid删除中间件数据库中的数据,以免增加无用内存
await deleteSwiper(onlyId)
// 刷新页面,拿到所有的轮播图数据
getallswiper()
} else {
ElMessage.error('添加轮播图片失败,请检查网络是否通畅')
}
}
前端接口调用部分:
// 删除在image的轮播图
export const deleteSwiper = onlyId => {
return instance({
url: '/set/deleteSwiperInImage',
method: 'POST',
data:{
onlyId
}
})
}
// 添加轮播图到setting中
export const addSwiper = (set_name,set_value) => {
return instance({
url: '/set/insertSwiperInSetting',
method: 'POST',
data:{
set_name,
set_value
}
})
}
// 获取全部轮播图
export const getSwiperList = () => {
return instance({
url: '/set/getAllSwiper',
method: 'POST',
})
}
后端接口实现:
// 轮播图上传
exports.uploadswiper = (req, res) => {
const useful = '轮播图'
let oldName = req.files[0].filename;
// 新建uuid
const onlyId = crypto.randomUUID()
// 计算机上文件的名称
let originalname = req.files[0].originalname;
//给新名字加上原来的后缀
let newName = req.files[0].originalname;
//改图片的名字 renameSync为重命名
fs.renameSync('./public/upload/' + oldName, './public/upload/' + newName);
const sql = 'insert into image set ? '
db.query(sql, {
onlyId,
image_url: `http://127.0.0.1:3007/upload/${newName}`,
useful,
}, (err, result) => {
if (err) return res.cc(err)
// 上传成功
res.send({
data:req.body,
// 返回uuid
onlyId,
err: 0,
url: "http://127.0.0.1:3007/upload/" + newName
});
})
}
// 删掉image中的轮播图
exports.deleteSwiperInImage = (req, res) => {
const userinfo = req.body
// 根据唯一的id删除
const sql = 'delete from image where onlyId = ?'
db.query(sql, userinfo.onlyId, (err, result) => {
if (err) return res.cc(err)
res.send("删除图片成功")
})
}
// 添加轮播图到setting中 字段是轮播图和setting中的名字
exports.insertSwiperInSetting = (req, res) => {
const userinfo = req.body
const sql = 'update setting set set_value = ? where set_name = ?'
db.query(sql, [userinfo.set_value,userinfo.set_name], (err, result) => {
if (err) return res.cc(err)
res.send("添加图片成功")
})
}
// 获取全部轮播图 用like字符
exports.getAllSwiper = (req, res) => {
const userinfo = req.body
// 使用了like关键字
const sql = "select * from setting where set_name like '轮播图%' "
db.query(sql,(err, result) => {
if (err) return res.cc(err)
res.send(result)
})
}