NoteZ_技术博客 NoteZ_技术博客
🏠 首页
  • 📚 Web技术
  • 📋 Npm笔记
  • 📑 Markdown
  • 📄 Git笔记
  • 📝 Nginx文档
  • 📓 Linux文档
  • 📖 技术文档
  • 📜 其他文档
  • 🧊 NodeJs
  • 🎡 Express
  • 🔥 Rust
  • 🎉 Koa2
  • 🍃 MongoDB
  • 🐬 MySql
  • 🥦 Oracle
  • 🍁 Python
  • 🍄 JavaScript
  • 🌰 CSS
  • 🧄 HTML
  • 🥑 Canvas
  • 🌽 Nuxt
  • 🍆 React
  • 🥜 Vue
  • 🧅 TypeScript
  • 🌶️ AI
  • 📘 分类
  • 📗 标签
  • 📙 归档
⚜️ 在线编辑 (opens new window)
  • 📁 站点收藏
  • 📦 前端组件库
  • 📊 数据可视化
  • 🌈 开源插件
  • 🎗️ 关于我
  • 🔗 友情链接
GitHub (opens new window)

NoteZ_技术博客

前端界的小学生
🏠 首页
  • 📚 Web技术
  • 📋 Npm笔记
  • 📑 Markdown
  • 📄 Git笔记
  • 📝 Nginx文档
  • 📓 Linux文档
  • 📖 技术文档
  • 📜 其他文档
  • 🧊 NodeJs
  • 🎡 Express
  • 🔥 Rust
  • 🎉 Koa2
  • 🍃 MongoDB
  • 🐬 MySql
  • 🥦 Oracle
  • 🍁 Python
  • 🍄 JavaScript
  • 🌰 CSS
  • 🧄 HTML
  • 🥑 Canvas
  • 🌽 Nuxt
  • 🍆 React
  • 🥜 Vue
  • 🧅 TypeScript
  • 🌶️ AI
  • 📘 分类
  • 📗 标签
  • 📙 归档
⚜️ 在线编辑 (opens new window)
  • 📁 站点收藏
  • 📦 前端组件库
  • 📊 数据可视化
  • 🌈 开源插件
  • 🎗️ 关于我
  • 🔗 友情链接
