由于作者并非专业前台开发人员,是一位后端开发者,组件也是与我们前台人员查询资料合并的;由于时间过长已也没保存那些资料博客资料,如有不妥处请联系我;QQ:1836302994 。
这是作者开发的时候遇到的问题,希望可以帮到你。此组件在电脑界面测试时,会出现时灵时不灵的情况,但在手机上使用时无此情况发生。
如遇到问题大家可以相互交流;如需要后台代码也可Q我,由于作者时间有限,每周五晚上8点可以找我。
组件中使用了BASE64编码 后台需要BASE64解码
import PhotoSwipe from "photoswipe";
import PhotoSwipeUI_Default from "photoswipe/dist/photoswipe-ui-default";
import "photoswipe/dist/photoswipe.css";
import "photoswipe/dist/default-skin/default-skin.css";
import { Toast } from "mint-ui";
export default {
name:'upload-box',
data() {
return {
// lang: this.$lang("dynamic"),
files: [], // 文件缓存
index: 0, // 序列号
maxLength: 9, // 图片最大数量
maxSize: 10240000 //图片限制为10M内
};
},
methods: {
//选择图片
selectImgs() {
let fileList = this.$refs.file.files;
if (fileList.length > 9) {
alert(this.lang.dynamic_upload_tips);
}
let tempList = []; //每次点击+号后选择的图片信息
for (let i = 0, len = fileList.length; i < len; i++) {
let fileItem = {
Id: this.index++,
name: fileList[i].name,
size: fileList[i].size,
file: fileList[i]
};
//将图片文件转成Base64
let reader = new FileReader();
reader.onloadend = e => {
this.getBase64(e.target.result).then(url => {
this.$set(fileItem, "src", url);
});
};
if (fileItem.size > this.maxSize) {
Toast(this.lang.dynamic_over_size);
} else {
reader.readAsDataURL(fileList[i]);
tempList.push(fileItem);
this.files.push(fileItem);
}
}
setTimeout(() => {
this.$emit("getFiles", tempList);
}, 300);
this.files.splice(9);
},
// 图片压缩并保存到files
getBase64(url) {
let self = this;
let Img = new Image(),
dataURL = "";
Img.src = url;
let p = new Promise(function(resolve, reject) {
Img.onload = function() {
//要先确保图片完整获取到,这是个异步事件
let canvas = document.createElement("canvas"), //创建canvas元素
width = Img.width, //确保canvas的尺寸和图片一样
height = Img.height;
// 默认将长宽设置为图片的原始长宽,这样在长宽不超过最大长度时就不需要再处理
let ratio = width / height,
maxLength = 1000,
newHeight = height,
newWidth = width;
// 在长宽超过最大长度时,按图片长宽比例等比缩小
if (width > maxLength || height > maxLength) {
if (width > height) {
newWidth = maxLength;
newHeight = maxLength / ratio;
} else {
newWidth = maxLength * ratio;
newHeight = maxLength;
}
}
canvas.width = newWidth;
canvas.height = newHeight;
canvas.getContext("2d").drawImage(Img, 0, 0, newWidth, newHeight); //将图片绘制到canvas中
dataURL = canvas.toDataURL("image/jpeg", 0.5); //转换图片为dataURL
resolve(dataURL);
};
});
return p;
},
// 移除图片
remove(index, e) {
e.stopPropagation(); //阻止
this.files.splice(index, 1);
setTimeout(() => {
this.$emit("removeFiles", index);
}, 300);
},
//引入photoSwipe(可预览、滑动)
initPhotoSwipeFromDOM(gallerySelector) {
var parseThumbnailElements = function(el) {
var thumbElements = el.childNodes,
numNodes = thumbElements.length,
items = [],
figureEl,
linkEl,
size,
item;
for (var i = 0; i < numNodes - 1; i++) {
figureEl = thumbElements[i];
if (figureEl.nodeType !== 1) {
continue;
}
linkEl = figureEl.children[0];
var img = new Image();
img.src = linkEl.getAttribute("href");
linkEl.setAttribute(
"data-size",
img.naturalWidth + "x" + img.naturalHeight
);
size = linkEl.getAttribute("data-size").split("x");
item = {
src: linkEl.getAttribute("href"),
w: parseInt(size[0], 10),
h: parseInt(size[1], 10)
};
if (figureEl.children.length > 1) {
item.title = figureEl.children[1].innerHTML;
}
if (linkEl.children.length > 0) {
item.msrc = linkEl.children[0].getAttribute("src");
}
item.el = figureEl;
items.push(item);
}
return items;
};
var closest = function closest(el, fn) {
return el && (fn(el) ? el : closest(el.parentNode, fn));
};
var onThumbnailsClick = function(e) {
e = e || window.event;
// e.preventDefault ? e.preventDefault() : (e.returnValue = false);
var eTarget = e.target || e.srcElement;
var clickedListItem = closest(eTarget, function(el, e) {
return el.tagName && el.tagName.toUpperCase() === "FIGURE";
});
if (!clickedListItem) {
return;
}
var clickedGallery = clickedListItem.parentNode,
childNodes = clickedListItem.parentNode.childNodes,
numChildNodes = childNodes.length,
nodeIndex = 0,
index;
for (var i = 0; i < numChildNodes; i++) {
if (childNodes[i].nodeType !== 1) {
continue;
}
if (childNodes[i] === clickedListItem) {
index = nodeIndex;
break;
}
nodeIndex++;
}
if (index >= 0) {
openPhotoSwipe(index, clickedGallery);
}
return false;
};
var photoswipeParseHash = function() {
var hash = window.location.hash.substring(1),
params = {};
if (hash.length < 5) {
return params;
}
var vars = hash.split("&");
for (var i = 0; i < vars.length; i++) {
if (!vars[i]) {
continue;
}
var pair = vars[i].split("=");
if (pair.length < 2) {
continue;
}
params[pair[0]] = pair[1];
}
if (params.gid) {
params.gid = parseInt(params.gid, 10);
}
return params;
};
var openPhotoSwipe = function(
index,
galleryElement,
disableAnimation,
fromURL
) {
var pswpElement = document.querySelectorAll(".pswp")[0],
gallery,
options,
items;
items = parseThumbnailElements(galleryElement);
options = {
history: false,
tapToClose: true,
galleryUID: galleryElement.getAttribute("data-pswp-uid"),
getThumbBoundsFn: function(index) {
var thumbnail = items[index].el.getElementsByTagName("img")[0],
pageYScroll =
window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return { x: rect.left, y: rect.top + pageYScroll, w: rect.width };
}
};
if (fromURL) {
if (options.galleryPIDs) {
for (var j = 0; j < items.length; j++) {
if (items[j].pid == index) {
options.index = j;
break;
}
}
} else {
options.index = parseInt(index, 10) - 1;
}
} else {
options.index = parseInt(index, 10);
}
if (isNaN(options.index)) {
return "";
}
if (disableAnimation) {
options.showAnimationDuration = 0;
}
gallery = new PhotoSwipe(
pswpElement,
PhotoSwipeUI_Default,
items,
options
);
gallery.init();
};
var galleryElements = document.querySelectorAll(gallerySelector);
for (var i = 0, l = galleryElements.length; i < l; i++) {
galleryElements[i].setAttribute("data-pswp-uid", i + 1);
galleryElements[i].onclick = onThumbnailsClick;
}
var hashData = photoswipeParseHash();
if (hashData.pid && hashData.gid) {
openPhotoSwipe(
hashData.pid,
galleryElements[hashData.gid - 1],
true,
true
);
}
}
},
mounted() {
this.initPhotoSwipeFromDOM(".my-gallery");
}
};
#imgUploader {
flex: 1;
margin-top: auto;
padding-left: 10px;
.file-list {
padding: 10px 0px;
&::after {
content: "";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
font-size: 0;
}
.file-remove {
position: absolute;
font-size: 12px;
right: 5px;
top: 1px;
width: 14px;
height: 14px;
color: white;
cursor: pointer;
line-height: 12px;
background: rgba(0, 0, 0, 0.25);
z-index: 1000;
}
&:hover .file-remove {
display: inline;
}
}
}
.add {
width: 100%;
height: 110px;
float: left;
text-align: center;
line-height: 110px;
// font-size: 1.4rem;
font-weight: 100;
cursor: pointer;
border: 1px dashed #ccc;
color: #999;
position: relative;
// background: #f2f2f2;
@media screen and(min-width:768px) and(max-width:1024px) {
height: 180px;
line-height: 180px;
font-size: 56px;
}
.fa {
font-size: 1.4em;
color: #7dd2d9;
}
}
.uploadBtn {
position: relative;
.empty {
position: absolute;
right: 0;
bottom: 0;
background-color: #eee;
color: #fff;
padding: 0.2em 1em;
}
}
.thumbnails {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
.thumbnail {
position: relative;
margin: 0 0 10px 0;
padding-right: 5px;
width: 33%;
box-sizing: border-box;
height: 110px;
@media screen and(min-width:768px) and(max-width:1024px) {
height: 180px;
}
// &:nth-child(3n){
// padding-right: 0;
// }
.img-wrapper {
position: relative;
display: flex;
height: 110px;
@media screen and(min-width:768px) and(max-width:1024px) {
height: 180px;
}
img {
width: auto;
height: auto;
width: 100%;
max-width: 100%;
max-height: 100%;
}
}
}
}
input[type="file"] {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 110px;
opacity: 0;
}