< Cropperref = " cropperRef" :imgUrl = " url" @searchImg = " searchImg" > </ Cropper> < template> < el- dialog : title= "title"  : visible. sync= "dialogVisible"  width= "1000px" > < input ref= "input"  type= "file"  name= "image"  @change= "setImage"  / > < div class = "flex justify-around" > < div class = "w-480px h-270px flex justify-center items-center" > < divv- show= "!imgSrc" @click= "showFileChooser" class = "w-full h-full flex cursor-pointer justify-center items-center border-1px border-dashed border-gray-300 rounded-lg" > < i class = "font-size-20px el-icon-plus avatar-uploader-icon" > < / i> < / div> < ! --  : aspect- ratio= "16 / 16"  -- > < vue- cropperv- show= "imgSrc" class = "w-full h-full" ref= "cropper" : src= "imgSrc" alt= "Source Image" @ready= "ready" @cropstart= "cropstart" @cropmove= "cropmove" @cropend= "cropend" @crop= "crop" @zoom= "zoom" preview= ".preview" : autoCropArea= "autoCropArea" > < / vue- cropper> < / div> < div class = "w-420px" > < div class = "font-bold color-#666 ml-20px mb-10px" > 预览< / div> < div v- show= "!imgSrc"  class = "preview_empty ml-20px" > < / div> < div v- show= "imgSrc"  class = "preview ml-20px" > < / div> < ! --  < div> 裁剪图片< / div> < div class = "cropped-image" > < el- image class = "h-180px"  v- if = "cropImg"  : src= "cropImg"  alt= "Cropped Image"  / > < div v- else  class = "crop-placeholder"  / > < / div>  -- > < div class = "actions mt-10px ml-10px" > < el- button class = "mb-10px ml-10px"  type= "primary"  @click= "zoom(0.2)"  size= "small" > 放大< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "zoom(-0.2)"  size= "small" > 缩小< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "move(-10, 0)"  size= "small" > 左移< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "move(10, 0)"  size= "small" > 右移< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "move(0, -10)"  size= "small" > 上移< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "move(0, 10)"  size= "small" > 下移< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "rotate(90)"  size= "small" > 旋转90 °< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "rotate(-90)"  size= "small" > 旋转- 90 °< / el- button> < ! --  < el- button class = "mb-10px"  type= "primary"  @click= "flipX"  size= "small" > 水平翻转< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "flipY"  size= "small" > 垂直翻转< / el- button>  -- > < ! --  < el- button class = "mb-10px"  type= "success"  @click= "cropImage"  size= "small" > 搜索< / el- button>  -- > < el- button class = "mb-10px"  type= "primary"  @click= "reset"  size= "small"  plain> 重置< / el- button> < el- buttonv- if = "!isHideFileChooser" class = "mb-10px" type= "success" @click= "showFileChooser" size= "small" plain> 更换图片< / el- button> < ! --  < el- button class = "mb-10px"  type= "primary"  @click= "getCropBoxData"  size= "small" > 获取裁剪框数据< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "setCropBoxData"  size= "small" > 设置裁剪框数据< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "getData"  size= "small" > 获取裁剪数据< / el- button> < el- button class = "mb-10px"  type= "primary"  @click= "setData"  size= "small" > 设置裁剪数据< / el- button>  -- > < / div> < / div> < / div> < span slot= "footer"  class = "dialog-footer" > < el- button size= "small"  @click= "dialogVisible = false" > 取 消< / el- button> < el- button size= "small"  type= "primary"  @click= "cropImage" > 搜索< / el- button> < / span> < / el- dialog> 
< / template> < script> 
import  VueCropper from  'vue-cropperjs' 
import  'cropperjs/dist/cropper.css' export  default  { name :  'Cropper' , components :  {  VueCropper } , props :  { title :  { type :  String, default :  '图片框选' } , imgUrl :  { type :  String, default :  '' } , autoCropArea :  { type :  Number, default :  0.6 } , isHideFileChooser :  { type :  Boolean, default :  true } } , data ( )  { return  { imgSrc :  '' , dialogVisible :  false , cropImg :  '' } } , watch :  { imgUrl ( val )  { if  ( val)  { this . imgSrc =  valconsole. log ( '🚀 ~ imgUrl ~ this.imgSrc:' ,  this . imgSrc) } } } , methods :  { open ( )  { if  ( ! this . imgUrl)  { this . imgSrc =  '' } this . dialogVisible =  true } , handleClose ( )  { this . $emit ( 'close' ) } , ready ( )  { } , cropImage ( )  { this . cropImg =  this . $refs. cropper. getCroppedCanvas ( ) . toDataURL ( ) const  base64Data =  this . cropImg. split ( ',' ) [ 1 ] this . $emit ( 'searchImg' ,  base64Data) this . dialogVisible =  false } , cropstart ( )  { } , cropmove ( )  { } , cropend ( )  { } , crop ( data )  { } , flipX ( )  { const  dom =  this . $refs. flipXlet  scale =  dom. getAttribute ( 'data-scale' ) scale =  scale ?  - scale :  - 1 this . $refs. cropper. scaleX ( scale) dom. setAttribute ( 'data-scale' ,  scale) } , flipY ( )  { const  dom =  this . $refs. flipYlet  scale =  dom. getAttribute ( 'data-scale' ) scale =  scale ?  - scale :  - 1 this . $refs. cropper. scaleY ( scale) dom. setAttribute ( 'data-scale' ,  scale) } , getCropBoxData ( )  { this . data =  JSON . stringify ( this . $refs. cropper. getCropBoxData ( ) ,  null ,  4 ) } , getData ( )  { this . data =  JSON . stringify ( this . $refs. cropper. getData ( ) ,  null ,  4 ) console. log ( '🚀 ~ getData ~ this.data:' ,  this . data) } , move ( offsetX,  offsetY )  { this . $refs. cropper. move ( offsetX,  offsetY) } , reset ( )  { this . $refs. cropper. reset ( ) } , rotate ( deg )  { this . $refs. cropper. rotate ( deg) } , setCropBoxData ( )  { if  ( ! this . data)  return this . $refs. cropper. setCropBoxData ( JSON . parse ( this . data) ) } , setData ( )  { if  ( ! this . data)  return this . $refs. cropper. setData ( JSON . parse ( this . data) ) } , setImage ( e )  { const  file =  e. target. files[ 0 ] if  ( file. type. indexOf ( 'image/' )  ===  - 1 )  { alert ( 'Please select an image file' ) return } if  ( typeof  FileReader ===  'function' )  { const  reader =  new  FileReader ( ) reader. onload  =  ( event )  =>  { this . imgSrc =  event. target. resultthis . $refs. cropper. replace ( event. target. result) } reader. readAsDataURL ( file) }  else  { alert ( 'Sorry, FileReader API not supported' ) } } , showFileChooser ( )  { this . $refs. input. click ( ) } , zoom ( percent )  { this . $refs. cropper. relativeZoom ( percent) } } , mounted ( )  { this . imgSrc =  this . imgUrl} 
} 
< / script> < style lang= "scss"  scoped> 
input[ type= 'file' ]  { display :  none; 
} . preview- area { width :  100 % ; 
} . preview- area p { font- size:  1 . 25rem; margin :  0 ; margin- bottom:  1rem; 
} . preview- area p: last- of - type { margin- top:  1rem; 
} . preview { width :  270px; height :  calc ( 270px *  ( 9  /  16 ) ) ; overflow :  hidden; background- color:  #f5f5f5; 
} . preview_empty { width :  270px; height :  calc ( 270px *  ( 9  /  16 ) ) ; overflow :  hidden; background- color:  #f5f5f5; 
} 
. crop- placeholder { width :  100 % ; height :  200px; background :  #ccc; 
} . cropped- image img { max- width:  100 % ; 
} 
< / style>