欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue實(shí)現(xiàn)圖片裁剪后上傳

 更新時(shí)間:2020年12月16日 09:20:01   作者:halo1416  
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)圖片裁剪后上傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了vue實(shí)現(xiàn)圖片裁剪后上傳的具體代碼,供大家參考,具體內(nèi)容如下

一、背景

目前負(fù)責(zé)的系統(tǒng)(商城后臺(tái)管理系統(tǒng))里面有這么一個(gè)需求,為了配合前臺(tái)的展示,上傳的商品圖片比較必須是1:1的正方形。(其它地方有時(shí)會(huì)有5:4或者16:9的需求,但較少)。所以需要對(duì)上傳的圖片先進(jìn)行裁剪,并且按要求只能裁剪為1:1,然后在進(jìn)行上傳。

當(dāng)然,為了兼容系統(tǒng)其它地方有5:4或者16:9的圖片比例需求,需要給出一個(gè)參數(shù),可以隨時(shí)控制圖片裁剪的比例。

二、使用什么插件實(shí)現(xiàn)

使用 vue-cropper 顯示,該插件是基于 cropper 的二次封裝,簡(jiǎn)單小巧,更合適vue項(xiàng)目。注意:功能沒有 cropper 強(qiáng)大。

三、使用 cropper

3.1 封裝一下cropper, 配置自己想要的參數(shù)

<template>
 <div class="Cropper">
 <el-dialog
  :visible.sync="dialogVisible"
  width="740px"
  title="圖片裁剪"
  :before-close="handleClose"
  :close-on-click-modal="false">
  <div
  class="cropper-container">
  <div class="cropper-el">
   <vue-cropper
   ref="cropper"
   :img="cropperImg"
   :output-size="option.size"
   :output-type="option.outputType"
   :info="true"
   :can-move="option.canMove"
   :can-move-box="option.canMoveBox"
   :fixed-box="option.fixedBox"
   :auto-crop="option.autoCrop"
   :auto-crop-width="option.autoCropWidth"
   :auto-crop-height="option.autoCropHeight"
   :center-box="option.centerBox"
   :high="option.high"
   :info-true="option.infoTrue"
   @realTime="realTime"
   :enlarge="option.enlarge"
   :fixed="option.fixed"
   :fixed-number="option.fixedNumber"
   :limitMinSize="option.limitMinSize"
   />
  </div>
  <!-- 預(yù)覽 ==>> 我不需要預(yù)覽 -->
  <!-- <div class="prive-el">
   <strong>預(yù)覽:</strong>
   <div class="prive-style" :style="{'width': '200px', 'height': '200px', 'overflow': 'hidden', 'margin': '10px 25px', 'display':'flex', 'align-items' : 'center'}">
   <div class="prive-style" :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden', 'margin': '10px 25px', 'display':'flex', 'align-items' : 'center'}">
   <div class="preview" :style="previews.div">
    <img :src="previews.url" :style="previews.img">
   </div>
   </div>
   <el-button @click="uploadBth">重新上傳</el-button>
  </div> -->
  </div>
  <span
  slot="footer"
  class="dialog-footer">
  <el-button @click="uploadBth">重新上傳</el-button>
  <el-button
   @click="handleClose">取 消</el-button>
  <el-button
   type="primary"
   @click="saveImg">確 定</el-button>
  </span>
 </el-dialog>
 </div>
</template>
 
