文章目录
-
-
- [一、安装(Vue 3 专用)](#一、安装(Vue 3 专用))
- [二、核心 API 说明](#二、核心 API 说明)
-
- [1. 常用 Props(配置项)](#1. 常用 Props(配置项))
- [2. 常用事件](#2. 常用事件)
- [3. 常用方法(通过 ref 调用)](#3. 常用方法(通过 ref 调用))
- [三、Vue 3 完整示例(Composition API)](#三、Vue 3 完整示例(Composition API))
-
- [1. 组件代码(直接复制可用)](#1. 组件代码(直接复制可用))
- 四、全局引入(可选)
- 五、常见场景与技巧
- [六、TypeScript 支持](#六、TypeScript 支持)
- 七、总结
-
vue-cropper 是一款专为 Vue 设计的轻量级图片裁剪组件,支持实时预览、旋转、缩放、固定比例、自动裁剪 等核心功能。在 Vue 3 中需安装 @next 版本,以下是完整详解与可直接运行的示例。
一、安装(Vue 3 专用)
bash
# npm
npm install vue-cropper@next --save
# yarn
yarn add vue-cropper@next
# pnpm
pnpm add vue-cropper@next
二、核心 API 说明
1. 常用 Props(配置项)
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
img |
String | - | 图片地址(URL / Base64) |
outputSize |
Number | 1 | 输出质量(0-1) |
outputType |
String | 'jpeg' | 格式:jpeg / png / webp |
autoCrop |
Boolean | false | 是否自动生成裁剪框 |
autoCropWidth |
Number | 200 | 自动裁剪宽度 |
autoCropHeight |
Number | 200 | 自动裁剪高度 |
fixed |
Boolean | false | 是否固定裁剪比例 |
fixedNumber |
Array | [] | 固定宽高比,如 [1,1](正方形) |
canScale |
Boolean | true | 能否鼠标滚轮缩放 |
canMove |
Boolean | true | 能否移动图片 |
canMoveBox |
Boolean | true | 能否拖动裁剪框 |
2. 常用事件
@realTime:实时裁剪触发(返回预览数据)@imgLoad:图片加载完成@cropMove:裁剪框移动时
3. 常用方法(通过 ref 调用)
javascript
// 旋转
cropper.value.rotateRight() // 右旋转90°
cropper.value.rotateLeft() // 左旋转90°
// 缩放
cropper.value.changeScale(1) // 放大
cropper.value.changeScale(-1) // 缩小
// 获取结果
cropper.value.getCropData((data) => {
// data = Base64
})
cropper.value.getCropBlob((blob) => {
// blob = 二进制(上传用)
})
三、Vue 3 完整示例(Composition API)
1. 组件代码(直接复制可用)
vue
<template>
<div class="cropper-demo">
<h3>Vue3 + vue-cropper 图片裁剪</h3>
<!-- 上传选择图片 -->
<input
type="file"
accept="image/*"
@change="handleFileChange"
class="file-input"
/>
<!-- 裁剪组件 -->
<div class="cropper-box" v-if="options.img">
<vue-cropper
ref="cropper"
:img="options.img"
:output-size="options.outputSize"
:output-type="options.outputType"
:auto-crop="options.autoCrop"
:auto-crop-width="options.autoCropWidth"
:auto-crop-height="options.autoCropHeight"
:fixed="options.fixed"
:fixed-number="options.fixedNumber"
:can-scale="options.canScale"
@real-time="realTimePreview"
style="width: 100%; height: 400px; border: 1px solid #eee;"
/>
</div>
<!-- 工具栏 -->
<div class="tool-bar" v-if="options.img">
<button @click="rotateLeft">↺ 左旋转</button>
<button @click="rotateRight">↻ 右旋转</button>
<button @click="zoomIn">+ 放大</button>
<button @click="zoomOut">- 缩小</button>
<button @click="getCropBase64">✅ 获取Base64</button>
<button @click="getCropBlob">✅ 获取Blob</button>
</div>
<!-- 预览区 -->
<div class="preview-wrapper" v-if="previewUrl">
<h4>裁剪预览</h4>
<img :src="previewUrl" class="preview-img" />
</div>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
// 引入组件与样式
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'
const cropper = ref(null)
// 配置项
const options = reactive({
img: '', // 图片
outputSize: 1, // 质量
outputType: 'jpeg', // 格式
autoCrop: true, // 自动裁剪
autoCropWidth: 200,
autoCropHeight: 200,
fixed: true, // 固定比例
fixedNumber: [1, 1], // 1:1 正方形(头像)
canScale: true // 允许缩放
})
const previewUrl = ref('')
// 选择本地图片
const handleFileChange = (e) => {
const file = e.target.files[0]
if (!file) return
const reader = new FileReader()
reader.onload = (ev) => {
options.img = ev.target.result
}
reader.readAsDataURL(file)
}
// 实时预览
const realTimePreview = (data) => {
previewUrl.value = data.url
}
// 旋转
const rotateLeft = () => cropper.value.rotateLeft()
const rotateRight = () => cropper.value.rotateRight()
// 缩放
const zoomIn = () => cropper.value.changeScale(1)
const zoomOut = () => cropper.value.changeScale(-1)
// 获取 Base64
const getCropBase64 = () => {
cropper.value.getCropData((data) => {
console.log('Base64:', data)
alert('Base64 已输出到控制台')
})
}
// 获取 Blob(用于上传)
const getCropBlob = () => {
cropper.value.getCropBlob((blob) => {
console.log('Blob:', blob)
alert('Blob 已输出到控制台(可直接上传)')
})
}
</script>
<style scoped>
.cropper-demo {
max-width: 800px;
margin: 20px auto;
padding: 20px;
}
.file-input {
margin: 10px 0;
}
.tool-bar {
margin: 15px 0;
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.tool-bar button {
padding: 6px 12px;
cursor: pointer;
}
.preview-img {
width: 200px;
height: 200px;
object-fit: cover;
border: 1px solid #ddd;
}
</style>
四、全局引入(可选)
在 main.js 中全局注册,所有组件可直接使用:
javascript
import { createApp } from 'vue'
import App from './App.vue'
import VueCropper from 'vue-cropper'
import 'vue-cropper/dist/index.css'
const app = createApp(App)
app.use(VueCropper)
app.mount('#app')
五、常见场景与技巧
-
头像裁剪(正方形固定比例)
javascriptfixed: true, fixedNumber: [1, 1] -
封面图(16:9)
javascriptfixed: true, fixedNumber: [16, 9] -
禁止移动/缩放
javascriptcanMove: false, canScale: false, canMoveBox: false -
上传服务器(Blob 方式推荐)
javascriptconst formData = new FormData() cropper.value.getCropBlob((blob) => { formData.append('avatar', blob, 'avatar.jpg') // axios.post('/api/upload', formData) })
六、TypeScript 支持
如遇类型缺失,可在项目根目录创建 vue-cropper.d.ts:
typescript
declare module 'vue-cropper' {
import type { DefineComponent } from 'vue'
const VueCropper: DefineComponent<any, any, any>
export { VueCropper }
}
七、总结
- Vue 3 必须安装
vue-cropper@next - 核心流程:选择图片 → 裁剪配置 → 实时预览 → 获取 Base64 / Blob → 上传
- 常用功能:固定比例、旋转、缩放、自动裁剪
- 上传推荐使用 Blob 格式,体积更小、兼容性更好