vue-cropper图片裁剪(vue2与vue3)

在项目中,前端开发经常会遇到有图片上传的需求,而别人的组件大多都满足不了当下产品的需求,这是往往我们得去依靠组件自己自定义一个项目通用的裁剪组件

一、vue-cropper安装依赖:

vue2:

npm install vue-cropper  或  yarn add vue-cropper

vue3:

npm install vue-cropper@next  或  yarn add vue-cropper@next

二、引入相关css文件

import 'vue-cropper/dist/index.css'

vue3才需要引入样式,vue2不需要

注意:这个样式一定记得引啊,我就是忘引入,裁剪框一直弄不出来

三、自定义组件

<!-- 裁剪图片工具-->
<template>
<view class="upgrade-box">
<szy-common-popup poptitle="裁剪图片" showPopup position="center" @close_popup="close_popup">
<view class="prompt-content">
<view class="inner-box">
<view class="tip">提示:按微信公众号封面图2:35:1或1:1比例选择保留区域后,裁剪上传。</view>
<!-- 选择裁剪比例 -->
<view class="group-btn">
<view
class="item"
:class="option.fixedNumber[0] === 2.35 ? 'item active' : 'item'"
@click="cropSize(2.35, 1)"
>2:35:1</view
>
<view
class="item"
:class="option.fixedNumber[0] === 1 ? 'item active' : 'item'"
@click="cropSize(1, 1)"
>1:1</view
>
</view>
<!-- 裁剪区域 -->
<view
class="cropper-box"
:style="{ width: `${imgObj.width}px`, height: `${imgObj.height}px` }"
>
<VueCropper
ref="cropperRef"
:img="option.img"
:output-size="option.outputSize"
:output-type="option.outputType"
:can-scale="option.canScale"
:auto-crop="option.autoCrop"
:full="option.full == '0'"
:auto-crop-width="option.autoCropWidth"
:auto-crop-height="option.autoCropHeight"
:can-move-box="option.canMoveBox"
:can-move="option.canMove"
:center-box="option.centerBox"
:info="option.info"
:fixed-box="option.fixedBox"
:fixed="option.fixed"
:fixed-number="option.fixedNumber"
/>
</view>
</view>
<view class="button-group">
<view class="dialog-button" @click="close_popup">
<text class="dialog-button-text">取消</text>
</view>
<view class="dialog-button button-confirm" @click="cropperClick">
<text class="dialog-button-text">保存/上传</text>
</view>
</view>
</view>
</szy-common-popup>
</view>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { VueCropper } from 'vue-cropper';
import 'vue-cropper/dist/index.css'; // vue3才需要引入样式,vue2不要
const props = defineProps({
coverFile: {
type: String,
require: '',
},
});
// 裁剪组件Ref
const cropperRef: any = ref({});
// 裁剪组件需要使用到的参数
interface Options {
img: string;
outputSize: number; // 裁剪生成图片质量
outputType: string; // 裁剪生成图片格式
canScale: boolean; // 图片是否允许滚轮播放
autoCrop: boolean; // 是否默认生成截图框 false
info: boolean; // 是否展示截图框信息
autoCropWidth: number; // 生成截图框的宽度
autoCropHeight: number; // 生成截图框的高度
canMoveBox: boolean; // 截图框是否可以拖动
enlarge: number;
fixedBox: boolean; // 固定截图框的大小
fixed: boolean; // 是否开启截图框宽高固定比例
fixedNumber: number[]; // 截图框的宽高比例 默认2.35, 1:1,
canMove: boolean; // 上传图片是否可拖动
centerBox: boolean; // 截图框限制在图片里面
accept: string; // 上传允许的格式
infoTrue: boolean;
original: boolean;
full: boolean | string;
}
const option = ref<Options>({
img: String(props.coverFile), // 裁剪图片地址
outputSize: 1, // 裁剪生成图片质量
outputType: 'jpeg', // 裁剪生成图片格式
canScale: true, // 图片是否允许滚轮播放
autoCrop: true, // 是否默认生成截图框 false
info: true, // 是否展示截图框信息
autoCropWidth: 235, // 生成截图框的宽度
autoCropHeight: 100, // 生成截图框的高度
enlarge: 1, // 采集后放大倍数
full: '0', // 是否开启原尺寸裁剪 0 原尺寸 1当前尺寸
infoTrue: true,
original: true,
canMoveBox: true, // 截图框是否可以拖动
fixedBox: false, // 固定截图框的大小
fixed: true, // 是否开启截图框宽高固定比例
fixedNumber: [2.35, 1], // 截图框的宽高比例 默认2.35, 1:1,
canMove: true, // 上传图片是否可拖动
centerBox: true, // 截图框限制在图片里面
accept: 'image/jpeg,image/jpg,image/png,image/gif,image/x-icon',
});
const handleSelectImg = (imgItem: any) => {
option.value.img = String(imgItem);
};
// 外框大小
const imgObj = ref({
width: 300,
height: 200,
});
// 修改截图框尺寸,宽,高
const cropSize = (w: number, h: number) => {
option.value.fixedNumber = [w, h];
cropperRef.value.refresh();
};
// 裁剪后
const cropperClick = () => {
cropperRef.value.getCropData((data: any) => {
emit('cropperClick', data);
});
};
//
const emit = defineEmits(['onClose', 'cropperClick']);
const close_popup = () => {
emit('onClose');
};
onMounted(() => {
handleSelectImg(String(props.coverFile));
});
</script>
<style lang="scss" scoped>
.upgrade-box {
.inner-box {
.tip {
font-size: 30rpx;
text-align: left;
}
.group-btn {
display: flex;
align-items: center;
justify-content: flex-start;
margin: 20rpx 0rpx;
.item {
flex: 1;
display: inline-flex;
background: rgba(0, 0, 0, 0.03);
border-radius: 6rpx 6rpx 0 0;
text-align: center;
justify-content: center;
align-items: center;
padding: 0 30rpx;
height: 80rpx;
white-space: nowrap;
font-size: 34rpx;
cursor: pointer;
color: #353535;
position: relative;
&:after {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 1rpx;
background: #eee;
height: 100%;
display: block;
}
&:first-child {
border-radius: 6rpx 0 0 6rpx;
&:after {
display: none;
}
}
&.active {
background: $uni-main-color;
color: #fff;
border-radius: 6rpx;
}
}
}
.cropper-box {
background: #eee;
overflow: hidden;
}
}
}
</style>

