vue头像编辑实时裁剪预览功能(element+vueCropper)

最近做的项目,根据UI图实现头像修改功能,点击头像编辑,弹出头像修改框,需要裁剪及实时预览。

  • 话不多说,先来一波效果图:

选择图片前
在这里插入图片描述
选择图片后
在这里插入图片描述
实现代码:

<template>
  <el-dialog
    title="编辑头像"
    :visible.sync="dialogVisible"
    :show-close="false"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    width="600px"
  >
    <div style="display: flex" class="avatar">
      <div class="avatar-left">
        <div v-show="!options.img">
          <el-upload
            ref="upload"
            action=""
            style="text-align: center;margin-bottom: 24px"
            :on-change="uploads"
            accept="image/png, image/jpeg, image/jpg"
            :show-file-list="false"
            :auto-upload="false">
            <el-button slot="trigger" size="small" type="primary" ref="uploadBtn">选择图片</el-button>
          </el-upload>
          <div>支持jpg、png格式的图片,大小不超过3M</div>
        </div>
        <div v-show="options.img" class="avatar-left-crop">
          <vueCropper
            class="crop-box"
            ref="cropper"
            :img="options.img"
            :autoCrop="options.autoCrop"
            :fixedBox="options.fixedBox"
            :canMoveBox="options.canMoveBox"
            :autoCropWidth="options.autoCropWidth"
            :autoCropHeight="options.autoCropHeight"
            :centerBox="options.centerBox"
            @realTime="realTime">
          </vueCropper>
          <p class="avatar-left-p">
            鼠标滚轮缩放控制图片显示大小,鼠标拖拽调整显示位置</p>
        </div>
      </div>
      <div class="avatar-right">
        <div class="avatar-right-div" v-for="item in previewsDiv" :style="item.style">
          <div v-show="options.img" :class="previews.div" class="avatar-right-previews" :style="item.zoomStyle">
            <img :src="previews.url" :style="previews.img">
          </div>
        </div>
        <div class="avatar-right-text">
          <el-button v-if="options.img" type="text" @click="uploadPreviews">重新上传</el-button>
          <span v-else>预览</span>
        </div>
      </div>
    </div>
    <span slot="footer" class="dialog-footer">
    <el-button @click="closeDialog">取 消</el-button>
    <el-button type="primary" @click="getCrop">确 定</el-button>
  </span>
  </el-dialog>
</template>

<script>
  export default {
    name: "avatarEdit",
    props: {
      dialogVisible: {
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        //vueCropper组件 裁剪配置信息
        options: {
          img: '',  //原图文件
          autoCrop: true,  //默认生成截图框
          fixedBox: true,  //固定截图框大小
          canMoveBox: false,    //截图框不能拖动
          autoCropWidth: 200,  //截图框宽度
          autoCropHeight: 200, //截图框高度
          centerBox: true,    //截图框被限制在图片里面
        },
        //实时预览图数据
        previews: {},
        //实时预览图样式
        previewsDiv: [
          //108px 预览样式
          {
            style: {
              width: '108px',
              height: '108px',
              margin: '0 auto'
            },
            zoomStyle: {
              zoom: 0.54
            }
          },
          //68px 预览样式
          {
            style: {
              width: '68px',
              height: '68px',
              margin: '27px auto'
            },
            zoomStyle: {
              zoom: 0.34
            }
          },
          //48px 预览样式
          {
            style: {
              width: '48px',
              height: '48px',
              margin: '0 auto'
            },
            zoomStyle: {
              zoom: 0.24
            }
          }
        ],
      }
    },

    methods: {
      //读取原图
      uploads(file) {
        const isIMAGE = file.raw.type === 'image/jpeg' || file.raw.type === 'image/png';
        const isLt3M = file.raw.size / 1024 / 1024 < 3;
        if (!isIMAGE) {
          this.$message({
            showClose: true,
            message: '请选择 jpg、png 格式的图片!',
            type: 'error',  //提示类型
          });
          return false;
        }
        if (!isLt3M) {
          this.$message({
            showClose: true,
            message: '上传图片大小不能超过 3MB',
            type: 'error',  //提示类型
          });
          return false;
        }
        let reader = new FileReader();
        reader.readAsDataURL(file.raw);
        reader.onload = e => {
          this.options.img = e.target.result //base64
        }
      },
      //实时预览数据
      realTime(data) {
        this.previews = data
      },
      //重新上传
      uploadPreviews() {
        this.$refs.uploadBtn.$el.click()
      },
      //获取截图信息
      getCrop() {
        // 获取截图的 base64 数据
        this.$refs.cropper.getCropData((data) => {
          console.log(data)
        })
        // 获取截图的 blob 数据
        this.$refs.cropper.getCropBlob((data) => {
          console.log(data)
        })
      },
      //关闭弹框
      closeDialog() {
        //调用父组件关闭弹框方法 closeAvatarEdits()
        this.$parent.closeAvatarEdits()
        //重置 data 数据。(Object.assign是对象深复制  this.$data是组件内的数据对象 this.$options.data()是原始的数据)
        Object.assign(this.$data, this.$options.data())
      },
    }
  }