<script>
import { VueCropper } from 'vue-cropper';
export default {
 name: 'Cropper',
 components: {
 VueCropper
 },
 props: {
 dialogVisible: {
  type: Boolean,
  default: false
 },
 imgType: {
  type: String,
  default: 'blob'
 },
 cropperImg: {
  type: String,
  default: ''
 },
 zoomScale: {  // 裁剪比例,默認(rèn)1:1
  type: Array,
  default: [1, 1]
 }
 },
 data () {
 return {
  previews: {},
  option: {
  img: '', // 裁剪圖片的地址
  size: 1, // 裁剪生成圖片的質(zhì)量
  outputType: 'png', // 裁剪生成圖片的格式 默認(rèn)jpg
  canMove: false, // 上傳圖片是否可以移動(dòng)
  fixedBox: false, // 固定截圖框大小 不允許改變
  canMoveBox: true, // 截圖框能否拖動(dòng)
  autoCrop: true, // 是否默認(rèn)生成截圖框
  // 只有自動(dòng)截圖開啟 寬度高度才生效
  autoCropWidth: 500, // 默認(rèn)生成截圖框?qū)挾?
  autoCropHeight: 500, // 默認(rèn)生成截圖框高度
  centerBox: true, // 截圖框是否被限制在圖片里面
  high: false, // 是否按照設(shè)備的dpr 輸出等比例圖片
  enlarge: 1, // 圖片根據(jù)截圖框輸出比例倍數(shù)
  mode: 'contain', // 圖片默認(rèn)渲染方式
  maxImgSize: 2000, // 限制圖片最大寬度和高度
  // limitMinSize: [500,500], // 更新裁剪框最小屬性
  limitMinSize: 500, // 更新裁剪框最小屬性
  infoTrue: true, // true 為展示真實(shí)輸出圖片寬高 false 展示看到的截圖框?qū)捀?
  fixed: true, // 是否開啟截圖框?qū)捀吖潭ū壤?(默認(rèn):true)
  // fixedNumber: [1, 1] // 截圖框的寬高比例 ==>> 這個(gè)參數(shù)目前沒有作用(作者解釋的)
  fixedNumber: this.zoomScale // 截圖框的寬高比例
  },
 };
 },
 methods: {
 // 裁剪時(shí)觸發(fā)的方法,用于實(shí)時(shí)預(yù)覽
 realTime (data) {
  this.previews = data;
 },
 // 重新上傳
 uploadBth () {
  this.$emit('update-cropper');
 },
 // 取消關(guān)閉彈框
 handleClose () {
  this.$emit('colse-dialog', false);
 },
 // 獲取裁剪之后的圖片,默認(rèn)blob,也可以獲取base64的圖片
 saveImg () {
  if (this.imgType === 'blob') {
  this.$refs.cropper.getCropBlob(data => {
   this.$emit('upload-img', data);
  });
  } else {
  this.$refs.cropper.getCropData(data => {
   this.uploadFile = data;
   this.$emit('upload-img', data);
  });
  }
 }
 }
};
</script>
 
<style lang="scss" scoped>
.Cropper {
 .cropper-el {
 height: 700px;
 width: 700px;
 flex-shrink: 0;
 }
 .cropper-container {
 display: flex;
 justify-content: space-between;
 .prive-el {
  flex: 1;
  align-self: center;
  text-align: center;
  .prive-style {
  margin: 0 auto;
  flex: 1;
  -webkit-flex: 1;
  display: flex;
  display: -webkit-flex;
  justify-content: center;
  -webkit-justify-content: center;
  overflow: hidden;
  background: #ededed;
  margin-left: 40px;
  }
  .preview {
  overflow: hidden;
  }
  .el-button {
  margin-top: 20px;
  }
 }
 }
}
</style>
<style lang="scss">
.cropper-box-canvas img{
 width: 100% !important;
 height: 100% !important;
}
</style>

3.2 將 el-upload 和 cropper 組合,封裝,其他地方可以直接調(diào)用

<template>
 <div>
 <!-- 注意:必須關(guān)閉自動(dòng)上傳屬性 auto-upload -->
 <el-upload
  :http-request="Upload"
  :multiple="true"
  list-type="picture-card"
  :file-list="productImageList"
  :on-remove="removeImage"
  :limit="12"
  :before-upload="beforeAvatarUpload"
  ref="fileUpload"
  :auto-upload="false"
  :on-change="selectChange"
  action=""
  class="cropper-upload-box"
 >
  <i slot="default" class="el-icon-plus"></i>
 </el-upload>
 
 <cropper
  v-if="showCropper"
  :dialog-visible="showCropper"
  :cropper-img="cropperImg"
  :zoomScale="zoomScale"
  @update-cropper="updateCropper"
  @colse-dialog="closeDialog"
  @upload-img="uploadImg"
 />
 </div>
</template>
 
