vue + axios 上传图片到七牛组件
2019-11-12 本文已影响0人
索哥来了
关联文章,axios的封装:https://www.jianshu.com/p/f3268f923465
里面代码没有整理,可以直接抠出自己需要的部分
<template>
<div>
<div class="c" v-if="onlyShow" :class="{imgParPr: (canHover && !hoverInBox)}">
<div class="uploadImg_common_100_100" :class="{sizeNotFixed:sizeNotFixed}" v-for="(val,ind) in myImgArr" :key="ind">
<img :src="val" @mouseenter="showPic(val,$event)" @mouseleave="hidePic">
<em class="sw1" v-if="ind == 0 && !!showWords && showWords.type==1"><em>{{showWords.msg}}</em></em>
</div>
</div>
<div class="c" v-else :class="{disabledPar:disabled, imgParPr: (canHover && !hoverInBox)}">
<draggable v-model="myImgArr" :animation="500" @change="sortChange">
<div class="uploadImg_common_100_100" :class="{sizeNotFixed:sizeNotFixed}" v-for="(val,ind) in myImgArr" :key="ind">
<input class="file" type="file" accept="image/png,image/jpeg,image/gif" @change="update($event,1,ind)" @mouseenter="showPic(val,$event)" @mouseleave="hidePic"/>
<img :src="val">
<em class="sw1" v-if="ind == 0 && !!showWords && showWords.type==1"><em>{{showWords.msg}}</em></em>
<i class="el-icon-circle-close remove" @click.prevent="remove(ind)"></i>
</div>
</draggable>
<div class="uploadImg_common_100_100" v-if="!(limitLen && limitLen>0) || (limitLen && limitLen>0 && myImgArr.length < limitLen)">
<input class="file" type="file" accept="image/png,image/jpeg,image/gif" multiple="multiple" @change="update($event,2)"/>
<i class="el-icon-plus add"></i>
</div>
</div>
<p class="uploadImg_tips" v-if="tips">{{tips}}</p>
</div>
<!-- Ex -->
<!-- <upload-multiimg
:imgArr.sync = "formData.detail_arr"
tips = "图片尺寸比例建议750*750px"
:valid="{w:1,h:1}"
:limitLen = "5"
></upload-multiimg> -->
</template>
<script>
import draggable from 'vuedraggable'
import myfetch from '@/function/fetch'
export default{
data(){
return {
qiniuhost : this.$globalConfig.qiniuhost + '/',
upUrl : this.$globalConfig.qiniu_upUrl,
upToken : null,
pl_picArr_once : [],//批量上传图片,用来暂时保存顺序
myImgArr : [],
}
},
props:{
imgArr : Array,
tips : String,
valid : Object,//{w:1,h:1} 比例校验,不传则不校验
// 也可拓展其他校验,比如大小校验,后续有需要再加
disabled : {
type : Boolean,
default : false
},
sizeNotFixed: {
type : Boolean,
default : false
},
limitLen : Number,//选填,传了则大于这个值的时候 不再显示加号
canHover: {//鼠标移上去显示大图
type: Boolean,
default: false
},
hoverInBox: {//配合canHover使用,true表示是在弹框里面,false表示直接在页面上
type: Boolean,
default: true
},
onlyShow: {//仅仅只是展示,不能编辑,页面效果还是和之前一样,去掉删除和新增
type: Boolean,
default: false
},
showWords: Object,//根据type来定,目前已定:type=1 取msg字段放在第一张图的顶部
},
components: {
draggable
},
created(){
this.myImgArr = [].concat(this.imgArr);
},
watch: {
imgArr(val) {
this.myImgArr = [].concat(val);//监听外部对props属性的变更,避免弹框使用v-show的时候 组件后面不会再赋值
},
},
methods:{
showPic(val,e){
if(this.canHover){
this.$commonFun.imgMouseleave();
this.$commonFun.imgMouseenter(val, e, this.hoverInBox);
}
},
hidePic(val,e){
if(this.canHover){
this.$commonFun.imgMouseleave();
}
},
getToken(){
this.$ajax.get('/common/uptoken',{}).then(res=>{
this.upToken = res;
})
},
uploading(param,config,pathName,cb){
//使用axios
/*this.$ajax.post(this.upUrl,param,config)
.then(response=>{
cb(response)
})*/
//使用fetch
myfetch(this.upUrl, param, 'post')
.then(res => {
cb(res)
})
},
update(e,upLoadType,ind){
/*
e : event
upLoadType : 1-单张替换上传 2-多张上传(+号上传)
ind : 数字,数组里面第几个修改,单张替换需要
*/
let me = this;
let file;
me.pl_picArr_once = [];// 清空
let bl_count = 0;//记录比例不正确的值
let has_upload = 0;//已经上传的
if(upLoadType != 2){
file = e.target.files[0];
if(file){
thisUpFun(file);
}
}else{
let file_arr = e.target.files;
if(file_arr && file_arr.length>0){
for(let i =0;i<file_arr.length;i++){
if(i<file_arr.length){
thisUpFun(file_arr[i],file_arr.length,(i+1));
}
}
}
}
function thisUpFun(file,totalInd,thisInd){
let param = new FormData(); //创建form对象
param.append('file',file,file.name)
// console.log(param.get('file')); //FormData私有类对象,访问不到,可以通过get判断值是否传进去
let config = {
headers:{'Content-Type':'multipart/form-data'}
};
if(me.upToken){
param.append('token',me.upToken);
me.uploading(param,config,file.name,function(res){
callBack(res,totalInd,thisInd);
});
}else{
me.$ajax.get('/common/uptoken',{}).then(res=>{
me.upToken = res;
param.append('token',me.upToken);
me.uploading(param,config,file.name,function(res){
callBack(res,totalInd,thisInd);
});
})
}
}
e.target.setAttribute('type','text');
e.target.setAttribute('type','file');
function callBack(res,totalInd,thisInd){
let newArr = [].concat(me.myImgArr);
if(upLoadType != 2){
// 单张替换上传
if(me.valid && me.$commonFun.testInt(me.valid.w) && me.$commonFun.testInt(me.valid.h)){
let w = Number(me.valid.w),
h = Number(me.valid.h);
if(me.$commonFun.multi(res.h , w) != me.$commonFun.multi(res.w , h)){
me.$message('图片尺寸比例必须'+w+':'+h+'!');
return false;
}
newArr[ind] = me.qiniuhost +res.key;
}else{
newArr[ind] = me.qiniuhost +res.key;
}
me.myImgArr = [].concat(newArr);
}else{
has_upload += 1;
if(me.valid && me.$commonFun.testInt(me.valid.w) && me.$commonFun.testInt(me.valid.h)){
let w = Number(me.valid.w),
h = Number(me.valid.h);
if(me.$commonFun.multi(res.h , w) != me.$commonFun.multi(res.w , h)){
bl_count += 1;
}else{
me.pl_picArr_once.push({
ind : Number(thisInd),
src : me.qiniuhost +res.key
})
}
}else{
me.pl_picArr_once.push({
ind : Number(thisInd),
src : me.qiniuhost +res.key
})
}
if(totalInd && has_upload == totalInd){
let arr = [].concat(me.pl_picArr_once);
me.pl_picArr_once = [];
arr.sort((a,b)=>{
return a.ind - b.ind;
});
let arr_src = [];
arr.forEach(function(v,i){
arr_src.push(v.src)
})
me.myImgArr = me.myImgArr.concat(arr_src);
if(bl_count>0){
me.$message('所选图片中,有'+(totalInd-bl_count)+'张上传成功,'+bl_count+'张上传失败,尺寸比例应为'+me.valid.w+':'+me.valid.h+'!');
return false;
}
}
}
me.$emit('update:imgArr',me.myImgArr);
}
},
remove(ind){
this.myImgArr.splice(ind, 1);
this.$emit('update:imgArr',this.myImgArr);
},
sortChange(){
// console.log(this.myImgArr)
this.$emit('update:imgArr',this.myImgArr);
}
}
}
</script>
<style lang="scss" scoped>
.uploadImg_common_100_100{
width: 98px;
height: 98px;
border: 1px dashed #d9d9d9;
cursor: pointer;
position: relative;
float: left;
margin-bottom: 10px;
margin-right: 10px;
background: #eee;
.file {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
opacity: 0;
cursor: pointer;
z-index: 9;
}
.add {
font-size: 28px;
color: #8c939d;
width: 100%;
height: 100%;
line-height: 98px;
text-align: center;
}
img {
width: 98px;
max-height: 98px;
}
.remove {
position: absolute;
right: -8px;
top: -8px;
font-size: 16px;
z-index: 10;
background:#fff;
border-radius: 50%;
}
.sw1{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 20px;
line-height: 20px;
text-align: center;
background: rgba(0,0,0,.5);
color: #fff;
font-size: 12px;
}
}
.uploadImg_common_100_100.sizeNotFixed{
img {
width: auto;
height: auto;
max-width: 98px;
max-height: 98px;
}
}
.disabledPar{
.uploadImg_common_100_100{
cursor: not-allowed !important;
opacity: .8!important;
input[type="file"]{
display: none;
}
}
}
.margin_none{
.uploadImg_common_100_100{
margin-right: 0;
margin-bottom: 0;
}
}
.imgParPr{
padding-right: 400px;
}
.mainPic_par{
.uploadImg_common_100_100:first-child{
&:before{
content: 'SKU主图';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 20px;
line-height: 20px;
text-align: center;
background: rgba(0,0,0,.5);
font-size: 12px;
color: #fff;
}
}
}
</style>