vue3 vue-cropper实现图片裁剪+上传功能(组件封装使用)

效果(CV即用)

Snipaste_2023-12-26_18-49-34.png

1.安装引入vue-cropper(官网)官网地址

  npm install vue-cropper@next
  import 'vue-cropper/dist/index.css'
  import { VueCropper }  from "vue-cropper";

2. 全局引入

import VueCropper from 'vue-cropper'; 
import 'vue-cropper/dist/index.css'

const app = createApp(App)
app.use(VueCropper)
app.mount('#app')

3.组件完整代码

<template>
  <div class="avatar-container" @click="editImage()">
    <el-dialog
      :title="title"
      :model-value="dialogVisibleCorpper"
      width="800px"
      append-to-body
      @opened="openDialog"
      :before-close="beforeClose"
    >
      <el-row>
        <el-col :span="12" style="height: 300px">
          <vue-cropper
            ref="cropper"
            :img="options.img"
            :info="true"
            :autoCrop="options.autoCrop"
            :autoCropWidth="options.autoCropWidth"
            :autoCropHeight="options.autoCropHeight"
            :fixedBox="options.fixedBox"
            :outputType="options.outputType"
            @realTime="realTime"
            v-if="showCropper"
          />
        </el-col>
        <el-col :span="12" style="height: 300px">
          <div class="preview-box">
            <img v-if="previews.url" :src="previews.url" :style="previews.img" />
            <span v-else></span>
          </div>
        </el-col>
      </el-row>
      <el-row style="margin-top: 12px">
        <el-col :span="12">
          <el-row>
            <el-col :span="8">
              <el-upload
                action="#"
                :http-request="() => {}"
                :before-upload="beforeUpload"
                :show-file-list="false"
              >
                <el-button>选择</el-button>
              </el-upload>
            </el-col>
            <el-col :span="4">
              <el-button :icon="Plus" @click="changeScale(1)"></el-button>
            </el-col>
            <el-col :span="4">
              <el-button :icon="Minus" @click="changeScale(-1)"></el-button>
            </el-col>
            <el-col :span="4">
              <el-button :icon="RefreshLeft" @click="rotateLeft()"></el-button>
            </el-col>
            <el-col :span="4">
              <el-button :icon="RefreshRight" @click="rotateRight()"></el-button>
            </el-col>
          </el-row>
        </el-col>
        <el-col :span="4" :offset="8" style="margin-left: 22.3%">
          <el-button type="primary" @click="determine()">提 交</el-button>
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>
 
<script setup lang="ts">
import { Plus, Minus, RefreshLeft, RefreshRight } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'
import { getCurrentInstance, ref, reactive, watch } from 'vue'

const { proxy } = getCurrentInstance()
const props = defineProps({
  dialogVisibleCorpper: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: '上传图片'
  }
})
const showCropper = ref(false)
// cropper配置  更多配置可参考 https://www.npmjs.com/package/vue-cropper
const options = reactive({
  img: null, // 裁剪图片的地址
  autoCropWidth: 200, // 默认生成截图框宽度 默认容器的 80%
  autoCropHeight: 200, // 默认生成截图框高度 默认容器的 80%
  outputType: 'png', // 裁剪生成图片的格式 jpeg, png, webp
  autoCrop: true, // 是否默认生成截图框
  fixedBox: false // 固定截图框大小
})
const previews = ref({
  url: ''
})

// 打开裁剪弹窗
const openDialog = () => {
  showCropper.value = true
}
// 修改图片大小 正数为变大 负数变小
const changeScale = (num) => {
  num = num || 1
  proxy.$refs.cropper.changeScale(num)
}
// 向左边旋转90度
const rotateLeft = () => {
  proxy.$refs.cropper.rotateLeft()
}
// 向右边旋转90度
const rotateRight = () => {
  proxy.$refs.cropper.rotateRight()
}
// 上传图片处理
const beforeUpload = (rawFile) => {
  if (rawFile.type.indexOf('image/') == -1) {
    ElMessage.error('请上传图片类型文件!')
    return false
  }
  if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('文件大小不能超过2MB!')
    return false
  }
  const reader = new FileReader()
  reader.readAsDataURL(rawFile)
  reader.onload = () => {
    // 图片在这里
    options.img = reader.result
  }
} 
// 实时预览事件
const realTime = (data) => {
  previews.value = data
}
const emit = defineEmits(['update:dialogVisibleCorpper', 'confirm'])