四、展示样式

posted @   蓦然JL  阅读(1484)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
  1. 1 唯一 G.E.M.邓紫棋
  2. 2 他只是经过 白敬亭 魏大勋
  3. 3 Uptown Funk Mark Ronson / Bruno Mars
  4. 4 在你的身边 盛哲
  5. 5 Edge of My Life Manafest
  6. 6 凄美地 郭顶
  7. 7 Wonderful Tonight Boyce Avenue
  8. 8 心如止水 Ice Paper
  9. 9 Sugar Maroon 5
  10. 10 静谧时光 JIAxNING
  11. 11 Right Now (Na Na Na) Aamir
  12. 12 Dangerously Charlie Puth
  13. 13 Someone You Loved Madilyn Paige
  14. 14 Shape of My Heart Boyce Avenue
  15. 15 We Can't Stop Boyce Avenue / Bea Miller
  16. 16 Perfect Boyce Avenue
  17. 17 Love Me Like You Do Boyce Avenue
  18. 18 Thank You Boyce Avenue
  19. 19 Don’t Wanna Know Boyce Avenue / Sarah Hyland
Uptown Funk - Mark Ronson / Bruno Mars
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

Not available

访问主页
关注我
关注微博
私信我
返回顶部
点击右上角即可分享
微信分享提示

目录导航