Vue3图片上传剪裁vue-picture-cropper

小罗同学2024-05-2114

官网地址

vue-picture-cropper官网地址

介绍

::: danger 注意
请注意只能在 Vue 3 项目里使用,且 Vue 版本号至少为 =3.2.13 ,不支持 Vue 2 。
:::

安装插件 #

使用 npm :

npm install vue-picture-cropper

使用 yarn :

yarn add vue-picture-cropper

使用 pnpm :

pnpm add vue-picture-cropper

按需引入 #

在 Vue 组件里按需引入,模板和实例也仅限在组件内使用。

ts

import VuePictureCropper, { cropper } from 'vue-picture-cropper'

工具实例,可用于操作相关的 API ,必须用花括号导入该名称

基础用法 #

这里提供一个基础用法的代码片段介绍,完整用法可以参考在线演示的例子,提供了功能演示和源码参考。

使用 JavaScript #

标准组件写法:

vue

<script>
    import VuePictureCropper, { cropper } from 'vue-picture-cropper'
    
    export default {
      components: {
        VuePictureCropper,
      },
      // ...
    }
    </script> 

使用 script-setup 语法糖:

vue

 <script setup>
    import VuePictureCropper, { cropper } from 'vue-picture-cropper'
    </script>

使用 TypeScript #

标准组件写法:

vue

<script lang="ts">
    import { defineComponent } from 'vue'
    import VuePictureCropper, { cropper } from 'vue-picture-cropper'
    
    export default defineComponent({
      components: {
        VuePictureCropper,
      },
      // ...
    })
    </script>

使用 script-setup 语法糖:

vue

<script setup lang="ts">
    import VuePictureCropper, { cropper } from 'vue-picture-cropper'
    </script>

渲染组件 #

导入的 VuePictureCropper 是一个组件,像平时引入子组件那样使用即可。


<label for="input-file">
                    <div class="upload-icon-bg" :style="{background:bgstr,backgroundSize:'cover',backgroundRepeat:'no-repeat'}">
                        <div v-show="bgstr =='#f2f3f5'" class="icon-center">
                            <img class="upload-icon-img" src="~@/assets/images/camera.png" alt="" srcset="">
                            <el-text class="upload-tips">上传会籍照片</el-text>
                        </div>
                    <input class="input-file" id="input-file" @change="fileUpload" single accept="image/*" style="display: none;" type="file">
                    </div>
                </label>
<!-- 上传头像截图弹窗 -->
    <el-dialog
        class="cliap-dialog"
        v-model="pageConfig.isShowModel"
        title="剪裁上传图片"
        width="350"
        :before-close="handleClose"
    >
    <div class="cliap-content">
            <VuePictureCropper
                :boxStyle="{
                width: '100%',
                height: '100%',
                backgroundColor: '#f8f8f8',
                margin: 'auto',
                maxHeight:'350px'
                }"
                :img="review"
                :options="{
                viewMode: 1,
                dragMode: 'crop',
                aspectRatio: 1 / 1,
                }"
                @ready="readyHandler"
            />
        </div>
        <template #footer>
        <div class="dialog-footer">
            <el-button @click="resetCliapHandler">重置</el-button>
            <el-button type="primary" @click="confirmClipping">
            上传
            </el-button>
        </div>
        </template>
    </el-dialog>
let fileUpload = (e) => {
    showLoading('正在上传...')
    let file = e.target.files[0] // 获取到的文件
    console.log('file',file);
    if(!file){
        closeLoading()
        console.log('失败回调');
        ElMessage({
            message: '已取消',
            type: 'info',
            plain: true,
        })
        return
    }
    // 获取上传文件的base64信息并显示预览信息
    let fileReader = new FileReader()
    let base64 = ''
    fileReader.readAsDataURL(file)
    fileReader.onload = function (event){
        console.log('onloadRead',event.target.result);
        base64 = event.target.result
        // bgstr.value = `url(${base64})`
        review.value = base64
        closeLoading()
        pageConfig.isShowModel = true
        // ElMessage.success('选择的图片长度为'+ (base64.length / 1024).toFixed(0) + 'kb')
    }
}

/* 准备完毕处理函数 */
let readyHandler = () => {
    console.log('图片处理完成');
}

/** 确认剪裁当前区域 */
let confirmClipping = () => {
    let clipBase = cropper.getDataURL()
    console.log('剪裁',clipBase);
    bgstr.value = `url(${clipBase})`
    pageConfig.isShowModel = false
}

/* 重置剪裁区域 */
let resetCliapHandler = () => {
    cropper.reset()
}

vue

<template>
      <VuePictureCropper
        :boxStyle="{
          width: '100%',
          height: '100%',
          backgroundColor: '#f8f8f8',
          margin: 'auto',
        }"
        :img="pic"
        :options="{
          viewMode: 1,
          dragMode: 'crop',
          aspectRatio: 16 / 9,
        }"
        @ready="ready"
      />
    </template>

对于文件的选择以及裁剪结果,请通过 <input type="file" > 和 cropper 实例的 API 获取,可参考在线演示的例子源码。

多个裁剪框 #

0.5.0 版本开始支持在同一个页面里使用多个裁剪框,无需额外配置,可在 多个裁剪框 demo 体验并参考 demo 源码使用。

TIP

当存在多个裁剪框时,请在 <input type="file" /> 选择了图片之后,需要重置掉原先裁剪目标的值,避免使用同一张图片无法触发 Watch 侦听导致实例切换失败。

License #

MIT License © 2020 chengpeiquan

分类:前端Vue

标签:前端vue3

上一篇SKU商品规格属性-笛卡尔乘积算法下一篇ElementPlus自动按需引入以及限制表单输入数字

版权声明

本文系作者 @小罗同学 转载请注明出处,文中若有转载的以及参考文章地址也需注明。\(^o^)/~

Preview