</script>

<style lang="scss" scoped>

  /deep/ .el-dialog__header {
    padding: 24px 0 11px 28px;
  }

  /deep/ .el-dialog__title {
    color: #333333;
  }

  /deep/ .el-dialog__body {
    padding: 0 28px;
  }

  /deep/ .el-dialog__footer {
    padding: 20px 28px;

    .el-button {
      width: 145px;
    }
  }

  .avatar {
    display: flex;

    .avatar-left {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 400px;
      height: 400px;
      background-color: #F0F2F5;
      margin-right: 10px;
      border-radius: 4px;

      .avatar-left-crop {
        width: 400px;
        height: 400px;
        position: relative;

        .crop-box {
          width: 100%;
          height: 100%;
          border-radius: 4px;
          overflow: hidden
        }

      }

      .avatar-left-p {
        text-align: center;
        width: 100%;
        position: absolute;
        bottom: 20px;
        color: #ffffff;
        font-size: 14px;
      }
    }

    .avatar-right {
      width: 150px;
      height: 400px;
      background-color: #F0F2F5;
      border-radius: 4px;
      padding: 16px 0;
      box-sizing: border-box;

      .avatar-right-div {
        border: 3px solid #ffffff;
        border-radius: 50%;
      }

      .avatar-right-previews {
        width: 200px;
        height: 200px;
        overflow: hidden;
        border-radius: 50%;
      }

      .avatar-right-text {
        text-align: center;
        margin-top: 50px;
        font-size: 14px;

        /deep/ .el-button {
          padding: 0;
        }

        span {
          color: #666666;
        }
      }
    }
  }

</style>

  • 图片裁剪插件 vueCropper
  • 图片上传element ----upload

文字说明不多,如有疑问,请私信哦~

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue.js 实现头像预览功能可以结合使用`vue-image-preview`组件和`vue-cropperjs`组件来实现。`vue-image-preview`用于预览头像,`vue-cropperjs`用于剪裁头像。 下面是一个基本的使用示例: 1. 安装`vue-image-preview`和`vue-cropperjs`组件: ``` npm install vue-image-preview vue-cropperjs --save ``` 2. 在Vue.js应用程序的入口文件中引入`vue-image-preview`和`vue-cropperjs`组件: ```javascript import Vue from 'vue' import VueImagePreview from 'vue-image-preview' import VueCropper from 'vue-cropperjs' import 'vue-image-preview/dist/vue-image-preview.css' import 'cropperjs/dist/cropper.css' Vue.use(VueImagePreview) Vue.component('VueCropper', VueCropper) ``` 3. 在需要预览和剪裁头像的组件中使用`vue-image-preview`和`vue-cropperjs`组件: ```vue <template> <div> <img :src="imageUrl" @click="showPreview"> <vue-cropper :img="imageUrl" ref="cropper" :guides="true"></vue-cropper> </div> </template> <script> import VueCropper from 'vue-cropperjs' export default { data() { return { imageUrl: 'https://example.com/avatar.jpg' } }, methods: { showPreview() { this.$preview.show({ images: [{ src: this.imageUrl }] }) }, cropAvatar() { const canvas = this.$refs.cropper.getCroppedCanvas() const croppedImage = canvas.toDataURL('image/jpeg') // 将剪裁后的头像上传到服务器 } }, components: { VueCropper } } </script> ``` 在这个示例中,我们在点击头像时调用了`showPreview()`方法,该方法使用了`vue-image-preview`组件的预览功能,并传入了需要预览头像路径。同时,我们还在组件中使用了`vue-cropperjs`组件,在预览头像时可以对头像进行剪裁操作,剪裁后的头像可以通过`toDataURL()`方法获取到。 需要注意的是,在使用`vue-cropperjs`组件时,需要在组件中添加`ref`属性,以便在剪裁头像时获取到组件的实例。同时,在剪裁头像后,可以将剪裁后的头像上传到服务器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值