GitHub (opens new window)
  • JavaScript笔记

  • CSS笔记

  • HTML笔记

  • Canvas笔记

  • Nuxt笔记

  • React笔记

  • Vue笔记

    • markdown(md-editor-v3)简单使用
    • Prop 验证 与 非 Prop 的 Attribute
    • transition-group列表过渡
    • transition过渡&动画
    • vetur 中 eslint 的问题
    • vite 打包时内存溢出处理方案
    • Vite2 + Vue3添加svg的使用并通过svg实现自定义Icon组件
    • Vite项目构建优化之移除console.log和其他生产日志
    • vsCode 之 Monaco Editor 在 vue-cli3.0 中的使用方法
    • vue cli3 中的使用Luckysheet和Luckyexcel
    • vue 与 Koa 上传示例代码
    • vue 中 axios 如何取消请求,取消前面一个或多个请求
    • Vue 中 node-sass 安装失败简单解决方案
    • vue 中使用 pinia 状态管理教程
    • vue 中使用 web worker
    • vue 中封装 Axios 和 管理 API 接口
    • vue 中的 hash 与 history 两种路由模式
    • Vue 中的鼠标事件汇总
    • Vue 实现 Base64 图片上传
    • vue 强制刷新组件
    • Vue 组件中 v-mode 的本质以及实现方式
    • vue 组件中的.native 原生事件(@click.native)
    • Vue 组件中的.native原生事件(@click.native)
    • Vue 页面路由(router)权限控制和登陆验证
    • Vue 项目中如何在打包时清除 console 和 debugger
    • Vue 项目打包去除 .map 文件方法
    • Vue 预渲染之 prerender-spa-plugin 的配置使用
    • vue-cli 2.x和3.x配置移动端适配px自动转为rem
    • vue-cli3 如何实现pc端自适应
    • vue-cli3.0 开启 Gzip 压缩方法
    • Vue-cli3.0 监听路由变化的几种方式
    • Vue-cli3.0 结合 axios 解决生产环境中的跨域问题
    • vue-cli3.0移动端项目将px转换成rem
    • vue-cli3.x项目兼容ie解决方案
    • vue-router传递参数的几种方式
    • Vue2-ace-editor 基本使用方法
    • vue2.x 插槽slot使用总结
    • Vue2.x 组件通信方式
    • vue3 + vite 自适应(rem 适配)方法
    • vue3+vite:本地代理,配置proxy
    • Vue3.0 基础知识点总结
    • Vue3.0 挂载方法,添加全局属性
    • vue3.0之全局变量app.config.globalProperties的使用
    • vue3.2+elelmenui-plus+vite 按需导入ui组件库
    • vue3.x 中使用 ol (openlayer)地图
    • Vue3.x 组件通信方式
    • Vue3全局变量的定义和使用
    • Vuex使用记录
    • vue中使用html2canvas将html页面转为图片并且下载该图片
    • vue中父子组件之间的通信
    • Vue中的防抖函数封装和使用
    • Vue中配合clipboard.js实现点击按钮复制内容到剪切板
    • vue使用monaco editor时报错 Unexpected usage at EditorSimpleWorker.loadForeignModule
    • Vue列表渲染之数组、对象更新检测
    • Vue实现下拉滚动加载刷新功能
    • Vue开发中安装库经常报错
    • Vue技术框架
    • Vue生命周期
    • Vue监听store中数据变化的两种方式
    • Vue非父子组件之间通信的几种方式
    • Vue项目 解决 vuex 在页面刷新后数据丢失的问题
    • vue项目nginx部署子目录_vue 多项目部署_二级目录 copy
    • 使用 monaco-editor 汉化 右键菜单汉化
    • 使用 vite 脚手架创建 vue3 项目
    • 使用animate库
    • 使用vue实现鼠标框选文件的功能
    • 使用vue的transition标签结合css样式完成动画
    • 关于Vue项目优化方案总结
    • 关于解决vue-cli2.xx、vue-cli3.xx项目在ie中白屏的方案总结
    • 利用create-nuxt-app脚手架创建NuxtJS应用
    • 国际化插件 vue-i18n 使用方法
    • 在 vite-vue3.x 中的使用 vscode monaco-editor 方法
    • 在 Vue 中 如何使用 jsencrypt 实现 Rsa 进行加密
    • 在 vue 中使用 jsPlumb 总结
    • 在 vue 中使用 v-viewer 预览图方法
    • 在 Vue 中读取本地文本文件(兼容各种浏览器)
    • 在 vue 或 vuex 中如何使用 axios 进行请求操作
    • 在 vue 项目中 mock 的基本使用方法
    • 在 vue-cli3 项目更改 favicon 图标
    • 在 vue-cli3.0 中使用 Sass 全局变量
    • 在vue3+vite中使用markdown(v-md-editor)编辑器
    • 在vue中如何使用watch深度监听对象中值的变化
    • 基于 vue 列表拖拽排序
    • 基于 vue 图片裁剪(vue-cropper)
      • 安装
      • 使用
      • 示例代码
      • 示例图片
    • 基于 vue 的 CodeMirror 代码编辑器
    • 如何在 vue 中使用 swiper 插件创建轮播图
    • 如何在 vue 中实现代码高亮?
    • 如何在 Vue-cli3.0 中使用 prerender-spa-plugin 进行预渲染
    • 如何用 vue 实现一个虚拟列表
    • 清除项目中无用的console.log代码方法
    • 解决vue-cli3.0中提示syntax 'classProperties' isn't currently enabled的错误
    • 记录vite打包vue项目内存溢出问题及解决方法
    • Vite中使用 svg-sprite-loader加载svg文件
    • vite引入svg图片
    • vue 使用CompressionPlugin压缩解决打包后文件过大的问题
    • vue2.x递归组件 树形组件
    • vue3.x递归组件 树形组件
    • 使用Vite快速构建Vue3+ts+pinia脚手架
    • 启动vue项目时报错digital envelope routines__unsupported
    • Pinia 快速入门(使用教程)
    • 关于 Vite Vue 辨别当前所处于什么(生产、开发)环境
  • TypeScript笔记

  • AI相关笔记

  • 开发文档
  • Vue笔记
NoteZ
2020-07-13
目录

基于 vue 图片裁剪(vue-cropper)

