在vue3中vue-cropper的初使用示例詳解
一、前言
在學(xué)習(xí) Vue-Cropper 之前 先了解一下 Cropper,兩者的關(guān)系與區(qū)別,避免在學(xué)習(xí)的時(shí)候踩坑和把它們搞混淆。
Cropper 是一個(gè)基于JavaScript 的圖像剪切庫(kù),它可以在多種現(xiàn)代瀏覽器中運(yùn)行工作。它提供了豐富的配置選項(xiàng)和事件,使得用戶可以輕松地圖像上傳、剪切、旋轉(zhuǎn)、縮放等功能。Cropper的設(shè)計(jì)目標(biāo)是提供簡(jiǎn)單、靈活和強(qiáng)大的圖像處理功能。
Cropper 的主要特性:
1、支持多種圖片格式,如JPEG、PNG、GIF等。
2、提供多種剪切形狀。
3、支持圖片旋轉(zhuǎn)。
4、支持多種語(yǔ)言和主體。
5、提供豐富的API和事件,便于自定義和集成。
6、Cropper 不依賴與 Vue.js環(huán)境,可以在其它環(huán)境中使用。
Vue-Cropper 是一個(gè)基于 Vue.js 的圖像剪切組件,它是專門(mén)為 Vue.js應(yīng)用程序設(shè)計(jì)的。Vue-Cropper 封裝了 Cropper 庫(kù)的許多功能,使其更易于在 Vue.js 項(xiàng)目中集成和使用。
Vue-Cropper 的主要特性:
1、簡(jiǎn)單易用:可以直接作為 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)化會(huì)報(bào)錯(cuò)。
重要: 需要使用外層容器包裹并設(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 | 是否開(kāi)啟截圖框?qū)捀吖潭ū壤?/td> | false | true, false |
| fixedNumber | 截圖框的寬高比例, 開(kāi)啟fixed生效 | [1, 1] | [ 寬度 , 高度 ] |
| full | 是否輸出原圖比例的截圖 | false | true, false |
| fixedBox | 固定截圖框大小 | 不允許改變 | false |
| canMove | 上傳圖片是否可以移動(dòng) | true | true, false |
| canMoveBox | 截圖框能否拖動(dòng) | true | true, false |
| original | 上傳圖片按照原始比例渲染 | false | true, false |
| centerBox | 截圖框是否被限制在圖片里面 | false | true, false |
| high | 是否按照設(shè)備的dpr 輸出等比例圖片 | true | true, false |
| infoTrue | true 為展示真實(shí)輸出圖片寬高 false 展示看到的截圖框?qū)捀?/td> | false | true, false |
| maxImgSize | 限制圖片最大寬度和高度 | 2000 | 0 ~ max |
| enlarge | 圖片根據(jù)截圖框輸出比例倍數(shù) | 1 | 0 ~ max(建議不要太大不然會(huì)卡死的呢) |
| mode | 圖片默認(rèn)渲染方式 | contain | contain , cover, 100px, 100% auto |
| limitMinSize | 裁剪框限制最小區(qū)域 | 10 | Number, Array, String |
| fillColor | 導(dǎo)出時(shí)背景顏色填充 | 空 | #ffffff, white |
2、回調(diào)函數(shù)
@realTime實(shí)時(shí)預(yù)覽事件@imgMoving圖片移動(dòng)回調(diào)函數(shù)@cropMoving截圖框移動(dòng)回調(diào)函數(shù)@imgLoad圖片加載的回調(diào), 返回結(jié)果success,error
// 實(shí)時(shí)預(yù)覽事件
const realTime = (data) => {
previews.value = data;
};3、內(nèi)置方法和屬性
在vue2中通過(guò) this.$refs.cropper 調(diào)用,這里的this 表示當(dāng)前實(shí)例,在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)用。
屬性
| 屬性 | 說(shuō)明 |
|---|---|
this.$refs.cropper.cropW / cropper.value.cropW | 截圖框?qū)挾?/td> |
this.$refs.cropper.cropH / cropper.value.cropH | 截圖框高度 |
方法
| 方法 | 說(shuō)明 |
|---|---|
| this.$refs.cropper.startCrop() | 開(kāi)始截圖 |
| this.$refs.cropper.stopCrop() | 停止截圖 |
| this.$refs.cropper.clearCrop() | 清除截圖 |
| this.$refs.cropper.changeScale() | 修改圖片大小 正數(shù)為變大 負(fù)數(shù)變小 |
| this.$refs.cropper.getImgAxis() | 獲取圖片基于容器的坐標(biāo)點(diǎn) |
| his.$refs.cropper.getCropAxis() | 獲取截圖框基于容器的坐標(biāo)點(diǎn) |
| this.$refs.cropper.goAutoCrop | 自動(dòng)生成截圖框函數(shù) |
| this.$refs.cropper.rotateRight() | 向右邊旋轉(zhuǎn)90度 |
| this.$refs.cropper.rotateLeft() | 向左邊旋轉(zhuǎn)90度 |
獲取截圖數(shù)據(jù)
重點(diǎn):在 vue-cropper中沒(méi)有g(shù)etCroppedCanvas(),沒(méi)有任何帶 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ù)是一個(gè)異步函數(shù),不能在 data回調(diào)中直接使用 emit鉤子,需要定義Promise,并在getCropData的回調(diào)函數(shù)中調(diào)用resolve來(lái)解析Promise,
然后等待getCropData執(zhí)行完成,才會(huì)繼續(xù)往下執(zhí)行,再通過(guò) 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 來(lái)聲明組件可以拋出的事件
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", // 圖片拖動(dòng)模式
guides: false, // 是否顯示裁剪框內(nèi)的虛線
background: false, // 是否顯示容器的網(wǎng)格背景
initialAspectRatio: 1, // 裁剪框的寬高比(可選)
aspectRation: 1, // 裁剪框的寬高比(可選)
cropBoxMovable: false, // 截圖框是否可拖動(dòng)
cropBoxResizable: false, // 截圖框是否可調(diào)整大小
outputType: "png", // 裁剪生成圖片的格式 jpeg, png, webp
autoCrop: true, // 是否默認(rèn)生成截圖框
fixedBox: true, // 固定截圖框大小 true:表示不能改變大小 false:表示可以改變大小
canMoveBox: false, // 截圖框不能拖動(dòng) true:表示可以拖動(dòng) false:表示不能拖動(dòng)
aspectRation: 1, // 裁剪框的寬高比(可選)
fixedNumber: [1, 1], // 截圖框的寬高比例
enlarge: 1, // 圖片根據(jù)截圖框輸出比例倍數(shù)
fixed: true, // 是否開(kāi)啟截圖框?qū)捀吖潭ū壤?
centerBox: true, // 截圖框是否限制在圖片里(只有在自動(dòng)生成截圖框時(shí)才能生效)
info: false, // 剪切框的大小信息
original: false, // 上傳圖片按照原始比例渲染
infoTrue: true, //
mode: "cover auto", // 圖片默認(rèn)渲染方式
fillColor: "#fff", // 裁剪框的背景色
});
const previews = ref(null);
// 打開(kāi)裁剪彈窗
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("請(qǐng)上傳圖片文件!");
return false;
}
if (rawFile.size / 1024 / 1024 > 5) {
ElMessage.error("文件大小不能超過(guò)5MB!");
return false;
}
const reader = new FileReader();
reader.readAsDataURL(rawFile);
reader.onload = () => {
// 圖片在這里
options.img = reader.result;
};
};
// 實(shí)時(shí)預(yù)覽事件
const realTime = (data) => {
previews.value = data;
};
// 關(guān)閉彈窗
const beforeClose = () => {
options.img = null;
previews.value = "";
// 使用 emit 來(lái)更新父組件的 dialogVisibleCorpper 值
emit("update:dialogVisibleCorpper", false);
};
// 提交圖片
const determine = async () => {
try {
// getCropData是異步函數(shù),需要定義Promise,并在getCropData的回調(diào)函數(shù)中調(diào)用resolve來(lái)解析Promise,
// 然后等待getCropData執(zhí)行完成,才會(huì)繼續(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(() => {
// 在進(jìn)入頁(yè)面時(shí),自動(dòng)觸發(fā)點(diǎn) 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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
axios請(qǐng)求頭設(shè)置常見(jiàn)Content-Type和對(duì)應(yīng)參數(shù)的處理方式
這篇文章主要介紹了axios請(qǐng)求頭設(shè)置常見(jiàn)Content-Type和對(duì)應(yīng)參數(shù)的處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
vscode中開(kāi)發(fā)運(yùn)行uniapp項(xiàng)目詳細(xì)步驟
VSCode作為一個(gè)非常強(qiáng)大的代碼編輯器,可以集成眾多的插件和工具來(lái)優(yōu)化開(kāi)發(fā)效率,這篇文章主要給大家介紹了關(guān)于vscode中開(kāi)發(fā)運(yùn)行uniapp項(xiàng)目的詳細(xì)步驟,需要的朋友可以參考下2023-07-07
當(dāng)vue路由變化時(shí),改變導(dǎo)航欄的樣式方法
今天小編就為大家分享一篇當(dāng)vue路由變化時(shí),改變導(dǎo)航欄的樣式方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
vue通過(guò)v-html指令渲染的富文本無(wú)法修改樣式的解決方案
這篇文章主要介紹了vue通過(guò)v-html指令渲染的富文本無(wú)法修改樣式的解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
vue-extend和vue-component注冊(cè)一個(gè)全局組件方式
這篇文章主要介紹了vue-extend和vue-component注冊(cè)一個(gè)全局組件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
Vue如何實(shí)現(xiàn)文件預(yù)覽和下載功能的前端上傳組件
在Vue.js項(xiàng)目中,使用ElementUI的el-upload組件可以輕松實(shí)現(xiàn)文件上傳功能,通過(guò)配置組件參數(shù)和實(shí)現(xiàn)相應(yīng)的方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09
vue.js過(guò)濾器+ajax實(shí)現(xiàn)事件監(jiān)聽(tīng)及后臺(tái)php數(shù)據(jù)交互實(shí)例
這篇文章主要介紹了vue.js過(guò)濾器+ajax實(shí)現(xiàn)事件監(jiān)聽(tīng)及后臺(tái)php數(shù)據(jù)交互,結(jié)合實(shí)例形式分析了vue.js前臺(tái)過(guò)濾器與ajax后臺(tái)數(shù)據(jù)交互相關(guān)操作技巧,需要的朋友可以參考下2018-05-05

