Vue怎么实现图片裁剪功能(vue,开发技术)

时间:2024-05-04 00:42:40 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

',
type:'error'
})
}
}).finally(()=>{
_this.loading=false
})
})

/if(flag){
this.$message.warning('请选择图片')
}
/
}
},
createNewFileName(){
//constnow=Date.now()
//constfileName=now+'-'+Math.ceil(Math.random()*100)
//returnfileName+'.jpg'
constfileName=regularFileName()
returnfileName+'.jpg'
}
}
}
</script>

<stylescopedlang="scss">
.cropper-content{
display:flex;
display:-webkit-flex;
justify-content:flex-end;
.cropper-box{
flex:1;
width:100%;
.cropper{
width:auto;
height:300px;
}
}

.show-preview{
flex:1;
-webkit-flex:1;
display:flex;
display:-webkit-flex;
justify-content:center;
.preview{
overflow:hidden;
border:1pxsolid#67c23a;
background:#cccccc;
}
}
}
.footer-btn{
margin-top:30px;
display:flex;
display:-webkit-flex;
justify-content:flex-end;
.scope-btn{
display:flex;
display:-webkit-flex;
justify-content:space-between;
padding-right:10px;
}
.upload-btn{
flex:1;
-webkit-flex:1;
display:flex;
display:-webkit-flex;
justify-content:center;
}
.btn{
outline:none;
display:inline-block;
line-height:1;
white-space:nowrap;
cursor:pointer;
-webkit-appearance:none;
text-align:center;
-webkit-box-sizing:border-box;
box-sizing:border-box;
outline:0;
-webkit-transition:0.1s;
transition:0.1s;
font-weight:500;
padding:8px15px;
font-size:12px;
border-radius:3px;
color:#fff;
background-color:#409eff;
border-color:#409eff;
margin-right:10px;
}
}
</style>

需要更改成自己的上传接口:

import{uploadFile}from'@/api/smrz/setting'

后台接口参数如下,要求表单方式上传

