Skip to content

CropperUpload

裁剪上传,常在上传头像等场景下使用。基于 vue-cropper 二次封装。

WARNING

目前受 Vitepress 框架限制,此文档暂时无在线示例, 详见

基础用法

vue
<template>
    <ham-cropper-upload ref="cropperRef" repository="ibu"> </ham-cropper-upload>
    <el-button @click="submit" style="margin-top: 8px">提交</el-button>
    <el-button @click="clear" style="margin-top: 8px">清空</el-button>
</template>

<script setup>
import { ref } from 'vue'

const cropperRef = ref()

const submit = () => {
    cropperRef.value.upload().then(url => {
        console.log(url)
    })
}

const clear = () => {
    cropperRef.value.clear()
}
</script>
<template>
    <ham-cropper-upload ref="cropperRef" repository="ibu"> </ham-cropper-upload>
    <el-button @click="submit" style="margin-top: 8px">提交</el-button>
    <el-button @click="clear" style="margin-top: 8px">清空</el-button>
</template>

<script setup>
import { ref } from 'vue'

const cropperRef = ref()

const submit = () => {
    cropperRef.value.upload().then(url => {
        console.log(url)
    })
}

const clear = () => {
    cropperRef.value.clear()
}
</script>

设置默认图片

vue
<template>
    <ham-cropper-upload ref="cropperRef1" repository="ibu" defaultImg="/swiper1.png">
    </ham-cropper-upload>
    <el-button @click="submit" style="margin-top: 8px">提交</el-button>
</template>

<script setup>
import { ref } from 'vue'

const cropperRef = ref()

const submit = () => {
    cropperRef.value.finish().then(file => {
        console.log(file)
    })
}
</script>
<template>
    <ham-cropper-upload ref="cropperRef1" repository="ibu" defaultImg="/swiper1.png">
    </ham-cropper-upload>
    <el-button @click="submit" style="margin-top: 8px">提交</el-button>
</template>

<script setup>
import { ref } from 'vue'

const cropperRef = ref()

const submit = () => {
    cropperRef.value.finish().then(file => {
        console.log(file)
    })
}
</script>

自定义裁剪图片

vue
<template>
    <ham-cropper-upload
        ref="cropperRef"
        repository="ibu"
        :showPreviewList="false"
        :fixed="false"
        :containerWidth="400"
        :containerHeight="200"
        @onRealTime="onRealTime"
    >
    </ham-cropper-upload>
    <div id="preview" style="margin-top: 8px" v-if="previews?.url">
        <p>截图框大小</p>
        <div :style="previewStyle">
            <div :style="previews?.div">
                <img :src="previews?.url" :style="previews?.img" />
            </div>
        </div>
        <p>固定为100高度</p>
        <div :style="previewStyle1">
            <div :style="previews?.div">
                <img :src="previews?.url" :style="previews?.img" />
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref } from 'vue'

const cropperRef = ref()
const previews = ref({})
const previewStyle = ref({})
const previewStyle1 = ref({})

const onRealTime = data => {
    previews.value = data
    previewStyle.value = {
        width: `${data.w}px`,
        height: `${data.h}px`,
        overflow: 'hidden',
        margin: '0',
    }
    previewStyle1.value = {
        width: `${data.w}px`,
        height: `${data.h}px`,
        overflow: 'hidden',
        margin: '0',
        zoom: 100 / data.h,
    }
}

const submit = () => {
    cropperRef.value.finish().then(file => {
        console.log(file)
    })
}
</script>
<template>
    <ham-cropper-upload
        ref="cropperRef"
        repository="ibu"
        :showPreviewList="false"
        :fixed="false"
        :containerWidth="400"
        :containerHeight="200"
        @onRealTime="onRealTime"
    >
    </ham-cropper-upload>
    <div id="preview" style="margin-top: 8px" v-if="previews?.url">
        <p>截图框大小</p>
        <div :style="previewStyle">
            <div :style="previews?.div">
                <img :src="previews?.url" :style="previews?.img" />
            </div>
        </div>
        <p>固定为100高度</p>
        <div :style="previewStyle1">
            <div :style="previews?.div">
                <img :src="previews?.url" :style="previews?.img" />
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref } from 'vue'

