在vue3中vue-cropper的初使用示例詳解
一、前言
在學(xué)習(xí) Vue-Cropper 之前 先了解一下 Cropper,兩者的關(guān)系與區(qū)別,避免在學(xué)習(xí)的時候踩坑和把它們搞混淆。
Cropper 是一個基于JavaScript 的圖像剪切庫,它可以在多種現(xiàn)代瀏覽器中運行工作。它提供了豐富的配置選項和事件,使得用戶可以輕松地圖像上傳、剪切、旋轉(zhuǎn)、縮放等功能。Cropper的設(shè)計目標(biāo)是提供簡單、靈活和強大的圖像處理功能。
Cropper 的主要特性:
1、支持多種圖片格式,如JPEG、PNG、GIF等。
2、提供多種剪切形狀。
3、支持圖片旋轉(zhuǎn)。
4、支持多種語言和主體。
5、提供豐富的API和事件,便于自定義和集成。
6、Cropper 不依賴與 Vue.js環(huán)境,可以在其它環(huán)境中使用。
Vue-Cropper 是一個基于 Vue.js 的圖像剪切組件,它是專門為 Vue.js應(yīng)用程序設(shè)計的。Vue-Cropper 封裝了 Cropper 庫的許多功能,使其更易于在 Vue.js 項目中集成和使用。
Vue-Cropper 的主要特性:
1、簡單易用:可以直接作為 vue 組件使用。
2、支持與 vue 的響應(yīng)式數(shù)據(jù)綁定。
3、支持多種圖像格式和剪切形狀。
4、支持圖像選裝、縮放和翻轉(zhuǎn)。
5、提供了一些 額外的功能,如圖片預(yù)覽、圖片上傳等。
6、只能在 vue.js 的環(huán)境中使用。
二、安裝與使用
1、安裝
# npm 安裝 npm install vue-cropper@next -d --save
# yarn 安裝 yarn add vue-cropper@next
2、引入
在組件中引入
import 'vue-cropper/dist/index.css'; import { VueCropper } from 'vue-cropper';
全局引入
在 main.js中
import VueCropper from 'vue-cropper'; import 'vue-cropper/dist/index.css' const app = createApp(App) app.use(VueCropper) app.mount('#app')
3、代碼使用
重要: 需要關(guān)掉本地的 mock 服務(wù), 不然圖片轉(zhuǎn)化會報錯。
重要: 需要使用外層容器包裹并設(shè)置寬高。
<div style="width: 300px; height: 300px;"> <vueCropper ref="cropper" :img="option.img" :outputSize="option.size" :outputType="option.outputType" > </vueCropper> </div>
三、文檔
1、props 屬性
名稱 | 功能 | 默認(rèn)值 | 可選值 |
---|---|---|---|
img | 裁剪圖片的地址 | 空 | url 地址 , base64 , blob |
outputSize | 裁剪生成圖片的質(zhì)量 | 1 | 0.1 ~ 1 |
outputType | 裁剪生成圖片的格式 | jpg (jpg 需要傳入jpeg) | jpeg , png , webp |
info | 裁剪框的大小信息 | true | true , false |
canScale | 圖片是否允許滾輪縮放 | true | true , false |
autoCrop | 是否默認(rèn)生成截圖框 | false | true , false |
autoCropWidth | 默認(rèn)生成截圖框?qū)挾?/td> | 容器的 80% | 0 ~ max |
autoCropHeight | 默認(rèn)生成截圖框高度 | 容器的 80% | 0 ~ max |
fixed | 是否開啟截圖框?qū)捀吖潭ū壤?/td> | false | true , false |
fixedNumber | 截圖框的寬高比例, 開啟fixed 生效 | [1, 1] | [ 寬度 , 高度 ] |
full | 是否輸出原圖比例的截圖 | false | true , false |
fixedBox | 固定截圖框大小 | 不允許改變 | false |
canMove | 上傳圖片是否可以移動 | true | true , false |
canMoveBox | 截圖框能否拖動 | true | true , false |
original | 上傳圖片按照原始比例渲染 | false | true , false |
centerBox | 截圖框是否被限制在圖片里面 | false | true , false |
high | 是否按照設(shè)備的dpr 輸出等比例圖片 | true | true , false |
infoTrue | true 為展示真實輸出圖片寬高 false 展示看到的截圖框?qū)捀?/td> | false | true , false |
maxImgSize | 限制圖片最大寬度和高度 | 2000 | 0 ~ max |
enlarge | 圖片根據(jù)截圖框輸出比例倍數(shù) | 1 | 0 ~ max(建議不要太大不然會卡死的呢) |
mode | 圖片默認(rèn)渲染方式 | contain | contain , cover , 100px , 100% auto |
limitMinSize | 裁剪框限制最小區(qū)域 | 10 | Number, Array, String |
fillColor | 導(dǎo)出時背景顏色填充 | 空 | #ffffff , white |
2、回調(diào)函數(shù)
@realTime
實時預(yù)覽事件@imgMoving
圖片移動回調(diào)函數(shù)@cropMoving
截圖框移動回調(diào)函數(shù)@imgLoad
圖片加載的回調(diào), 返回結(jié)果success
,error
// 實時預(yù)覽事件 const realTime = (data) => { previews.value = data; };
3、內(nèi)置方法和屬性
在vue2中通過 this.$refs.cropper
調(diào)用,這里的this 表示當(dāng)前實例,在vue3中,等同于下面的 proxy,或者cropper。
import { getCurrentInstance } from "vue"; const { proxy } = getCurrentInstance();
// cropper 是使用 ref 綁定到 vueCropper組將上的 const cropper = ref(null);
即在 vue3中,可以使用 proxy.$refs.cropper 或 cropper.value.調(diào)用。
屬性
屬性 | 說明 |
---|---|
this .$refs.cropper.cropW / cropper.value.cropW | 截圖框?qū)挾?/td> |
this .$refs.cropper.cropH / cropper.value.cropH | 截圖框高度 |
方法
方法 | 說明 |
---|---|
this.$refs.cropper.startCrop() | 開始截圖 |
this.$refs.cropper.stopCrop() | 停止截圖 |
this.$refs.cropper.clearCrop() | 清除截圖 |
this.$refs.cropper.changeScale() | 修改圖片大小 正數(shù)為變大 負(fù)數(shù)變小 |
this.$refs.cropper.getImgAxis() | 獲取圖片基于容器的坐標(biāo)點 |
his.$refs.cropper.getCropAxis() | 獲取截圖框基于容器的坐標(biāo)點 |
this.$refs.cropper.goAutoCrop | 自動生成截圖框函數(shù) |
this.$refs.cropper.rotateRight() | 向右邊旋轉(zhuǎn)90度 |
this.$refs.cropper.rotateLeft() | 向左邊旋轉(zhuǎn)90度 |
獲取截圖數(shù)據(jù)
重點:在 vue-cropper中沒有g(shù)etCroppedCanvas(),沒有任何帶 canvas的函數(shù)方法,getCroppedCanvas()函數(shù) cropper 中的。
// 獲取 base64 cropper.value.getCropData((data) => { console.log(data); });
// 獲取 blob cropper.value.getCropBlob(((data ) => { console.log(data); });
四、用例
1、效果
樣式
截切后的base64數(shù)據(jù)轉(zhuǎn)圖片
2、代碼
<!-- 圖片裁剪組件 圖片剪切使用 vue-cropper 工具剪切圖片,讀取圖片后將圖片轉(zhuǎn)換成Base64格式,使用 getCropData函數(shù)獲取剪切后的Base64格式的圖片數(shù)據(jù), getCropData函數(shù)是一個異步函數(shù),不能在 data回調(diào)中直接使用 emit鉤子,需要定義Promise,并在getCropData的回調(diào)函數(shù)中調(diào)用resolve來解析Promise, 然后等待getCropData執(zhí)行完成,才會繼續(xù)往下執(zhí)行,再通過 emit鉤子將剪切后的圖片數(shù)據(jù)傳遞到父組件。父組件再將Base64格式圖片轉(zhuǎn)換成file格式, 上傳到服務(wù)器。 --> <template> <div class="custom-dialog" :model-value="dialogVisibleCorpper" @opened="openDialog" :before-close="beforeClose"> <div class="dialog"> <div class="container"> <div class="cropper-container"> <div class="cropper-box"> <div class="cropper-content" ref="cropperBox"> <vue-cropper id="imag" ref="cropper" :img="options.img" :outputType="options.outputType" :autoCropHeight="options.autoCropHeight" :autoCropWidth="options.autoCropWidth" :autoCrop="options.autoCrop" :aspectRation="options.aspectRation" :infoTrue="options.infoTrue" :viewMode="options.viewMode" :dragMode="options.dragMode" :guides="options.guides" :initialAspectRatio="options.initialAspectRatio" :background="options.background" :cropBoxMovable="options.cropBoxMovable" :cropBoxResizable="options.cropBoxResizable" :fixedBox="options.fixedBox" :centerBox="options.centerBox" :original="options.original" :canMoveBox="options.canMoveBox" :fixedNumber="options.fixedNumber" :mode="options.mode" :enlarge="options.enlarge" :fixed="options.fixed" :info="options.info" :fillColor="options.fillColor" @realTime="realTime" v-if="showCropper" /> </div> </div> </div> <div class="btn-container"> <div class="item-btn"> <el-upload action="#" :http-request="() => { }" :before-upload="beforeUpload" :show-file-list="false" style="display: none;"> <el-button></el-button> </el-upload> <div class="closeDialog" @click.stop="beforeClose">取消</div> </div> <div class="item-btn"> <el-icon class="btn" @click.stop="changeScale(1)"> <Plus /> </el-icon> </div> <div class="item-btn"> <el-icon class="btn" @click.stop="changeScale(-1)"> <Minus /> </el-icon> </div> <div class="item-btn"> <el-icon class="btn" @click.stop="rotateLeft()"> <RefreshLeft /> </el-icon> </div> <div class="item-btn"> <el-button type="primary" @click.stop="determine">確 定</el-button> </div> </div> </div> </div> </div> </template> <script setup> import { getCurrentInstance, ref, reactive, onMounted } from "vue"; import 'vue-cropper/dist/index.css'; import { VueCropper } from 'vue-cropper'; const { proxy } = getCurrentInstance(); const props = defineProps({ dialogVisibleCorpper: { type: Boolean, default: false, }, }); // 使用 defineEmits 來聲明組件可以拋出的事件 const emit = defineEmits(["update:dialogVisibleCorpper", "getImagValue"]); const cropper = ref(null); const cropperBox = ref(null); const showCropper = ref(true); const options = reactive({ img: null, // 裁剪圖片的地址 autoCropWidth: 300, // 默認(rèn)生成截圖框?qū)挾?默認(rèn)容器的 80% autoCropHeight: 300, // 默認(rèn)生成截圖框高度 默認(rèn)容器的 80% viewMode: 1, // 0-3,控制裁剪框的顯示模式 dragMode: "none", // 圖片拖動模式 guides: false, // 是否顯示裁剪框內(nèi)的虛線 background: false, // 是否顯示容器的網(wǎng)格背景 initialAspectRatio: 1, // 裁剪框的寬高比(可選) aspectRation: 1, // 裁剪框的寬高比(可選) cropBoxMovable: false, // 截圖框是否可拖動 cropBoxResizable: false, // 截圖框是否可調(diào)整大小 outputType: "png", // 裁剪生成圖片的格式 jpeg, png, webp autoCrop: true, // 是否默認(rèn)生成截圖框 fixedBox: true, // 固定截圖框大小 true:表示不能改變大小 false:表示可以改變大小 canMoveBox: false, // 截圖框不能拖動 true:表示可以拖動 false:表示不能拖動 aspectRation: 1, // 裁剪框的寬高比(可選) fixedNumber: [1, 1], // 截圖框的寬高比例 enlarge: 1, // 圖片根據(jù)截圖框輸出比例倍數(shù) fixed: true, // 是否開啟截圖框?qū)捀吖潭ū壤? centerBox: true, // 截圖框是否限制在圖片里(只有在自動生成截圖框時才能生效) info: false, // 剪切框的大小信息 original: false, // 上傳圖片按照原始比例渲染 infoTrue: true, // mode: "cover auto", // 圖片默認(rèn)渲染方式 fillColor: "#fff", // 裁剪框的背景色 }); const previews = ref(null); // 打開裁剪彈窗 const openDialog = () => { showCropper.value = true; }; // 修改圖片大小 正數(shù)為變大 負(fù)數(shù)變小 const changeScale = (num) => { num = num || 1; proxy.$refs.cropper.changeScale(num); }; // 向左邊旋轉(zhuǎn)90度 const rotateLeft = () => { proxy.$refs.cropper.rotateLeft(); }; // 選擇圖片 const beforeUpload = (rawFile) => { if (rawFile.type.indexOf("image/") == -1) { ElMessage.error("請上傳圖片文件!"); return false; } if (rawFile.size / 1024 / 1024 > 5) { ElMessage.error("文件大小不能超過5MB!"); return false; } const reader = new FileReader(); reader.readAsDataURL(rawFile); reader.onload = () => { // 圖片在這里 options.img = reader.result; }; }; // 實時預(yù)覽事件 const realTime = (data) => { previews.value = data; }; // 關(guān)閉彈窗 const beforeClose = () => { options.img = null; previews.value = ""; // 使用 emit 來更新父組件的 dialogVisibleCorpper 值 emit("update:dialogVisibleCorpper", false); }; // 提交圖片 const determine = async () => { try { // getCropData是異步函數(shù),需要定義Promise,并在getCropData的回調(diào)函數(shù)中調(diào)用resolve來解析Promise, // 然后等待getCropData執(zhí)行完成,才會繼續(xù)往下執(zhí)行 const imgBase64 = await new Promise((resolve) => { cropper.value.getCropData((data) => { resolve(data); }); }); emit("getImagValue", imgBase64); } catch (err) { ElMessage({ message: 'err', type: 'error', plain: true, }); } beforeClose(); }; onMounted(() => { // 在進入頁面時,自動觸發(fā)點 el-upload 的擊事件 const btn = document.querySelector(".el-button"); if (btn) { btn.click(); } }); </script> <style scoped> .custom-dialog { width: 100%; height: 100vh; background-color: rgb(35, 35, 35); } .dialog { width: 80%; /* width: 100%; */ height: 100vh; margin: 0 auto; padding: 0; } .container { width: 100%; height: 100vh; margin: 0; padding: 0; } .cropper-container { width: 100%; height: 100%; margin: 0; padding: 0; } .btn-container { margin: 0 auto; height: 40px; margin: 0; padding: 0; display: flex; justify-content: space-between; align-items: center; position: absolute; bottom: 20px; left: 30px; right: 30px; z-index: 1000; } .cropper-box { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } .cropper-content { /* width: 100%; Aspect-ratio: 1/1; */ width: 100%; height: 100%; margin: 0 auto; /* overflow: hidden; */ } .closeDialog { color: white; } .btn { height: 40px; width: 40px; line-height: 40px; font-size: 20px; font-weight: 700; color: rgb(77, 77, 77); } </style>
參考文檔:Vue-Cropper 文檔
到此這篇關(guān)于在vue3中vue-cropper的初使用的文章就介紹到這了,更多相關(guān)vue3 vue-cropper使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
axios請求頭設(shè)置常見Content-Type和對應(yīng)參數(shù)的處理方式
這篇文章主要介紹了axios請求頭設(shè)置常見Content-Type和對應(yīng)參數(shù)的處理方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03vscode中開發(fā)運行uniapp項目詳細(xì)步驟
VSCode作為一個非常強大的代碼編輯器,可以集成眾多的插件和工具來優(yōu)化開發(fā)效率,這篇文章主要給大家介紹了關(guān)于vscode中開發(fā)運行uniapp項目的詳細(xì)步驟,需要的朋友可以參考下2023-07-07當(dāng)vue路由變化時,改變導(dǎo)航欄的樣式方法
今天小編就為大家分享一篇當(dāng)vue路由變化時,改變導(dǎo)航欄的樣式方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08vue通過v-html指令渲染的富文本無法修改樣式的解決方案
這篇文章主要介紹了vue通過v-html指令渲染的富文本無法修改樣式的解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05vue-extend和vue-component注冊一個全局組件方式
這篇文章主要介紹了vue-extend和vue-component注冊一個全局組件方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11Vue如何實現(xiàn)文件預(yù)覽和下載功能的前端上傳組件
在Vue.js項目中,使用ElementUI的el-upload組件可以輕松實現(xiàn)文件上傳功能,通過配置組件參數(shù)和實現(xiàn)相應(yīng)的方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09vue.js過濾器+ajax實現(xiàn)事件監(jiān)聽及后臺php數(shù)據(jù)交互實例
這篇文章主要介紹了vue.js過濾器+ajax實現(xiàn)事件監(jiān)聽及后臺php數(shù)據(jù)交互,結(jié)合實例形式分析了vue.js前臺過濾器與ajax后臺數(shù)據(jù)交互相關(guān)操作技巧,需要的朋友可以參考下2018-05-05