/*
上传附件

@paramfile文件流(注意带文件后缀,统一使用.jpg结尾)
@paramfileName文件名称(唯一性)
@parambusType业务类型(具体值参考ApiConstants类中FILE_开头常量说明)
@authorwangkun
@createTime2022/7/1917:18
*/
@PostMapping(value="/file/upload",consumes="multipart/form-data")
publicRpcResultuploadFile(@RequestParam(value="rpc")MultipartFilefile,@RequestParam(value="fileName")StringfileName,@RequestParam(value="busType")StringbusType){

在uploadImg函数这里,使用FormData对象包装请求参数

注意append方法,要给文件对象指定文件名,必须要入参第三个参数

否则默认名称blob

Vue怎么实现图片裁剪功能

按实际接口对应调整参数即可

constformData=newFormData()

_this.randomFileName=this.createNewFileName()

//给blob对象的filename属性赋值文件名
formData.append('rpc',data,_this.randomFileName)
//给参数赋值文件名
formData.append('fileName',_this.randomFileName)
formData.append('busType',_this.busType)

uploadFile(formData)

其它自定义参数,通过Props属性传入此组件

props:{
autoCropWidth:{//默认生成截图框宽度
type:Number,
default:410
},
autoCropHeight:{//默认生成截图框高度
type:Number,
default:150
},
busType:{
type:String,
default:'advertPic'
}
},

文件名的生成方法,就是当前时间按单位数值排序

实际使用根据业务实际情况改写

exportfunctionregularFileName(){
constnow=newDate()
constyear=now.getFullYear()
constmonth=digitFix(now.getMonth()+1)
constdayOfMonth=digitFix(now.getDate())
consthour=digitFix(now.getHours())
constminute=digitFix(now.getMinutes())
constsecond=digitFix(now.getSeconds())
constmillSecond=now.getMilliseconds()
return${year}${month}${dayOfMonth}${hour}${minute}${second}${millSecond}
}constfileName=`${regularFileName()}

3、【图片上传表单项】组件编写

<template>
<divclass="cropper-app">
<el-form
ref="ruleForm"
:model="formValidate"
:rules="ruleValidate"
label-width="110px"
class="demo-ruleForm"
>
<el-form-item
:label="label"
prop="mainImage"
>
<divclass="list-img-box">
<div
v-if="formValidate.mainImage!==''"
class="img_div"

>
<img
:src="formValidate.mainImage"
alt="图片找不到"
>
<ahref="#"rel="externalnofollow">
<divclass="mask">
<h4>
<i
class="el-icon-zoom-in"
@click="clickImg('zoom-in')"
/>

<i
class="el-icon-delete"
@click="clickImg('delete')"
/>
</h4>
</div>
</a>
</div>
<div
v-else
class="upload-btn"

@click="uploadPicture('flagImg')"
>
<i
class="el-icon-plus"

/>
<!--<span>封面设置</span>-->
</div>
</div>
<input
v-model="formValidate.mainImage"
type="hidden"
placeholder="请添加封面"
>
</el-form-item>
</el-form>
<!--剪裁组件弹窗-->
<el-dialog
v-if="cropperModel"
title="图片剪切"
:visible.sync="cropperModel"
width="1020px"
center
append-to-body
>
<cropper-image
v-if="cropperModel"
ref="child"
:auto-crop-width="autoCropWidth"
:auto-crop-height="autoCropHeight"
:bus-type="busType"
@uploadImgSuccess="handleUploadSuccess"
/>
</el-dialog>
<!--查看大封面-->
<el-dialog
title=""
:visible.sync="imgVisible"
center
append-to-body
>
<img
v-if="imgVisible"
:src="imgUrl"

alt="查看"
>
</el-dialog>
</div>
</template>

<script>
importCropperImagefrom'@/components/CropperImage'
import{commonsDownloadAPI}from'@/api/smrz/setting'
exportdefault{
name:'Tailoring',
components:{CropperImage},
props:{
label:{
type:String,
default:'上传图片'
},
url:{
type:String
},
autoCropWidth:{//默认生成截图框宽度
type:Number,
default:410
},
autoCropHeight:{//默认生成截图框高度
type:Number,
default:150
},
isSignFlag:{
type:Boolean,
default:false
},
busType:{
type:String,
default:'busType'
}
},

data(){
varimageUrl2=(rule,value,callback)=>{
if(!this.isSignFlag){
returncallback()
}
if(!value){
returncallback(newError('请输上传图片'))
}
returncallback()
}
return{
formValidate:{
mainImage:''
},
ruleValidate:{
mainImage:[
/{required:true,message:'请上传图片',trigger:'blur'}/
{required:true,validator:imageUrl2,trigger:'blur'}
]
},
//裁切图片参数
cropperModel:false,
cropperName:'',
imgUrl:'',
imgVisible:false,

dialogImageUrl:'',
dialogVisible:false
}
},
created(){
this.formValidate.mainImage=this.url
this.imgUrl=this.url
},
methods:{
validateForm(){
this.$refs['ruleForm'].validate((valid)=>{
this.$emit('validVal',valid)
})
},
//封面设置
uploadPicture(name){
this.cropperName=name
this.cropperModel=true
},
//图片上传成功后
asynchandleUploadSuccess(data){
//this.formValidate.mainImage=data.url

//图片回显
const{data:res2,code}=awaitcommonsDownloadAPI({
fileName:data.fileName,
busType:'advertPic'
})

constimgBase64=
code!==200
?'-1':data:image/jpeg;base64,${res2.data}
this.formValidate.mainImage=imgBase64

/switch(data.name){
case'flagImg':
this.formValidate.mainImage=data.url
console.log('最终输出'+data.name)
console.log('最终输出2'+this.formValidate)
break
}
/
this.cropperModel=false
this.$emit('uploadSuccess',data)
},
clickImg(val){
if(val==='delete'){
this.formValidate.mainImage=''
this.$emit('deleteImage')
}elseif(val==='zoom-in'){
//
this.imgUrl=this.formValidate.mainImage
this.imgVisible=true
}
}

}
}
</script>
<stylescoped>
.upload-list-cover{
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
display:flex;
flex-wrap:wrap;
justify-content:space-between;
padding:040px;
align-items:center;
background:rgba(0,0,0,0.6);
opacity:0;
transition:opacity1s;
}
.cover_icon{
font-size:30px;
}
.upload-btn{
display:-webkit-box;
display:-ms-flexbox;
display:flex;
-ms-flex-wrap:wrap;
flex-wrap:wrap;
-webkit-box-pack:center;
-ms-flex-pack:center;
justify-content:center;
-webkit-box-align:center;
-ms-flex-align:center;
align-items:center;
border:1pxsolid#cccccc;
border-radius:5px;
overflow:hidden;
box-shadow:001px#cccccc;
}
.upload-btn:hover{
border:1pxsolid#69b7ed;
}
.upload-btni{
margin:5px;
}

.img_divimg{
width:200px!important;
height:100px!important;
/margin:20px400px0400px;
position:relative;
width:531px;
height:354px;
/
}
.mask{
position:absolute;
top:0;
left:0;
width:200px;
height:100px;
background:rgba(101,101,101,0.6);
color:#ffffff;
opacity:0;
}
.maskh4{
text-align:center;
line-height:60px;
}

.img_diva:hover.mask{
opacity:0.8;
}
</style>

表单项组件需要引入

1、裁剪组件

2、图片下载接口

importCropperImagefrom'@/components/CropperImage'
import{commonsDownloadAPI}from'@/api/smrz/setting'

3、表单项设置了自定义校验

varimageUrl2=(rule,value,callback)=>{
if(!this.isSignFlag){
returncallback()
}
if(!value){
returncallback(newError('请输上传图片'))
}
returncallback()
}

就是检查src有没有地址或者base64资源,校验触发的效果:

Vue怎么实现图片裁剪功能

4、图片上传后的回调处理:

上传成功后,回到表单页需要立即回显之前上传的图片

所以需要调用图片下载接口来获取刚刚上传的资源,

在这个回调方法中实现,因为下载接口提供的资源不是图片地址,而是返回Base64编码

这里我写的是base64编码资源的回显处理

实际使用根据业务实际情况改写

//图片上传成功后
asynchandleUploadSuccess(data){
//this.formValidate.mainImage=data.url

//图片回显
const{data:res2,code}=awaitcommonsDownloadAPI({
fileName:data.fileName,
busType:'advertPic'
})

constimgBase64=
code!==200
?'-1':data:image/jpeg;base64,${res2.data}
this.formValidate.mainImage=imgBase64

/switch(data.name){
case'flagImg':
this.formValidate.mainImage=data.url
console.log('最终输出'+data.name)
console.log('最终输出2'+this.formValidate)
break
}
/
this.cropperModel=false
this.$emit('uploadSuccess',data)
},

4、业务功能引用

引入表单项

importTailoringfrom'@/components/Tailoring'

声明组件,并注入参数

<divclass="ant-upload-preview">
<tailoring
v-if="true"
ref="child"
label="广告图片"
:is-sign-flag="true"
:url="url"
:bus-type="businessType"
:auto-crop-height="80"
:auto-crop-width="410"
@uploadSuccess="uploadSuccess"
@validVal="validVal"
/>
</div>

- url是一开始加载组件需要回显的图片资源地址  

- isSignFlag变量用来辅助自定义校验的,为false时直接放行校验,所以默认写死true

- bus-type是自定义的业务参数

- auto-crop的宽高用来配置裁剪的宽高,预览大小和裁剪大小合并使用这两个参数

上传成功的回调,uploadSuccess,可以在组件自定义需要的参数

这里是以图片名称作为记录主键,所以要传入这个文件名

实际使用根据业务实际情况改写

asyncuploadSuccess(res){
console.log(上传结果res-&gt;${JSON.stringify(res)})
constfileName=res.fileName
this.newId=fileName.substring(0,fileName.lastIndexOf('.'))
},

校验值,应该是返回校验后的src值,但我这里没用上,所以不执行任何逻辑

validVal(val){},

要触发【裁剪表单项】校验,使用

this.$refs.child.validateForm()
这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

本文:Vue怎么实现图片裁剪功能的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:C#/VB.NET怎么创建PDF/UA文件下一篇:

20 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18