- 项目难点总结,用法示例demo;
- 实现移动端可组图预览,调用本地相册、拍照上传图片,支持图片增删;
- 基于Vue+webpack+sfmui框架。
组图浏览:可浏览一组网络图片
调用示例:
Var imgUrls = [ 0, "http://10.202.32.117:8080/KMS/mobile/images/001/498/199153/14ac7dd0-3ed8-4c71-9550-4ad57f14e668.jpg"]
StartMedia.startKmsPicBroswer (imgUrls)
//组图数据,imgUrls [0]为当前浏览图片在数组的下标(0~n-1),imgUrls [1]为第1张图片地址…imgUrls [n]为第N张图片地址
复制代码
应用demo:
<div class="">
<div class="preview-img" v-for="(imgUrl,index) in imgUrlArr" :key="index">
<img :src="imgUrl" @click="previewImg(imgUrl,imgUrlArr)"/>
</div>
</div>
复制代码
previewImg(imgUrl,imgArr){
const data=[];
for (let i=0,let n=imgArr.length; i<n; i++){
if (imgArr[i] === imgUrl){
data.push(i);
}
}
const resultData= data.concat(imgArr);
console.info("图片预览:"+resultData);
StartMedia.startKmsPicBroswer (resultData);
}
复制代码
压缩图片:根据本地路径压缩一张图片
调用示例:
Var imgPath = “/storage/emulated/0/team_qrcode.jpg”;//原图路径
function success (pressedImgPath){//成功压缩后图片路径
}
function failed (error){//失败信息
}
ExpressPlugin.compress(success, failed,imagePath);
复制代码
应用demo:本地图片或拍照图片增删且可点击预览,压缩上传
<div class="upload-box">
<v-cell class="upload-cell" title="上传照片">
<i :style="{'backgroundImage': 'url('+require('../../assets/upLoad.svg')+')'}" slot="icon"></i>
</v-cell>
<div class="flex flex-hw">
<div class="upload-img" v-for="(imgUrl,index) in imgUrlArr" :key="index">
<v-icon type="cancel" @click.native="handleDeleteImg(index)"></v-icon>
<img :src="item.thumbnail" @click="previewImg(imgUrl.thumbnail,imgUrlArrCoyp)"/>
</div>
<div class="upload-add" @click="isActionsheet = true" v-if="imgUrlArr.length < 5">
<v-icon type="plus"></v-icon>
</div>
</div>
<v-actionsheet v-model="isActionsheet" :menus="actionsheetMenus" @on-click-menu="handleActionsheet" show-cancel></v-actionsheet>
</div>
复制代码
methods:
previewImg(imgUrl,imgUrlArrCopy){//组图浏览:imgUrlArrCopy为imgUrlArr数组对象转化成数组
const urlData=[];
for (var i=0,n=imgArr1.length; i<n; i++){
if (imgUrlArrCopy[i] === imgUrl){
urlData.push(i);
}
}
const resultData= urlData.concat(imgArr1);
console.info("图片预览:"+resultData);
StartMedia.startKmsPicBroswer (resultData);
},
//获取本地图片 handleActionsheet(a, b) { console.log(a, b) if(a === "menu1") {//menu1:拍照this.$takePhoto(this.acquireSuccess, this.acquireError)//调用手机摄像头 } else if(a==="menu2"){//menu2:相册this.$openAlbum(this.acquireSuccess, this.acquireError)//调用手机相册 }},
acquireSuccess(imageInfo) {//选择拍照或者相册上传成功的回调函数,可从函数参数中获取图片信息对象,包含原图(original)和缩略图(thumbnail)两个字段,分别表示对应图片的路径;
if(this.$getIsIOS()) {
var str = "";
str = imageInfo;
str = str.replace(/\n/g, '');
var obj1 = JSON.parse(str);
var that = this;
that.imgArr.push(obj1);
} else {
this.imgArr.push(imageInfo);
}
},
acquireError(type, a) {
this.$toast.show({
text: '调取失败',
})
},
复制代码
//开始压缩上传本地图片
startUpload(){
this.imageArrayUrlCopy = []
this.imgArrId = []
this.imageCompressIndex = 0
this.imageTransferIndex = 0
if(this.imgUrlArr.length){
if(this.imageCompressIndex >= this.imgUrlArr.length-1){
this.$compressFile(this.imgUrlArr[this.imageCompressIndex].original, this.compressSuccessSubmit, this.onFail);
return true;
}else{
this.$compressFile(this.imgUrlArr[this.imageCompressIndex].original, this.compressSuccess, this.onFail);
return true;
}
}else{
return false
}
},
compressSuccess(imgurl) {
this.imageCompressIndex++;
this.imageArrayUrlCopy.push(imgurl);
if(this.imageCompressIndex >= this.imgUrlArr.length - 1) {
this.$compressFile(this.imgUrlArr[this.imageCompressIndex].original, this.compressSuccessSubmit, this.onFail);
} else {
this.$compressFile(this.imgArr[this.imageCompressIndex].original, this.compressSuccess, this.onFail);
}
},
compressSuccessSubmit(imgUrl) {
//最后一张图片压缩后回调方法,并上传图片
this.imageArrayUrlCopy.push(imgUrl);
if(this.imageArrayUrlCopy && this.imageArrayUrlCopy.length > 0) {
if(this.imageTransferIndex >= this.imageArrayUrlCopy.length - 1) {
//当上传图片为最后一张时提交表单
this.$transferImageToService(
this.$axios.defaults.baseURL + "attachment/uploadFiles",
this.imageArrayUrlCopy[this.imageTransferIndex],
this.onSuccessSubmit,
this.onFail
);
} else {
this.$transferImageToService(
this.$axios.defaults.baseURL + "attachment/uploadFiles",//附件上传后台地址=>返回附件ID
this.imageArrayUrlCopy[this.imageTransferIndex],
this.onSuccess,
this.onFail
);
}
}
},
onSuccess(imgUploadData) {
this.imageTransferIndex++;
if(imgUploadData.succ === "ok") {
this.imgArrId.push(imgUploadData.msg)
}
console.log(imgUploadData, "onSuccess")
if(this.imageTransferIndex >= this.imageArrayUrlCopy.length - 1) {
//当上传图片为最后一张时提交表单
this.$transferImageToService(
this.$axios.defaults.baseURL + "attachment/uploadFiles",
this.imageArrayUrlCopy[this.imageTransferIndex],
this.onSuccessSubmit,
this.onFail
);
} else {
this.$transferImageToService(
this.$axios.defaults.baseURL + "attachment/uploadFiles",
this.imageArrayUrlCopy[this.imageTransferIndex],
this.onSuccess,
this.onFail
);
}
},
onSuccessSubmit(imgUploadData) {
console.log("onSuccessSubmit")
if(imgUploadData.succ === "ok") {
this.imgArrId.push(imgUploadData.msg)
}
this.$emit("onSuccessUpload",imgID)//子组件传递id值给父组件
this.$deleteFiles(this.imageArrayUrlCopy);
},
onFail(mess) {
//关闭loading拦截
console.log(mess, "失败")
this.$loading.hide()
this.$toast.hide();
this.$toast.show({
text: mess,
})
},
handleDeleteImg(index){
this.imgUrlArr.splice(index,1)
}
watch:
watch:{
imgUrlArr(){
for(let i=0;i<imgUrlArr.lenght;i++){
this.imgUrlArrCoyp.push(imgUrlArr[i].thumbnail)
}
}
}
复制代码
综合前面两点,实现=>本地组图压缩上传+组图浏览
-
背景:用户调整修改已提交信息,页面加载用户之前已提交信息,包括图片,此时图片以网络图片形式预览。
-
问题:压缩上传图片只能是本地路径图片,网络图片会报错。
-
解决方案:区别本地图片与网络图片,只压缩本地图片,最后提交时再拼接网络图片ID提交给后台。
- 备注:图片模块抽离成子组件,图片的增删改以及本地图片压缩上传后所得图片id通过this.emit()=>父组件。父组件原有网络图片信息通过:obj="obj"=>子组件
1、如果有增加本地图片,触发子组件拼接新imgID
- demo
<template>
<div class="upload-box">
<v-cell class="upload-cell" title="上传照片(非必填)">
<i :style="{'backgroundImage': 'url('+require('../../assets/upLoad.svg')+')'}" slot="icon"></i>
</v-cell>
<div class="flex flex-hw">
<div class="upload-img" v-for="(item,index) in imgArr" :key="index">
<v-icon type="cancel" @click.native="handleDeleteImg(index)"></v-icon>
<img :src="item.thumbnail" @click="previewImg(item.thumbnail,imgArr1)"/>
</div>
<div class="upload-add" @click="isActionsheet = true" v-if="imgArr.length < 5">
<v-icon type="plus"></v-icon>
</div>
</div>
<v-actionsheet v-model="isActionsheet" :menus="actionsheetMenus" @on-click-menu="handleActionsheet" show-cancel></v-actionsheet>
</div>
</template>
复制代码
<script>
export default {
props:{
obj:Object
},
created(){
this.getFatherData()
},
data() {
return {
deleteHttpImgID:'',
httpStr:"http://imgload?fileId=",
httpImgArrID:[],
imgArr:[],//表示包含图片两个路径(一个原图路径,一个缩略图路径)的图片信息对象
imageArrayUrlCopy:[],
imgArr1:[],
imgArrId:[],
imageCompressIndex:0,
imageTransferIndex:0,
isActionsheet:false,
actionsheetMenus: {
menu1: '拍照',
menu2: '从相册选择'
},
}
},
methods: {
previewImg(imgurl,imgArr1){
var urldata=[];
for (var i=0,n=imgArr1.length; i<n; i++){
if (imgArr1[i] === imgurl){
urldata.push(i);
}
}
var resultData= urldata.concat(imgArr1);
console.info("图片预览:"+resultData);
StartMedia.startKmsPicBroswer (resultData);
},
getFatherData(){
console.log(this.obj+'upload父元素对象')
if(this.obj){
this.imgArr=this.obj.imgurlArr
this.imgArr1=this.obj.imgurlArr1
console.log(this.obj.imgurlArr+'****'+this.obj.imgurlArr1+'upload获取父元素图片数据')
}
},
handleActionsheet(a, b) {
console.log(a, b)
if(a === "menu1") {
this.$takePhoto(this.acquireSuccess, this.acquireError)
} else if(a==="menu2"){
this.$openAlbum(this.acquireSuccess, this.acquireError)
}
},
acquireSuccess(imageInfo) {//选择拍照或者相册上传成功的回调函数,可从函数参数中获取图片信息对象,包含原图(original)和缩略图(thumbnail)两个字段,分别表示对应图片的路径;
if(this.$getIsIOS()) {
var str = "";
str = imageInfo;
str = str.replace(/\n/g, '');
var obj1 = JSON.parse(str);
var that = this;
that.imgArr.push(obj1);
} else {
this.imgArr.push(imageInfo);
}
console.log(this.imgArr, "acquireSuccess")
},
acquireError(type, a) {
this.$toast.show({
text: '调取失败',
})
},
onFail(mess) {
//关闭loading拦截
console.log(mess, "失败")
this.$loading.hide()
this.$toast.hide();
this.$toast.show({
text: mess,
})
},
startUpload(){
// 开始上传图片时,统一删除所有网络图片
var count=[];
this.imgArr.forEach((item,index) => {
if(item.original.indexOf(this.httpStr)!=-1){
count.push(index)
console.log('网络图片索引'+index)
this.httpImgArrID.push(item.original.replace(this.httpStr,''))
console.log(this.httpImgArrID+'**httpID数组**')
}
});
if(count.length>0){
this.imgArr.splice(0,count.length)
}
this.imageArrayUrlCopy = []
this.imgArrId = []
this.imageCompressIndex = 0
this.imageTransferIndex = 0
if(this.imgArr.length){
if(this.imageCompressIndex >= this.imgArr.length-1){
this.$compressFile(this.imgArr[this.imageCompressIndex].original, this.compressSuccessSubmit, this.onFail);
return true;
}else{
this.$compressFile(this.imgArr[this.imageCompressIndex].original, this.compressSuccess, this.onFail);
return true;
}
}else{
return false
}
},
compressSuccess(imgurl) {
this.imageCompressIndex++;
this.imageArrayUrlCopy.push(imgurl);
if(this.imageCompressIndex >= this.imgArr.length - 1) {
this.$compressFile(this.imgArr[this.imageCompressIndex].original, this.compressSuccessSubmit, this.onFail);
} else {
this.$compressFile(this.imgArr[this.imageCompressIndex].original, this.compressSuccess, this.onFail);
}
console.log("compressSuccess"+imgurl)
},
compressSuccessSubmit(imgUrl) {
//最后一张图片压缩后回调方法,并上传图片
console.log("compressSuccessSubmit0")
this.imageArrayUrlCopy.push(imgUrl);
if(this.imageArrayUrlCopy && this.imageArrayUrlCopy.length > 0) {
if(this.imageTransferIndex >= this.imageArrayUrlCopy.length - 1) {
//当上传图片为最后一张时提交表单
this.$transferImageToService(
this.$axios.defaults.baseURL + "attachment/uploadFiles",
this.imageArrayUrlCopy[this.imageTransferIndex],
this.onSuccessSubmit,
this.onFail
);
} else {
this.$transferImageToService(
this.$axios.defaults.baseURL + "attachment/uploadFiles",
this.imageArrayUrlCopy[this.imageTransferIndex],
this.onSuccess,
this.onFail
);
}
}
console.log("compressSuccessSubmit", this.imageArrayUrlCopy)
},
onSuccess(imgUploadData) {
this.imageTransferIndex++;
if(imgUploadData.succ === "ok") {
this.imgArrId.push(imgUploadData.msg)
}
console.log(imgUploadData, "onSuccess")
if(this.imageTransferIndex >= this.imageArrayUrlCopy.length - 1) {
//当上传图片为最后一张时提交表单
this.$transferImageToService(
this.$axios.defaults.baseURL + "attachment/uploadFiles",
this.imageArrayUrlCopy[this.imageTransferIndex],
this.onSuccessSubmit,
this.onFail
);
} else {
this.$transferImageToService(
this.$axios.defaults.baseURL + "attachment/uploadFiles",
this.imageArrayUrlCopy[this.imageTransferIndex],
this.onSuccess,
this.onFail
);
}
},
onSuccessSubmit(imgUploadData) {
console.log("onSuccessSubmit")
if(imgUploadData.succ === "ok") {
this.imgArrId.push(imgUploadData.msg)
}
//把提交时统一删除的网络图片id拼接回来
if(this.httpImgArrID.length>0){
var totalIDArr=this.httpImgArrID.concat(this.imgArrId)
var imgID=totalIDArr.join(",")
console.log(imgID+'我是最后成功的全部ID');
}else{
var imgID = this.imgArrId.join(",")
console.log(imgID+'我是最后成功的ID');
}
this.$emit("onSuccessUpload",imgID)
this.$deleteFiles(this.imageArrayUrlCopy);
},
handleDeleteImg(index){
//在未上传本地照片的情况下,删除的如果是http图片,需要单独告知父元素判断
if(this.imgArr[index].original.indexOf(this.httpStr)!=-1){
this.deleteHttpImgID=this.imgArr[index].original.replace(this.httpStr,'')
console.log(this.deleteHttpImgID)
this.$emit('deleteHttpImgArrIDFromUpload',this.deleteHttpImgID)
this.imgArr.splice(index, 1)
}else{
this.imgArr.splice(index, 1)
}
}
}
}
</script>
复制代码
<style lang="less" scoped="scoped">
.upload-box {
background-color: #fff;
.upload-cell {
margin-top: 10px;
&:before {
content: initial;
}
i {
background-repeat: no-repeat;
background-size: contain;
display: inline-block;
width: 20px;
height: 17px;
vertical-align: middle;
margin-right: 5px;
}
}
.flex {
padding-bottom: 10px;
}
.upload-add,
.upload-btn,
.upload-img {
margin-left: 10px;
margin-top: 10px;
box-sizing: border-box;
background: #FFFFFF;
border: 1px solid #DDDDDD;
border-radius: 3px;
width: 80px;
height: 80px;
text-align: center;
font-size: 28px;
line-height: 1.6rem;
line-height: 80px;
&.upload-add {
color: #ccc;
}
&.upload-btn {
color: #999;
}
&.upload-img {
position: relative;
line-height: 74px;
img {
width: 100%;
height: 100%;
}
.smui-icon-cancel {
position: absolute;
top: -10px;
left: -10px;
font-size: 16px;
color: #ccc;
}
}
}
}
</style>
复制代码
2、在无本地图片上传情况下,由于未调用子组件id拼接,传递最新id值给父组件,所以父组件需要接收此时更改(删除)后的网络图片id做特殊情况的记录,父组件匹配删除id后,再将剩余网络图片id发送至后台。
- demo
// 父子传值,记录子组件传递过来的删除了的http类型图片
deleteHttpImgArrIDFromUpload(deleteID){
// this.deleteHttpImgID=deletID
for(let i=0;i<this.oldFileIDsArr.length;i++){
if(this.oldFileIDsArr[i]==deleteID){
this.oldFileIDsArr.splice(i,1)
}
}
console.log('接受到的删除的网络图片id'+deleteID)
console.log(this.oldFileIDsArr+'原来的httpid数组')
}
复制代码
// 在未上传本地照片或者拍照情况下,提交剩余的http图片id
if(that.oldFileIDsArr.length>0){
var oldimgID=that.oldFileIDsArr.join(",")
console.log('撤销页面自己http图片id'+oldimgID)
that.onSubmit(oldimgID);
}else{
that.onSubmit();
}
复制代码