// 关闭弹窗
const beforeClose = () => {
  options.img = null
  previews.value.url = ''
  emit('update:dialogVisibleCorpper', false)
}
// 提交图片
const determine = () => {
  options.img = null
  previews.value.url = ''
  emit('confirm')
}
</script>
 
<style lang='scss' scoped>
.avatar-container {
  .img-box {
    border-radius: 50%;
    border: 1px solid #ccc;
    width: 10vw;
    height: 10vw;
  }
}
.preview-box {
  position: absolute;
  top: 50%;
  transform: translate(50%, -50%);
  width: 200px;
  height: 200px;
  border-radius: 50%;
  border: 1px solid #ccc;
  overflow: hidden;
}
</style>

4. 组件使用

<template>
  <div class="avatar-box">
    <el-button @click="btnClick">点击</el-button>
    <ImgCorpper v-model:dialogVisibleCorpper="dialogVisibleCorpper" @confirm="confirm" />
  </div>
</template>  
  
<script setup lang="ts">
import { ref } from 'vue'

const dialogVisibleCorpper = ref(false)
// 组件点击事件
const btnClick = () => {
  dialogVisibleCorpper.value = true
}
// 组件提交事件
const confirm = () => {
  dialogVisibleCorpper.value = false
}
</script>
<style lang="scss" scoped>
.avatar-box {
  width: 300px;
  display: flex;
  justify-content: center;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/272064.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

链接世界与中国时尚文化,积萨伯爵国际时尚品牌在中国大放异彩

时尚的历史是一部文化发展的历史。从中国古代到现代西方&#xff0c;每个时代的时尚都有其独特的文化背景和历史意义。自丝绸之路开启了古代中国与罗马帝国之间的贸易&#xff0c;时尚的不断创新和变革&#xff0c;是文化变迁和时代精神的反映。时尚的变化&#xff0c;也引领着…

关于Axios发送Get请求无法添加Content-Type

在拦截器中尝试给headers添加Content-Type&#xff1a; request.interceptors.request.use(config > {if (!config.headers[Content-Type]) {config.headers[Content-Type] application/json;}return config;},error > {return Promise.reject(error)} )如果是GET请求&…

nuc980开发板使用Agile Modbus软件包-基于 rs485 通讯

一、nuc980开发板电路 打开 nuc980-eth2p 开发板原理图&#xff0c;如下&#xff1a; 将JP1跳线帽连接到rs485。使用rs485转usb连接到电脑即可。 除了收发引脚&#xff0c;多了一个控制引脚。 linux内核使能串口4 二、Agile Modbus软件包 1、软件包的获取 下载网址 选择…

SQLite 安装与使用

SQLite 安装与使用 文章目录 SQLite 安装与使用1.什么是 SQLite&#xff1f;2.为什么要用 SQLite&#xff1f;3 安装3.1 在 Windows 上安装 SQLite3.2 安装路径3.3 接下来需要配置环境变量3.4 配置完变量测试成功3.5 创建数据库成功3.6 图形化界面操作3.7 数据表的增删改查新增…

代码随想录算法训练营Day10 | 239.滑动窗口的最大值、347.前K个高频元素

LeetCode 239 滑动窗口的最大值 本题思路: 采用单调队列来完成&#xff0c;单调队列就是队列里的元素顺序&#xff0c;是单调递减/递增的情况。 那么我们应该如何维护这个单调队列呢&#xff0c;此处既然是最大值&#xff0c;那么采用的是单调递减的队列。让队列的出口处是当前…

基于JSP+Servlet+Mysql的宠物管理系统(简单增删改查)

基于JSPServletMysql的宠物管理系统_简单增删改查 一、系统介绍二、功能展示1.主页2.增加3.修改4.查询5.删除 四、其它1.其他系统实现五.获取源码 一、系统介绍 项目名称&#xff1a;基于JSPServletMysql的宠物管理系统(简单增删改查) 项目架构&#xff1a;B/S架构 开发语言…

链表的详细介绍

目录 链表的简单定义&#xff1a; 链表的分类 单项带头非循环 单向不带头循环链表 实现单向非循环无头链表 定义链表&#xff1a; 实现链表方法 打印链表 头插法&#xff1a; 尾插法&#xff1a; 指定插入&#xff1a; 通过对应值删除节点&#xff1a; 删除所有对应…

业财一体化是什么意思?有哪些好用的业财一体化软件?

你所在的企业是否为这些问题所困扰&#xff1f; 数据割裂&#xff1a;系统之间的数据不互通&#xff0c;财务数据与业务数据分离&#xff0c;数据统计口径不一致&#xff0c;缺乏关联性&#xff0c;管理统筹难度大。数据滞后&#xff1a;企业管理层获取数据信息的时效性低&…

绝缘电阻测试仪档位的选择技巧有哪些?这么一看就明白了!

电子绝缘电阻测试仪是电力检测领域的一款重要设备&#xff0c;他对于那些电力检测人员来说&#xff0c;是工作的设备之一&#xff0c;虽然它的使用频率相对较高&#xff0c;但是在使用绝缘电阻测试仪时&#xff0c;该如何选择合适的档位是一个关键问题。下面我们就来说说电子绝…

中国社科大与新加坡新跃社科联合培养博士—金融学和经济学差别

经济学和金融学是两个紧密联系的学科&#xff0c;但两者在研究问题上的侧重点有所不同。我在通过中国社科大与新加坡新跃社科联合培养博士项目课堂上&#xff0c;彻底分清了金融学和经济学差别。 经济学通常被归为社会科学&#xff0c;主要着眼于研究宏观上的生产、消费、以及…

谷歌大裁员,3 万员工面临被 AI 取代;网易、暴雪疑似「复合」!丨 RTE 开发者日报 Vol.113

开发者朋友们大家好&#xff1a; 这里是**「RTE 开发者日报」**&#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」 、「有态度的 观点 」、「有意思的 数据 」、「…

Redis缓存穿透、缓存击穿、缓存雪崩介绍

一、Redis的缓存穿透 1.什么是缓存穿透&#xff1f; 缓存穿透是指&#xff1a;客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这时缓存就永远不会生效&#xff0c;这些请求都打到数据库从而导致数据库压力过大。 2.出现缓存穿透的解决方案&#xff0c;以下是常用的两…

从AMI镜像恢复AWS Amazon Linux 2实例碰到的VNC服务以及Chrome浏览器无法启动的问题

文章目录 小结问题及解决VNC服务无法启动Chrome浏览器无法启动 参考 小结 将Amazon Linux 2保存为AMI (Amazon Machine Images)后&#xff0c;恢复成EC2 Instance (实例)后&#xff0c;VNC服务以及Chrome浏览器无法启动&#xff0c;进行了解决。 问题及解决 如果要将一个EC2…

Redis分布式缓存之主从哨兵分片集群

Redis主从 数据同步原理 Redis哨兵 Redis分片集群 集群伸缩&#xff1a;在集群中插入或删除某个节点 集群故障转移

HubSpot到底好不好用?

HubSpot被认为是一款强大的综合营销平台&#xff0c;然而&#xff0c;其是否适合你的业务取决于多种因素。以下是一些关于HubSpot的优点和考虑因素&#xff1a; HubSpot的优点&#xff1a; 一体化平台&#xff1a; HubSpot集成了营销、销售和服务功能&#xff0c;使得企业可以…

excel统计分析——CVM正态性检验

参考资料&#xff1a;统计推断——正态性检验&#xff08;图形方法、偏度和峰度、统计&#xff08;拟合优度&#xff09;检验&#xff09;_sm.distributions.ecdf-CSDN博客 29_张达成_从经验过程出发建立 Cramer-von Mises 统计量的性质 - 豆丁网 https://cran.r-project.org…

LeetCode 每日一题 Day 24(Hard) ||dp动态规划

1349. 参加考试的最大学生数 给你一个 m * n 的矩阵 seats 表示教室中的座位分布。如果座位是坏的&#xff08;不可用&#xff09;&#xff0c;就用 ‘#’ 表示&#xff1b;否则&#xff0c;用 ‘.’ 表示。 学生可以看到左侧、右侧、左上、右上这四个方向上紧邻他的学生的答…

解析d3dx9_43.dll文件,有效修复d3dx9_43.dll文件丢失

最近有小伙伴给小编反映说他的电脑老是出现d3dx9_43.dll文件丢失的问题&#xff0c;问为啥会这样&#xff1f;要怎么解决&#xff1f;那么今天小编就来给大家详细的解析这个d3dx9_43.dll文件吧&#xff0c;同时教大家如何去进行修复。 一. d3dx11_43.dll是什么文件有啥用 1.d3…

【数据库系统概论】第3章-关系数据库标准语言SQL(3)

文章目录 3.5 数据更新3.5.1 插入数据3.5.2 修改数据3.5.3 删除数据 3.6 空值的处理3.7 视图3.7.1 建立视图3.7.2 查询视图3.7.3 更新视图3.7.4 视图的作用 3.5 数据更新 3.5.1 插入数据 注意&#xff1a;插入数据时要满足表或者列的约束条件&#xff0c;否则插入失败&#x…