# 安装

npm install vue-cropper --save
1

# 使用

main.js里面

import VueCropper from 'vue-cropper'
Vue.use(VueCropper)
1
2

或者组件里

<script>
  import { VueCropper } from "vue-cropper";
  export default {
    name: "CropperImage",
    components: {
      VueCropper,
    }
  };
</script>
1
2
3
4
5
6
7
8
9

# 示例代码

<template>
  <Modal
    v-model="isOpen"
    class-name="cropper-image-modal"
    @on-visible-change="handleVisibleChange"
    width="50%"
  >
    <div slot="header" class="header">
      <h2>
        <span><Icon type="md-cut" size="12"/></span> <span>图片裁剪</span>
      </h2>
    </div>
    <div class="cropper-content">
      <div class="cropper-box">
        <div class="cropper">
          <vue-cropper
            ref="cropper"
            :img="option.img"
            :outputSize="option.outputSize"
            :outputType="option.outputType"
            :info="option.info"
            :canScale="option.canScale"
            :autoCrop="option.autoCrop"
            :autoCropWidth="option.autoCropWidth"
            :autoCropHeight="option.autoCropHeight"
            :fixed="option.fixed"
            :fixedNumber="option.fixedNumber"
            :full="option.full"
            :fixedBox="option.fixedBox"
            :canMove="option.canMove"
            :canMoveBox="option.canMoveBox"
            :original="option.original"
            :centerBox="option.centerBox"
            :height="option.height"
            :infoTrue="option.infoTrue"
            :maxImgSize="option.maxImgSize"
            :enlarge="option.enlarge"
            :mode="option.mode"
            @realTime="realTime"
            @imgLoad="imgLoad"
          >
          </vue-cropper>
        </div>
        <!--底部操作工具按钮-->
        <div class="footer-btn">
          <div class="scope-btn">
            <label class="btn" for="uploads">选择封面</label>
            <input
              type="file"
              id="uploads"
              style="position: absolute; clip: rect(0 0 0 0)"
              accept="image/png, image/jpeg, image/gif, image/jpg"
              @change="selectImg($event)"
            />
            <Button @click="changeScale(1)">放大</Button>
            <Button @click="changeScale(-1)">缩小</Button>
            <Button @click="rotateLeft">↺ 左旋转</Button>
            <Button @click="rotateRight">↻ 右旋转</Button>
          </div>
          <div class="upload-btn">
            <Button type="success" @click="uploadImg('blob')"
              >上传封面 <i class="el-icon-upload"></i
            ></Button>
          </div>
        </div>
      </div>
      <!--预览效果图-->
      <div class="show-preview">
        <div :style="previews.div" class="preview">
          <img :src="previews.url" :style="previews.img" />
        </div>
      </div>
    </div>
  </Modal>