const cropperRef = ref()
const previews = ref({})
const previewStyle = ref({})
const previewStyle1 = ref({})

const onRealTime = data => {
    previews.value = data
    previewStyle.value = {
        width: `${data.w}px`,
        height: `${data.h}px`,
        overflow: 'hidden',
        margin: '0',
    }
    previewStyle1.value = {
        width: `${data.w}px`,
        height: `${data.h}px`,
        overflow: 'hidden',
        margin: '0',
        zoom: 100 / data.h,
    }
}

const submit = () => {
    cropperRef.value.finish().then(file => {
        console.log(file)
    })
}
</script>

在 ElForm 内使用

vue
<template>
    <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules">
        <el-form-item label="头像" prop="avatar">
            <ham-cropper-upload ref="cropperRef" repository="ibu"> </ham-cropper-upload>
        </el-form-item>
    </el-form>
    <el-button @click="submit(ruleFormRef)" style="margin-left: 50px">提交</el-button>
</template>

<script setup>
import { ref, reactive } from 'vue'

const cropperRef = ref()
const ruleFormRef = ref()

const ruleForm = reactive({})
const rules = reactive({
    avatar: [
        {
            required: true,
            message: '请选择图片',
            trigger: 'change',
            validator(rule, value, callback) {
                if (!cropperRef.value.getImg()) {
                    callback(rule.message)
                } else {
                    callback()
                }
            },
        },
    ],
})

async function submit(formEl) {
    if (!formEl) return
    await formEl.validate(valid => {
        if (valid) {
            cropperRef.value.upload().then(url => {
                console.log(url)
            })
        }
    })
}
</script>
<template>
    <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules">
        <el-form-item label="头像" prop="avatar">
            <ham-cropper-upload ref="cropperRef" repository="ibu"> </ham-cropper-upload>
        </el-form-item>
    </el-form>
    <el-button @click="submit(ruleFormRef)" style="margin-left: 50px">提交</el-button>
</template>

<script setup>
import { ref, reactive } from 'vue'

const cropperRef = ref()
const ruleFormRef = ref()

const ruleForm = reactive({})
const rules = reactive({
    avatar: [
        {
            required: true,
            message: '请选择图片',
            trigger: 'change',
            validator(rule, value, callback) {
                if (!cropperRef.value.getImg()) {
                    callback(rule.message)
                } else {
                    callback()
                }
            },
        },
    ],
})

async function submit(formEl) {
    if (!formEl) return
    await formEl.validate(valid => {
        if (valid) {
            cropperRef.value.upload().then(url => {
                console.log(url)
            })
        }
    })
}
</script>

属性

属性名说明类型默认值版本
baseUrl基础地址string
serve文件上传地址string/basic/file/upload/multi?repository=
repository仓库string
containerHeight裁剪容器高度number240
containerWidth裁剪容器宽度number240
outputSize裁剪生成图片的质量 0.1~1number1
outputType裁剪生成图片的格式'jpeg' | 'png' | 'webp'png
info裁剪框的大小信息booleantrue
canScale图片是否允许滚轮缩放booleanfalse
autoCrop是否默认生成截图框booleantrue
autoCropWidth默认生成截图框宽度number
autoCropHeight默认生成截图框高度number
canMove上传图片是否可以移动booleanfalse
centerBox截图框是否被限制在图片里面booleantrue
triggerTxt触发文件选择框的文本string上传图片
fixed是否开启截图框宽高固定比例booleantrue
fixedNumber宽高比例值[number, number][1, 1]
showPreviewList是否显示预览列表booleantrue
full是否输出原图比例的截图booleantrue

方法

方法名说明类型
upload上传裁剪图片到文件服务器,返回在线图片地址() => Promise<string>
finish返回一个 File 文件对象() => Promise<File>
clear清空组件内部 Input File 缓存() => void

事件

事件名说明参数
onRealTime实时预览事件(data) => void