<script>
import Cropper from "@/components/cropper";
import { client, randomWord } from '@/utils/alioss'
export default {
 name: "CropperUpload",
 data() {
 return {
  productImageList: [],
 
  showCropper: false, // 是否顯示裁剪框
  cropperImg: "" // 需要裁剪的圖片
 };
 },
 props: {
 defaultImgList: {  // 默認(rèn)顯示的圖片列表
  type: Array,
  default: () => []
 },
 zoomScale: {   // 裁剪比例,默認(rèn)1:1
  type: Array,
  default: [1, 1]
 }
 },
 components: {
 Cropper
 },
 watch: {
 defaultImgList: {
  handler: function(newVal, oldVal){
  this.productImageList = newVal // 賦值
  },
  deep: true
 }
 },
 methods: {
 beforeAvatarUpload(file) {
  const isLt2M = file.size / 1024 / 1024 < 2;  // 原圖片
  // const isLt2M = this.uploadFile.size / 1024 / 1024 < 1;  //裁剪后的圖片(會(huì)比原圖片大很多,應(yīng)該是轉(zhuǎn)成Blob的原因?qū)е拢?
  if (!isLt2M) {
  this.$message.error("上傳圖片大小不能超過 2MB!");
  this.noCanUpload = true  // 如果這里被攔截,將自動(dòng)刪除不能上傳的圖片
  return false
  }
  // return isLt2M
 },
 removeImage(file, fileList) {
  const index = this.productImageList.findIndex(item => {
  return item.uid == file.uid;
  });
  if (index > -1) {
  this.productImageList.splice(index, 1);
  }
  this.$emit('getUploadImg', this.productImageList) // 把最新上傳的圖片列表返回
 },
 Upload(file) {
  var fileName = `img/${randomWord(
  true,
  20
  )}${+new Date()}${file.file.name.substr(file.file.name.indexOf("."))}`;
  // client().put(fileName, file.file).then(result => {
  client()
  .put(fileName, this.uploadFile)
  .then(result => {
   // 上傳裁剪后的圖片
   console.log(result);
   this.productImageList.push({
   url: result.url,
   uid: file.file.uid,
   saveUrl: "/" + result.name
   });
   this.showCropper = false;
   this.$emit('getUploadImg', this.productImageList) // 把最新上傳的圖片列表返回
  })
  .catch(err => {
   this.showCropper = false;
   console.log(err);
  });
 },
 
 // 更新圖片
 updateCropper() {
  if(!this.noCanUpload){
  let fileList = this.$refs.fileUpload.uploadFiles  // 獲取文件列表
  let index02 = fileList.findIndex(item => {  // 把取消裁剪的圖片刪除
   return item.uid == this.currentFile.uid;
  });
  fileList.splice(index02, 1)
  }
 
  let index = this.$refs.fileUpload.$children.length - 1;
  this.$refs.fileUpload.$children[index].$el.click();
 },
 // 關(guān)閉窗口
 closeDialog() {
  this.showCropper = false;
  
  if(!this.noCanUpload){
  let fileList = this.$refs.fileUpload.uploadFiles  // 獲取文件列表
  let index = fileList.findIndex(item => {  // 把取消裁剪的圖片刪除
   return item.uid == this.currentFile.uid;
  });
  fileList.splice(index, 1)
  }
 },
 // 上傳圖片
 uploadImg(file) {
  this.uploadFile = file;
  // this.$refs.fileUpload.submit();
 
  // 判斷裁剪后圖片的寬高
  let img = new Image()
  img.src = window.URL.createObjectURL(file);  // Blob轉(zhuǎn)成url 才能給img顯示
  img.onload = () => {
  let minProp = Math.min(img.width, img.height) //裁剪后的圖片寬,高 ==> 取最小值
  if( minProp < 500){  // 如果最小值比設(shè)置的最小值(默認(rèn)為500)小
   this.$message.error(`請(qǐng)保證圖片短邊最小為500`);
   return false
  }
  this.$refs.fileUpload.submit();
  }
 },
 selectChange(file) {
  this.noCanUpload = false
  let files = file.raw;
  var reader = new FileReader();
  reader.onload = e => {
  let data;
  if (typeof e.target.result === "object") {
   // 把Array Buffer轉(zhuǎn)化為blob 如果是base64不需要
   data = window.URL.createObjectURL(new Blob([e.target.result]));
  } else {
   data = e.target.result;
  }
  this.cropperImg = data;
 
  // 圖片圖片尺寸,如果是正方形,則直接上傳;否則調(diào)用裁剪
  let img = new Image()
  img.src = this.cropperImg;
  img.onload = () => {
   if(img.width == img.height){ // 本來就是正方形 => 直接上傳
   this.uploadFile = files;
   this.$refs.fileUpload.submit(); // 調(diào)用上傳方法
   }else{
   this.showCropper = true;  // 不是正方形的圖片才開啟裁剪
   this.currentFile = file  // 保存當(dāng)前操作裁剪的圖片
   }
  }
  };
  // 轉(zhuǎn)化為base64
  // reader.readAsDataURL(file)
  // 轉(zhuǎn)化為blob
  reader.readAsArrayBuffer(files);
  
  // this.showCropper = true;  // 默認(rèn)開啟裁剪
 }
 }
};
</script>
 
