当前位置:首页 > VUE

vue实现图片裁切

2026-02-18 18:11:12VUE

Vue 实现图片裁切的方法

使用第三方库 vue-cropperjs

安装 vue-cropperjs 库:

npm install vue-cropperjs --save

引入并使用组件:

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

export default {
  components: {
    VueCropper
  },
  data() {
    return {
      imgSrc: '',
      cropperOptions: {
        aspectRatio: 1,
        viewMode: 1,
        autoCropArea: 0.8
      }
    };
  },
  methods: {
    handleFileChange(e) {
      const file = e.target.files[0];
      if (!file.type.includes('image/')) {
        alert('请选择图片文件');
        return;
      }
      const reader = new FileReader();
      reader.onload = (event) => {
        this.imgSrc = event.target.result;
      };
      reader.readAsDataURL(file);
    },
    getCroppedImage() {
      this.$refs.cropper.getCroppedCanvas().toBlob((blob) => {
        // 处理裁切后的图片
      });
    }
  }
};

模板部分:

<template>
  <div>
    <input type="file" accept="image/*" @change="handleFileChange">
    <vue-cropper
      ref="cropper"
      :src="imgSrc"
      :options="cropperOptions"
    />
    <button @click="getCroppedImage">裁切图片</button>
  </div>
</template>

使用原生 Canvas API 实现

创建图片裁切组件:

export default {
  data() {
    return {
      image: null,
      canvas: null,
      ctx: null,
      startX: 0,
      startY: 0,
      isDragging: false
    };
  },
  mounted() {
    this.canvas = this.$refs.canvas;
    this.ctx = this.canvas.getContext('2d');
  },
  methods: {
    handleImageUpload(e) {
      const file = e.target.files[0];
      const reader = new FileReader();
      reader.onload = (event) => {
        this.image = new Image();
        this.image.onload = () => {
          this.canvas.width = this.image.width;
          this.canvas.height = this.image.height;
          this.ctx.drawImage(this.image, 0, 0);
        };
        this.image.src = event.target.result;
      };
      reader.readAsDataURL(file);
    },
    startCrop(e) {
      this.startX = e.offsetX;
      this.startY = e.offsetY;
      this.isDragging = true;
    },
    cropImage(e) {
      if (!this.isDragging) return;
      const width = e.offsetX - this.startX;
      const height = e.offsetY - this.startY;

      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      this.ctx.drawImage(this.image, 0, 0);
      this.ctx.strokeStyle = 'red';
      this.ctx.strokeRect(this.startX, this.startY, width, height);
    },
    endCrop() {
      this.isDragging = false;
      // 获取裁切区域数据
    }
  }
};

模板部分:

<template>
  <div>
    <input type="file" @change="handleImageUpload">
    <canvas
      ref="canvas"
      @mousedown="startCrop"
      @mousemove="cropImage"
      @mouseup="endCrop"
    ></canvas>
  </div>
</template>

使用 Element UI 的 Upload 组件结合裁切功能

安装 Element UI:

npm install element-ui -S

实现代码:

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

export default {
  data() {
    return {
      dialogVisible: false,
      cropImg: '',
      cropper: null
    };
  },
  methods: {
    handlePreview(file) {
      this.dialogVisible = true;
      this.$nextTick(() => {
        this.cropImg = URL.createObjectURL(file.raw);
        this.initCropper();
      });
    },
    initCropper() {
      const image = this.$refs.cropImage;
      this.cropper = new Cropper(image, {
        aspectRatio: 1,
        viewMode: 1
      });
    },
    confirmCrop() {
      this.cropper.getCroppedCanvas().toBlob((blob) => {
        // 处理裁切后的图片
        this.dialogVisible = false;
      });
    }
  }
};

模板部分:

vue实现图片裁切

<template>
  <div>
    <el-upload
      action="#"
      :on-change="handlePreview"
      :auto-upload="false"
    >
      <el-button type="primary">上传图片</el-button>
    </el-upload>

    <el-dialog :visible.sync="dialogVisible">
      <img ref="cropImage" :src="cropImg" style="max-width: 100%">
      <span slot="footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmCrop">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

注意事项

  • 移动端适配需要考虑触摸事件替代鼠标事件
  • 裁切比例可以通过设置 aspectRatio 参数控制
  • 大图片处理需要考虑性能优化,可以限制最大尺寸
  • 裁切结果可以导出为多种格式:Blob、Base64 或 FormData

标签: 图片vue
分享给朋友:

相关文章

vue 实现长列表

vue 实现长列表

Vue 实现长列表的优化方案 虚拟滚动技术 虚拟滚动是处理长列表的高效方式,仅渲染可视区域内的元素。通过计算滚动位置动态加载和卸载DOM节点,大幅减少内存占用和渲染压力。 <template&…

vue实现hover

vue实现hover

Vue 实现 hover 效果的方法 在 Vue 中实现 hover 效果可以通过多种方式实现,包括使用 CSS、Vue 指令或事件监听。以下是几种常见的方法: 使用 CSS :hover 伪类 通…

vue实现机制

vue实现机制

Vue 实现机制的核心原理 Vue.js 的核心实现机制主要基于响应式系统、虚拟 DOM 和组件化设计。以下是关键实现细节: 响应式系统 Vue 通过 Object.defineProperty(V…

vue  实现分页

vue 实现分页

实现分页的基本思路 在Vue中实现分页通常需要结合后端API返回的数据和前端的分页组件。分页的核心逻辑包括计算总页数、处理当前页码变化以及触发数据请求。 分页组件示例 使用Element UI的分页…

实现vue vm

实现vue vm

Vue VM 实现方法 Vue VM(ViewModel)是 Vue.js 的核心概念之一,负责连接视图(View)和数据模型(Model)。以下是实现 Vue VM 的几种方法: 使用 Vue 实…

vue原生实现

vue原生实现

Vue 原生实现方法 在 Vue 中实现原生功能通常指直接使用 Vue 的核心特性(如指令、响应式数据、组件等)而非依赖第三方库。以下是几种常见场景的原生实现方式: 数据绑定与响应式更新 Vue 的…