vue3+ElementPlus+VueCropper實現(xiàn)上傳圖片功能
更新時間:2025年01月14日 09:58:18 作者:An_s
文章介紹了如何在Vue3、ElementPlus和VueCropper組件中實現(xiàn)圖片上傳和裁剪功能,包括放大、縮小等操作,感興趣的朋友跟隨小編一起看看吧
前言
我們需要上傳圖片,然后彈框進行裁剪(放大、縮?。?。
效果

實現(xiàn)
裁剪組件.vue
<template>
<div>
<!--裁剪圖片-->
<el-dialog v-model="tailorDialogVisible" @open="onTailorDialogOpen" @close="onTailorDialogCancel" title="編輯圖片" width="680" align-center>
<div style=" width: 550px; height: 450px; margin: 30px auto;" v-loading="loading"
element-loading-text="Loading...">
<vue-cropper ref="cropper"
:img="tailorOption.img"
:output-type="tailorOption.outputType"
:full="tailorOption.full"
:auto-crop="tailorOption.autoCrop"
:auto-crop-width="tailorOption.autoCropWidth"
:auto-crop-height="tailorOption.autoCropHeight"
:center-box="tailorOption.centerBox"
:max-img-size="tailorOption.max"
mode="cover"
@imgLoad="onTailorLoad"
></vue-cropper>
</div>
<div style="display: flex; margin: 0 200px; justify-content: center; align-items: center">
<div style="width: 40px;text-align: left; cursor: pointer;">
<!-- <el-icon @click="onScaleMinus(0.1)" :size="16"><Minus /></el-icon> -->
<span @click="onScaleMinus(0.1)">-號</span>
</div>
<div style="flex: 1">
<el-slider v-model="tailorAmplificationValue" :min="1" :max="3" :step="0.1" @change="onChangTailorAmplificationSlider" />
</div>
<div style="width: 40px;text-align: right; cursor: pointer;">
<!-- <el-icon @click="onScaleAdd(0.1)" :size="16"><Plus /></el-icon> -->
<span @click="onScaleAdd(0.1)">+號</span>
</div>
</div>
<div style="display: flex; margin: 10px 200px 40px 200px; justify-content: center; align-items: center">
<div style="width: 40px;text-align: left; cursor: pointer;">
<span @click="onRotateLeft">左旋</span>
<!-- <el-icon @click="onRotateLeft" :size="16"><Plus /></el-icon> -->
<!-- <img @click="onRotateLeft" style="width: 14px; height: 14px" src="../../../public/img/recipeManage/left_rotate.png" alt=""> -->
</div>
<div style="flex: 1">
<el-slider v-model="tailorSpinValue" :min="-180" :max="180" :step="90" @change="onChangTailorSpinSlider" />
</div>
<div style="width: 40px;text-align: right; cursor: pointer;">
<span @click="onRotateRight">右旋</span>
<!-- <el-icon @click="onRotateRight" :size="16"><Plus /></el-icon> -->
<!-- <img @click="onRotateRight" style="width: 14px; height: 14px" src="../../../public/img/recipeManage/right_rotate.png" alt=""> -->
</div>
</div>
<div style="padding-top: 20px;" class="recipeManage_border_top">
<div style="display: flex; align-items: center; justify-content: center">
<div>
<el-button type="primary" plain @click="onTailorDialogCancel">取消</el-button>
</div>
<div style="margin-left: 20px">
<el-button type="primary" @click="onTailorDialogSubmit">確認</el-button>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup>
import 'vue-cropper/dist/index.css'
import { VueCropper } from "vue-cropper";
// import { postImgData } from '@/api/base/public';
import { ref, defineProps, toRefs, defineEmits } from 'vue';
const emit = defineEmits(['close', 'submit']);
const props = defineProps({
tailorDialogImg: {
default: ''
},
autoCropWidth: {
default: 180
},
autoCropHeight: {
default: 180
},
tailorDialogVisible: {
type: Boolean,
required: true,
default: false
},
});
const { tailorDialogVisible, tailorDialogImg, autoCropWidth, autoCropHeight } = toRefs(props);
const loading = ref(false);
// 裁剪圖片
const cropper = ref("");
// const tailorDialogVisible = ref(visible.value);
const tailorAmplificationValue = ref(0);
const tailorSpinValue = ref(0);
const tailorOption = ref({
img: "",
full: false,
outputType: 'png',
autoCrop: true,
autoCropWidth: 180,
autoCropHeight: 180,
centerBox: true,
max: 99999,
});
// 放大
let oldTailorAmplificationValue = 0;
const onScaleAdd = (num) => {
if (tailorAmplificationValue.value === 3) return;
// tailorAmplificationValue.value = Number(parseFloat(tailorAmplificationValue.value + num).toFixed(1));
tailorAmplificationValue.value = +(parseFloat(tailorAmplificationValue.value + num).toFixed(1));
oldTailorAmplificationValue = tailorAmplificationValue.value;
cropper.value.changeScale(tailorAmplificationValue.value);
};
const onScaleMinus = (num) => {
if (tailorAmplificationValue.value === 1) return;
tailorAmplificationValue.value = tailorAmplificationValue.value - num;
oldTailorAmplificationValue = -tailorAmplificationValue.value;
cropper.value.changeScale(-tailorAmplificationValue.value);
};
const onChangTailorAmplificationSlider = (value) => {
if (oldTailorAmplificationValue > value) {
cropper.value.changeScale(-value);
} else {
cropper.value.changeScale(value);
}
oldTailorAmplificationValue = value;
};
// 旋轉
let oldTailorRotateValue = 0;
const onChangTailorSpinSlider = (value) => {
if (value > 0) {
cropper.value.rotateRight();
} else {
cropper.value.rotateLeft();
}
};
const onRotateLeft = () => {
if (cropper.value.rotate === -2) return false;
cropper.value.rotateLeft();
oldTailorRotateValue = cropper.value.rotate * 90
console.log("===oldTailorRotateValue===", oldTailorRotateValue)
tailorSpinValue.value = cropper.value.rotate * 90
};
const onRotateRight = () => {
if (cropper.value.rotate === 2) return false;
cropper.value.rotateRight();
oldTailorRotateValue = cropper.value.rotate * 90
console.log("===oldTailorRotateValue===", oldTailorRotateValue)
tailorSpinValue.value = cropper.value.rotate * 90
};
const onTailorDialogOpen = () => {
console.log("===彈框打開===");
loading.value = true;
tailorOption.value.img = tailorDialogImg.value;
tailorOption.value.autoCropWidth = autoCropWidth.value;
tailorOption.value.autoCropHeight = autoCropHeight.value;
};
const onTailorLoad = (msg) => {
console.log("===msg===", msg)
loading.value = false;
};
const onTailorDialogCancel = () => {
emit('close');
loading.value = false;
tailorOption.value.img = "";
tailorAmplificationValue.value = 0;
tailorSpinValue.value = 0;
};
const onTailorDialogSubmit = () => {
cropper.value.getCropData(data => {
tailorAmplificationValue.value = 0;
tailorSpinValue.value = 0;
tailorOption.value.img = "";
emit('submit', data);
})
// cropper.value.getCropBlob(data => {
// // 創(chuàng)建 FormData 對象并添加 Blob 對象
// const formData = new FormData();
// formData.append('file', data, '1.png');
// // postImgData(formData).then((res) => {
// // if (res.data.code === 200) {
// // emit('submit', res.data.data);
// // }
// // }).catch(err => {});
// tailorAmplificationValue.value = 0;
// tailorSpinValue.value = 0;
// tailorOption.value.img = "";
// emit('submit', '');
// })
// let blob = await cropper.value.getCropBlob();
// // 創(chuàng)建 FormData 對象并添加 Blob 對象
// const formData = new FormData();
// formData.append('file', blob, '1.png');
// let res = postImgData(formData);
//
// emit('submit', res.data.data);
//
// tailorAmplificationValue.value = 0;
// tailorSpinValue.value = 0;
// tailorOption.value.img = "";
};
</script>
<style>
</style>使用組件.vue
<template>
<div>
<el-upload action="#" :http-request="onImgRequest" :show-file-list="false" :before-upload="(file) => onImgUpload(file)">
<div style="height: 100px; width: 100px; background-color: red;">上傳</div>
</el-upload>
<el-image v-if="imagesUrl" :src="imagesUrl"></el-image>
<tailorImage :tailorDialogVisible="tailorDialogVisible" :tailorDialogImg="tailorDialogImg" @submit="tailorDialogImgSucc"></tailorImage>
<!-- <el-image :src="src" /> -->
</div>
</template>
<script setup>
import tailorImage from "./components/TailorImage.vue"
import {ref} from "vue"
import { ElMessage } from 'element-plus';
const tailorDialogVisible = ref(false)
const tailorDialogImg = ref("")
const imagesUrl = ref("")
const onImgRequest = () => {};
const onImgUpload = (rawFile) => {
if (rawFile.type.indexOf('image/') === -1) {
ElMessage.error('文件格式錯誤,請上傳圖片類型,如: JPG,PNG后綴的文件');
return false;
} else {
const reader = new FileReader();
reader.readAsDataURL(rawFile);
reader.onload = () => {
tailorDialogImg.value = reader.result;
tailorDialogVisible.value = true;
};
}
};
const tailorDialogImgSucc = (data) => {
// console.log("===tailorDialogImgSucc===", data)
imagesUrl.value = data;
tailorDialogVisible.value = false;
tailorDialogImg.value = "";
}
// const test = () => {
// tailorDialogVisible.value = true
// console.log("===裁剪圖片====");
// }
</script>
<style>
</style>到此這篇關于vue3+ElementPlus+VueCropper實現(xiàn)上傳圖片的文章就介紹到這了,更多相關vue3 ElementPlus VueCropper上傳圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue項目中使用rimraf?dev啟動時刪除dist目錄方式
這篇文章主要介紹了vue項目中使用rimraf?dev啟動時刪除dist目錄方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04
vue3配置代理實現(xiàn)axios請求本地接口返回PG庫數(shù)據(jù)
這篇文章主要為大家詳細介紹了vue3配置代理實現(xiàn)axios請求本地接口返回PG庫數(shù)據(jù)的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下2025-03-03
Vue使用Element實現(xiàn)增刪改查+打包的步驟
這篇文章主要介紹了Vue使用Element實現(xiàn)增刪改查+打包的步驟,幫助大家更好的理解和學習vue框架,感興趣的朋友可以了解下2020-11-11
vue用Object.defineProperty手寫一個簡單的雙向綁定的示例
這篇文章主要介紹了用Object.defineProperty手寫一個簡單的雙向綁定的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
使用Vue調(diào)取接口,并渲染數(shù)據(jù)的示例代碼
今天小編就為大家分享一篇使用Vue調(diào)取接口,并渲染數(shù)據(jù)的示例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10