<style lang="scss">
.cropper-upload-box{
 display: flex;
 .el-upload{
 width: 148px;
 height: 148px;
 }
}
</style>

3.3 其他頁面中調(diào)用裁剪組件

<!-- 
 zoomScale:定義的裁剪比例;
 defaultImgList: 默認(rèn)顯示的圖片列表
 @getUploadImg:這個(gè)事件將得到更新后(上傳、刪除)的圖片列表,在頁面中重新賦值給默認(rèn)的列表變量后就可以做頁面中的邏輯處理了
 -->
<cropper-upload :zoomScale='[1,1]' :defaultImgList="productImageList" @getUploadImg="getUploadImg"></cropper-upload>

自此,圖片裁剪功能實(shí)現(xiàn)?。。?/p>

3.4 看一下頁面中的效果

​​​​​​​以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 如何處理elementUI中表格多選框禁用的問題

    如何處理elementUI中表格多選框禁用的問題

    這篇文章主要介紹了如何處理elementUI中表格多選框禁用的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue+element-ui+sortable.js實(shí)現(xiàn)表格拖拽功能

    vue+element-ui+sortable.js實(shí)現(xiàn)表格拖拽功能

    這篇文章主要為大家詳細(xì)介紹了vue+element-ui+sortable.js實(shí)現(xiàn)表格拖拽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 深入淺析Vue中的 computed 和 watch

    深入淺析Vue中的 computed 和 watch

    computed 計(jì)算屬性是通過屬性計(jì)算得來的屬性,watch屬性變化,就會(huì)觸發(fā)監(jiān)聽的函數(shù)。下面通過本文給大家介紹Vue中的 computed 和 watch,感興趣的朋友一起看看吧
    2018-06-06
  • vue路由懶加載的實(shí)現(xiàn)方法

    vue路由懶加載的實(shí)現(xiàn)方法

    本篇文章主要介紹了vue路由懶加載的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03
  • vue中響應(yīng)式布局如何將字體大小改成自適應(yīng)

    vue中響應(yīng)式布局如何將字體大小改成自適應(yīng)

    這篇文章主要介紹了vue中響應(yīng)式布局如何將字體大小改成自適應(yīng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue對(duì)storejs獲取的數(shù)據(jù)進(jìn)行處理時(shí)遇到的幾種問題小結(jié)

    vue對(duì)storejs獲取的數(shù)據(jù)進(jìn)行處理時(shí)遇到的幾種問題小結(jié)

    這篇文章主要介紹了vue對(duì)storejs獲取的數(shù)據(jù)進(jìn)行處理時(shí)遇到的幾種問題小結(jié),需要的朋友可以參考下
    2018-03-03
  • Vue3 異步組件 suspense使用詳解

    Vue3 異步組件 suspense使用詳解

    vue在解析我們的組件時(shí), 是通過打包成一個(gè) js 文件,當(dāng)我們的一個(gè)組件 引入過多子組件是,頁面的首屏加載時(shí)間 由最后一個(gè)組件決定 優(yōu)化的一種方式就是采用異步組件,這篇文章主要介紹了Vue3 異步組件 suspense,需要的朋友可以參考下
    2022-12-12
  • Vue實(shí)現(xiàn)列表跑馬燈效果

    Vue實(shí)現(xiàn)列表跑馬燈效果

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)列表跑馬燈效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Vue3?TypeScript?實(shí)現(xiàn)useRequest詳情

    Vue3?TypeScript?實(shí)現(xiàn)useRequest詳情

    本文介紹了Vue3?TypeScript實(shí)現(xiàn)useRequest詳情,useRequest可能是目前社區(qū)中最強(qiáng)大,最接地氣的請(qǐng)求類?Hooks了??梢愿采w99%的網(wǎng)絡(luò)請(qǐng)求場(chǎng)景,無論是讀還是寫,無論是普通請(qǐng)求還是分頁請(qǐng)求,無論是緩存還是防抖節(jié)流,通通都能支持,關(guān)于其介紹需要的小伙伴可以參考一下
    2022-05-05
  • 如何在vuejs項(xiàng)目中使用md5加密密碼的實(shí)現(xiàn)

    如何在vuejs項(xiàng)目中使用md5加密密碼的實(shí)現(xiàn)

    本文主要介紹了如何在vuejs項(xiàng)目中使用md5加密密碼的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08

最新評(píng)論