<template>
<!-- 上传后显示 -->
<div id="look">
<div id="look-img" v-for="(item, index) in imgSrc" :key="index">
<img :src="item" alt="" />
<div id="look-operate">
<img src="https://s1.ax1x.com/2022/08/08/vMEtPO.png" alt="" title="点击查看" @click="toLook(index)" />
<img src="https://s1.ax1x.com/2022/08/08/vMEaxH.png" alt="" title="点击删除" @click="toDelete(index)" />
</div>
</div>
<!-- 上传图片按钮 -->
<div id="demo" v-show="uploadNum">
<input ref="fileBtn" type="file" id="input-file" accept="image/png,image/gif,image/jpeg" multiple @change="toUpload($event)" />
<img src="https://s1.ax1x.com/2022/08/08/vMEwMd.png" alt="" id="upload-img" />
</div>
</div>
</template>
<script >
import { getVueModules} from 'components/util';
//npm install v-viewer --save
import 'viewerjs/dist/viewer.css';
import { api as viewerApi } from 'v-viewer';
export default {
computed: {
baseUrl() {
return this.$axios.defaults.baseURL;
},
jwtToken() {
return this.$axios.defaults.headers.common.Authorization;
},
},
setup(props) {
const { toRefs, reactive, router, store, proxy, onMounted, ref } = getVueModules(),
reactiveData = reactive({
imgSrc: [], //已上传图片数组
arrLength: 3, //上传图片数量
uploadNum: true, //控制上传按钮的显示隐藏
show: false, //控制预览图片遮罩层显示隐藏
picSrc: '', //预览图片地址
picWhere: 0, //选择哪一张进行预览以及控制上一张下一张
imgEndArr: [], // 最终传给后端的图片数组
fileBtn: null
}),
methods = {
// 单个图片上传回显
toUpload(e) {
let file = e.target.files[0];
// 图片上传回显
methods.uploadImg(file);
},
uploadImg(file) {
let formData = new FormData();
formData.append('file', file);
$.ajax({
url: `${proxy.baseUrl}/order/upload_image`,
type: 'POST',
data: formData,
headers: {
Authorization: proxy.jwtToken,
},
async: false,
cache: false,
contentType: false, //不设置内容类型
processData: false, //不处理数据
success: res => {
// 后端上传返回的路径显示路径
reactiveData.imgSrc.push(res?.data?.filePath)
// 最终需要传给后端的传参
reactiveData.imgEndArr.push(res?.data);
},
error: function () {
notifyError('上传图片失败');
},
});
},
// 判断照片数量是否满足规定数量;满足则隐藏上传按钮
toJudgeNum() {
if (reactiveData.imgSrc.length >= reactiveData.arrLength) {
reactiveData.uploadNum = false;
} else {
reactiveData.uploadNum = true;
}
},
//删除图片
toDelete(i) {
reactiveData.imgSrc.splice(i, 1);
reactiveData.imgEndArr.splice(i, 1)
methods.toJudgeNum();
},
// 图片预览
toLook(i) {
const $viewer = viewerApi({
options: {
initialViewIndex: i,
inline: false,
button: true,
navbar: true,
title: false,
tooltip: false,
movable: false,
zoomable: true,
rotatable: false,
scalable: false,
transition: true,
fullscreen: true,
keyboard: false,
zIndex: 9999,
toolbar: {
zoomIn: 4,
zoomOut: 4,
prev: 4,
next: 4,
},
},
images: reactiveData.imgSrc
});
},
onMounted(async function () {});
return {
...toRefs(reactiveData),
...methods,
};
},
};
</script>
<style scoped>
#demo {
width: 100px;
height: 100px;
position: relative;
border: 3px dashed #dcdcdc;
display: flex;
justify-content: center;
align-items: center;
margin-left: 1em;
margin-top: 1em;
}
#input-file {
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
}
#upload-img {
display: block;
width: 50px;
height: 50px;
}
#look {
width: 70vh;
display: flex;
flex-wrap: wrap;
justify-content: left;
align-items: center;
}
#look-img {
width: 100px;
height: 100px;
margin-left: 1em;
margin-top: 1em;
display: flex;
justify-content: space-around;
}
#look-img img {
display: block;
width: 100px;
height: 100px;
cursor: pointer;
}
#look-operate {
background: rgba(0, 0, 0, 0.6);
width: 100px;
height: 0px;
position: absolute;
transition: 1s;
display: flex;
justify-content: center;
align-items: center;
}
#look-operate img {
display: block;
width: 2em;
height: 0em;
cursor: pointer;
}
#look-img:hover #look-operate {
height: 100px;
/* opacity: 50%; */
}
#look-img:hover #look-operate > img {
height: 2em;
}
#preview {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
#preview img {
width: 40%;
}
#preview-close {
position: absolute;
top: 40px;
right: 0;
display: flex;
justify-content: center;
}
#preview-pre {
position: absolute;
left: 0;
top: 50%;
display: flex;
justify-content: center;
}
#preview-next {
position: absolute;
right: 0;
top: 50%;
display: flex;
justify-content: center;
}
</style>
vue组件v-viewer 图片预览
最新推荐文章于 2024-08-10 17:04:19 发布