</template>
<script>
import { VueCropper } from "vue-cropper";
export default {
  name: "CropperImage",
  components: {
    VueCropper,
  },
  //   props: ["Name"],
  data() {
    return {
      isOpen: true,
      name: "",
      previews: {},
      option: {
        img: "", //裁剪图片的地址
        outputSize: 1, //裁剪生成图片的质量(可选0.1 - 1)
        outputType: "jpeg", //裁剪生成图片的格式(jpeg || png || webp)
        info: true, //图片大小信息
        canScale: true, //图片是否允许滚轮缩放
        autoCrop: true, //是否默认生成截图框
        autoCropWidth: 230, //默认生成截图框宽度
        autoCropHeight: 150, //默认生成截图框高度
        fixed: true, //是否开启截图框宽高固定比例
        fixedNumber: [1.53, 1], //截图框的宽高比例
        full: false, //false按原比例裁切图片,不失真
        fixedBox: false, //固定截图框大小,不允许改变
        canMove: false, //上传图片是否可以移动
        canMoveBox: true, //截图框能否拖动
        original: false, //上传图片按照原始比例渲染
        centerBox: false, //截图框是否被限制在图片里面
        height: true, //是否按照设备的dpr 输出等比例图片
        infoTrue: false, //true为展示真实输出图片宽高,false展示看到的截图框宽高
        maxImgSize: 3000, //限制图片最大宽度和高度
        enlarge: 1, //图片根据截图框输出比例倍数
        mode: "230px 150px", //图片默认渲染方式
      },
    };
  },
  methods: {
    handleVisibleChange(value) {
      if (!value) {
        clearTimeout(this.time);
        this.time = setTimeout(() => {
          this.$parent.isAccountSet = false;
        }, 500);
      }
    },
    //初始化函数
    imgLoad(msg) {
      console.log("工具初始化函数=====" + msg);
    },
    //图片缩放
    changeScale(num) {
      num = num || 1;
      this.$refs.cropper.changeScale(num);
    },
    //向左旋转
    rotateLeft() {
      this.$refs.cropper.rotateLeft();
    },
    //向右旋转
    rotateRight() {
      this.$refs.cropper.rotateRight();
    },
    //实时预览函数
    realTime(data) {
      this.previews = data;
    },
    //选择图片
    selectImg(e) {
      let file = e.target.files[0];
      if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
        this.$message({
          message: "图片类型要求:jpeg、jpg、png",
          type: "error",
        });
        return false;
      }
      //转化为blob
      let reader = new FileReader();
      reader.onload = (e) => {
        let data;
        if (typeof e.target.result === "object") {
          data = window.URL.createObjectURL(new Blob([e.target.result]));
        } else {
          data = e.target.result;
        }
        this.option.img = data;
      };
      //转化为base64
      reader.readAsDataURL(file);
    },
    //上传图片
    uploadImg(type) {
      let _this = this;
      if (type === "blob") {
        //获取截图的blob数据
        this.$refs.cropper.getCropBlob(async (data) => {
          let formData = new FormData();
          formData.append("file", data, "DX.jpg");
          //调用axios上传
          let { data: res } = await _this.$http.post("/api/file/imgUpload", formData);
          if (res.code === 200) {
            _this.$message({
              message: res.msg,
              type: "success",
            });
            let data = res.data.replace("[", "").replace("]", "").split(",");
            let imgInfo = {
              name: _this.Name,
              url: data[0],
            };
            _this.$emit("uploadImgSuccess", imgInfo);
          } else {
            _this.$message({
              message: "文件服务异常,请联系管理员!",
              type: "error",
            });
          }
        });
      }
    },
  },
};
</script>
<style lang="scss">
.cropper-image-modal {
  .cropper-content {
    display: flex;
    display: -webkit-flex;
    justify-content: flex-end;
    .cropper-box {
      flex: 1;
      width: 100%;
      .cropper {
        width: auto;
        height: 300px;
      }
    }
    .show-preview {
      flex: 1;
      -webkit-flex: 1;
      display: flex;
      display: -webkit-flex;
      justify-content: center;
      .preview {
        overflow: hidden;
        border: 1px solid #67c23a;
        background: #cccccc;
      }
    }
  }
  .footer-btn {
    margin-top: 30px;
    display: flex;
    display: -webkit-flex;
    justify-content: flex-end;
    .scope-btn {
      display: flex;
      display: -webkit-flex;
      justify-content: space-between;
      padding-right: 10px;
    }
    .upload-btn {
      flex: 1;
      -webkit-flex: 1;
      display: flex;
      display: -webkit-flex;
      justify-content: center;
    }
    .btn {
      outline: none;
      display: inline-block;
      line-height: 1;
      white-space: nowrap;
      cursor: pointer;
      -webkit-appearance: none;
      text-align: center;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
      outline: 0;
      -webkit-transition: 0.1s;
      transition: 0.1s;
      font-weight: 500;
      padding: 8px 15px;
      font-size: 12px;
      border-radius: 3px;
      color: #fff;
      background-color: #409eff;
      border-color: #409eff;
      margin-right: 10px;
    }
  }
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

# 示例图片

1636878201298-20211114162255.png

#Vue
上次更新: 2024/01/30, 00:35:17
基于 vue 列表拖拽排序
基于 vue 的 CodeMirror 代码编辑器

← 基于 vue 列表拖拽排序 基于 vue 的 CodeMirror 代码编辑器→

最近更新
01
Gitea数据备份与还原
03-10
02
Linux 中使用 rsync 同步文件目录教程
03-10
03
Linux 使用 rsync 互相传输同步文件的简单步骤
03-08
更多文章>
Theme by Vdoing | Copyright © 2019-2025 NoteZ,All rights reserved | 冀ICP备2021027292号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式