antd上传单张多张图片 预览和删除
图片上传(有后台接口)express框架+multer写的:https://www.cnblogs.com/catherLee/p/13141231.htmlvue+koa框架写的:https://www.cnblogs.com/threepigs/p/10703689.htmlhttps://www.cnblogs.com/miaSlady/p/13218319.html下面这个有入口文件说明,
·
图片上传(有后台接口)
express框架+multer写的:https://www.cnblogs.com/catherLee/p/13141231.html
vue+koa框架写的:https://www.cnblogs.com/threepigs/p/10703689.html
https://www.cnblogs.com/miaSlady/p/13218319.html
下面这个有入口文件说明,搭配上面的搭建node服务
以下代码块都是用的 formdata 方式上传图片
开发中用到的单张图片上传代码块(这是不带预览和删除的、比较简单)
<a-upload
name="avatar"
list-type="picture-card"
:show-upload-list="false"
:action="uplodFiles">
<img v-if="model.url" :src="model.url" alt="avatar" class="img-item" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">上传</div>
</div>
</a-upload>
async uplodFiles(files) {
this.loading = true
let formData = new FormData()
formData.append('files', files)
//console.log('formData', formData.get('files'))
const res = await uploadAction(this.url.uplodFiles, formData)
this.loading = false
this.model.url = res
},
多张图片上传代码块(用的传统http-request方法)
//element-ui图片多个上传完整代码
<el-upload
action=""
ref="upload"
multiple
:limit="3"
list-type="picture-card"
:auto-upload="false"
:http-request="httpUploadFile"
:on-change="codeChange"
v-loading="codeLoding"
>
<i slot="default" class="el-icon-upload2"></i>
<div slot="file" slot-scope="{ file }">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in"></i>
</span>
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
<el-button class="el-btn" @click="uploadClick">提交</el-button>
<a-modal centered :visible="previewVisible" :footer="null" @cancel="previewVisible = false">
<img width="100%" :src="dialogImageUrl" alt="" />
</a-modal>
data() {
return {
url: {
uplodUrl: '/pat/Snapshota/fileUpload',
},
loading: false,
previewVisible: false,
disabled: false,
dialogImageUrl: '',
fileList: [],
hasfileUrl: false,
}
}
//改变了触发
codeChange(file) {
console.log('改变', file)
if (file.url !== '') {
this.hasfileUrl = true
}
},
//点击提交触发
httpUploadFile(files) {
this.fileList.push(files.file)
console.log('请求后', this.fileList)
},
//提交上传
uploadClick() {
if (this.hasfileUrl === false) {
return this.$message.warning('请先选择图片')
}
let formData = new FormData()
this.$refs.upload.submit()
this.fileList.forEach((item) => {
formData.append('files', item)
})
this.codeLoding = true
uploadAction(this.url.uplodUrl, formData).then((res) => {
this.model.picDetails = res
console.log('上传成功', res)
this.codeLoding = false
this.$message.success('上传成功')
})
},
//预览
handlePictureCardPreview(files) {
console.log('预览', files)
this.dialogImageUrl = files.url
this.previewVisible = true
},
//移除
handleRemove(file) {
let index = this.fileList.findIndex((item) => {
return item.uid === file.raw.uid
})
this.fileList.splice(index, 1)
console.log(this.fileList)
this.$refs.upload.handleRemove(file)
},
// 表单和图片一起用自定义上传formData、append的方式传给后端、接口要设置contentType: "multipart/form-data",
// 这种方法是上传到服务器上、.env.development、.env.production、.env.staging都配置了
//# 图片路径前缀
//VUE_APP_IMG_BASE_API = 'http://192.168.3.73:8080/'
# 注意假如是用组件的自动上传要带上 :headers 自动上传会触发 :on-success
headers: {
'Content-Type': 'multipart/form-data', // 上传文件的表单要加上请求头multipart/form-data
// 或者这样写 ContentType: "multipart/form-data", Authorization: "Bearer " + getToken(),
},
<el-upload
action="#"
ref="uploadImg"
list-type="picture-card"
:limit="1"
:auto-upload="false"
:http-request="httpUploadFile"
:on-exceed="uploadExceed"
:file-list="fileList"
>
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{ file }">
<img
class="el-upload-list__item-thumbnail"
:src="file.url"
alt=""
/>
<span class="el-upload-list__item-actions">
<span
v-if="!disabled"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate((valid) => {
if (valid) {
this.elLoading = true;
let formData = new FormData();
// 假如有上传图片、调用上传方法、并添加上传的文件
this.$refs.uploadImg.submit();
if (this.file === null) {
return this.$modal.msgError("请上传图标");
}
let newForm = {
name: this.form.name,
unit: this.form.unit,
points: this.form.points,
comment: this.form.comment,
};
for (let obj in newForm) {
formData.append(obj, newForm[obj]);
}
formData.append("file", this.file);
if (this.form.id != null) {
formData.append("id", this.form.id);
this.editForm(formData); // 编辑
} else {
this.addForm(formData); // 增加
}
}
});
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids;
this.elLoading = true;
getSafflower(id).then((response) => {
this.elLoading = false;
this.form = response.data;
this.open = true;
this.title = "修改红花设置";
});
// 每次点击修改给fileList赋值
this.fileList = [
{
name: this.publicGetUrlMethods(row.url),
url: this.getTableUrl(row.url),
},
];
},
// 公共获取图片后缀方法
publicGetUrlMethods(url) {
let index = url.lastIndexOf("/");
return url.substr(index + 1);
},
// 转换成后台接口
getTableUrl(url) {
return VUE_APP_IMG_BASE_API + url;
},
//element组件的自动上传 代码块
<el-upload
ref="uploadImg"
:action="articleAction"
:limit="1"
:headers="headersObj"
:before-upload="beforeUpload"
:on-exceed="uploadExceed"
:on-success="uploadSuccess"
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="fileList"
>
<el-button
type="info"
plain
icon="el-icon-upload"
size="mini"
:disabled="isLocked"
>
上 传
</el-button>
</el-upload>
<script>
export default {
data() {
return {
articleAction: process.env.VUE_APP_BASE_API + "/zhxy/network/upload",
headersObj: {
ContentType: "multipart/form-data",
Authorization: "Bearer " + getToken(),
},
// 锁
isLocked: false,
}
},
methods: {
// 上传限制数量
uploadExceed() {
return this.$modal.msgWarning("只能上传一张图片");
},
// 上传之前
beforeUpload(file) {
if (this.isLocked) {
return;
}
this.isLocked = true;
},
// 上传成功
uploadSuccess(res, file, fileList) {
console.log("上传成功", res);
this.fileList = [
{
name: file.name,
url: res.msg,
},
];
if (res.code == 200) {
this.isLocked = false;
return this.$modal.msgSuccess("上传成功");
}
},
// 移除
handleRemove(file) {
console.log("移除", file);
this.fileList = [];
},
// 预览
handlePreview(file) {
console.log("预览", file);
this.pictureUrl = file.url;
window.open(file.url);
},
}
</script>
antd组件中实际上传图片并能 预览和删除 的代码块
formData.append('file', info.file)
formData.append('upload_token', res)
:customRequest="onUpload" // 自定义上传、
// 带Token :headers = { Authorization: 'Bearer' + getToken() }
headers: {
'Content-Type': 'multipart/form-data', // 上传文件的表单要加上请求头multipart/form-data
},
也可以直接这么写:contentType: "multipart/form-data", 这里注意两种写法都要写在data之前
// 封装的图片上传接口
export function uploadAction(url,parameter){
return axios({
url: url,
data: parameter,
method:'post' ,
headers: {
'Content-Type': 'multipart/form-data', // 文件上传
},
})
}
// 在Jeecg生成的代码中二次修改(单张上传)、这里没有引入它封装的JImageUpload.vue、这个组件是上传到服务器文件夹中
<a-upload
class="avatar-uploader"
list-type="picture-card"
:multiple="false"
:file-list="fileList"
:action="uploadImg"
@change="handleChange"
@preview="handlePreview"
:class="[fileList.length < 1 ? '' : 'image-upload-single-over']"
>
<div v-if="fileList.length < 1">
<a-icon :type="fileLoading ? 'loading' : 'plus'" />
<div class="ant-upload-text">上传</div>
</div>
<a-modal
:visible="previewVisible"
:footer="null"
@cancel="previewVisible = false"
:closable="false"
>
<img alt="example" style="width: 100%" :src="previewImage" />
</a-modal>
</a-upload>
<script>
import { uploadAction } from '@/api/manage'
// 不重复的负数uid方法(antd上传组件的fileList要用到)
const uidGenerator = () => {
return '-' + parseInt(Math.random() * 10000 + 1, 10)
}
// 不重复的name方法
const getFileName = (path) => {
if (path.lastIndexOf('\\') >= 0) {
let reg = new RegExp('\\\\', 'g')
path = path.replace(reg, '/')
}
return path.substring(path.lastIndexOf('/') + 1)
}
export default {
data() {
url: {
uploadUrl: '/pat/Snapshota/fileUpload',
},
fileLoading: false,
model: {},
fileList: [],
previewVisible: false,
previewImage: ''
}
methods() {
// 单张图片上传↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
uploadImg(file) {
this.fileLoading = true
let formData = new FormData()
// PS: 后端接口参数是files
formData.append('files', file)
uploadAction(this.url.uploadUrl, formData).then((res) => {
this.fileLoading = false
// 上传成功之后将oss返回的url赋值到表单model的 pictureUrl上来提交
this.model.pictureUrl = res
// 转数组
let arr = file.name.split(',')
let fileList1 = []
for (var i = 0; i < arr.length; i++) {
fileList1.push({
uid: uidGenerator(),
name: getFileName(arr[i]),
status: 'done',
url: res,
})
this.fileList = fileList1
}
})
},
handlePreview(file) {
this.previewImage = file.url
this.previewVisible = true
},
// 改变时触发
handleChange({ file }) {
if (file.status === 'removed') {
this.fileList.splice(this.fileList.indexOf(file), 1)
// PS: 每次删除之后要把对应的pictureUrl去除、不然提交的数据没有变化
this.model.pictureUrl = ''
}
},
// 单张图片上传↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
// jeecg封装表格当前行的编辑按钮触发方法
edit(record) {
this.model = Object.assign({}, record)
this.visible = true
// 假如本行数据拿到了record.pictureUrl 阿里oss传回来的url,那么给fileList重新赋值、编辑回显出图片
// antd预览的图片是通过绑定的 fileList 来决定的、要遵循官方给的格式
if (record.pictureUrl) {
let fileList1 = []
let arr = record.id.split(',')
for (var i = 0; i < arr.length; i++) {
fileList1.push({
uid: uidGenerator(),
name: getFileName(arr[i]),
status: 'done',
url: record.pictureUrl,
})
}
this.fileList = fileList1
}
}
},
}
</script>
<style scoped lang="less">
.img-item {
width: 100px;
height: 100px;
}
// 这里是用来控制单张图片上传后禁用上传的框
/deep/ .image-upload-single-over .ant-upload.ant-upload-select-picture-card {
display: none;
}
</style>
//多张上传预览和删除代码块、和上面单张上传差不多、区别在于这里限制了多张上传
//因为限制最多上传三张、为了防止出bug、设置了 :multiple="false"
<a-upload
class="avatar-uploader"
list-type="picture-card"
:multiple="false"
:file-list="detailFileList"
:action="uploadDetail"
@change="handleDetailChange"
@preview="handleDetailPreview"
>
<div>
<a-icon :type="detailLoading ? 'loading' : 'plus'" />
<div class="ant-upload-text">上传</div>
</div>
<a-modal
:visible="detailPreviewVisible"
:footer="null"
@cancel="detailPreviewVisible = false"
:closable="false">
<img alt="example" style="width: 100%" :src="detailPreviewImage" />
</a-modal>
</a-upload>
<script>
import { uploadAction } from '@/api/manage'
// 不重复的负数uid方法(antd上传组件的fileList要用到)
const uidGenerator = () => {
return '-' + parseInt(Math.random() * 10000 + 1, 10)
}
// 不重复的name方法
const getFileName = (path) => {
if (path.lastIndexOf('\\') >= 0) {
let reg = new RegExp('\\\\', 'g')
path = path.replace(reg, '/')
}
return path.substring(path.lastIndexOf('/') + 1)
}
export default {
data() {
url: {
uploadUrl: '/pat/Snapshota/fileUpload',
},
// 多张上传url暂存变量
allUrl: [],
detailFileList: [],
detailPreviewVisible: false,
detailLoading: false,
detailPreviewImage: '',
},
methods: {
edit(record) {
this.model = Object.assign({}, record)
this.visible = true
// 假如有record.picDetails、批量给 detailFileList赋值
if (record.picDetails) {
let arr = record.picDetails.split(',')
for (var i = 0; i < arr.length; i++) {
this.detailFileList.push({
uid: uidGenerator(),
name: getFileName(arr[i]),
status: 'done',
url: arr[i],
})
}
// 点击编辑也要给picDetails赋值
this.detailFileList.filter((item) => {
that.allUrl.push(item.url)
})
// PS: 这里必须重新赋值picDetails、不然回显删除在上传提交有bug
this.model.picDetails = this.allUrl.join(',')
console.log('点击了编辑的detailFileList', this.detailFileList)
console.log('点击了编辑的picDetails', this.model.picDetails)
}
},
// 多张上传↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
uploadDetail(file) {
this.detailLoading = true
let formData = new FormData()
formData.append('files', file)
if (this.detailFileList.length === 3) {
this.detailLoading = false
return this.$message.warning('最多只能上传三张详情图片')
}
uploadAction(this.url.uploadUrl, formData).then((res) => {
this.detailLoading = false
this.allUrl.push(res)
this.model.picDetails = this.allUrl.join(',')
this.detailFileList.push({
uid: uidGenerator(),
name: getFileName(file.name),
status: 'done',
url: res,
})
console.log('上传成功的detailFileList', this.detailFileList)
})
},
handleDetailPreview(file) {
let [{ url }] = this.detailFileList.filter((item) => {
return item.uid === file.uid
})
this.detailPreviewImage = url
this.detailPreviewVisible = true
},
handleDetailChange({ file }) {
if (file.status === 'removed') {
let delItem = this.detailFileList.filter((item) => {
return item.uid === file.uid
})
// 转数组
let picUrl = this.model.picDetails.split(',')
let index = picUrl.indexOf(delItem[0].url)
this.detailFileList.splice(index, 1)
picUrl.splice(index, 1)
// 转字符串
this.model.picDetails = picUrl.join(',')
console.log('删除之后的detailFileList', this.detailFileList)
console.log('删除之后的picDetails', this.model.picDetails)
}
},
// 多张上传↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
}
</script>
更多推荐
已为社区贡献2条内容
所有评论(0)