element-ui框架下el-avatar头像图片裁剪

业务需求——头像图片裁剪后上传

简单的el-avatar头像框图片裁剪组件
上传成功

具体代码如下:

<el-form-item  label="宣传图片">
        <el-avatar :key="avatarPreview" :size="150" shape="square" :src="avatarPreview" @click.native="openDialog"/>
        <my-cropper ref="myCropper" @saveImgUrl="saveImgUrl"/>
</el-form-item>

<script>
	import MyCropper from '@/extra/MyCropper';
	import {baseURL} from "@/config/net.config";
	import {getToken} from "@/utils/token";
	export default {
		components: {
	      MyCropper
	    },
	    data() {
	    	return {
	    		avatarPreview: '',
	    		url: {
		          downloadFileURL: `${baseURL}/base/admin/testOrgan/download?X-Access-				Token=${getToken()}&id=`,
        			}
	    	}
	    }methods: {
	    	showEdit(row) {
	    		let {imgPath} = row;
	    		if (imgPath != null && String(imgPath).trim().length > 0) {
	    			//请求后台获取图片流文件
	    			this.avatarPreview = `${this.url.downloadFileURL}${row.id}`;
	    		}
	    	}//裁剪完成后回调方法
	    	saveImgUrl(data) {
		        this.avatarPreview = data;
		        this.form.avatar = data;
	      	},
	      	//弹出裁剪对话框
	      	openDialog() {
		       this.$refs['myCropper'].initShow(this.avatarPreview);
	      	},
	    }
	}
</script>
net.config.js文件(后台获取图片流)
/**
 * @description 导出网络配置
 **/
module.exports = {
  // 默认的接口地址,开发环境和生产环境都会走/vab-mock-server
  // 正式项目可以选择自己配置成需要的接口地址,如"https://api.xxx.com"
  // 问号后边代表开发环境,冒号后边代表生产环境
  baseURL:
    process.env.NODE_ENV === 'development'
      ? '/manage-boot'
      : '这里正式地址域名',
  // 配后端数据的接收方式application/json;charset=UTF-8 或 application/x-www-form-urlencoded;charset=UTF-8
  contentType: 'application/json;charset=UTF-8',
  // 最长请求时间
  requestTimeout: 90000,
  // 操作正常code,支持String、Array、int多种类型
  successCode: [200, 0, '200', '0',true],
  // 数据状态的字段名称
  statusName: 'code',
  // 状态信息的字段名称
  messageName: 'message',
}

我使用的是"vue-cropper": "^0.4.8"版本的裁剪组件,需要在main.js全局注册一下
npm install vue-cropper@0.4.8 --save
import VueCropper from 'vue-cropper';
Vue.use(VueCropper)
MyCropper组件
<template>
  <el-dialog
    :close-on-click-modal="false"
    title="宣传图片"
    :visible.sync="dialogVisible"
    :modal="false"
    :destroy-on-close="true"
    width="800px"
  >
    <el-row>
      <el-col :xs="24" :md="12" :style="{height: '350px'}">
        <vue-cropper
          ref="cropper"
          :img="options.img"
          :info="true"
          :autoCrop="options.autoCrop"
          :fixedBox="options.fixedBox"
          :canMoveBox="options.canMoveBox"
          :autoCropWidth="options.autoCropWidth"
          :autoCropHeight="options.autoCropHeight"
          :centerBox="options.centerBox"
          :fixed="options.fixed"
          :fixedNumber="options.fixedNumber"
          :outputType="options.outputType"
          :full="options.full"
          @realTime="realTime"
        >
        </vue-cropper>
      </el-col>
      <el-col :xs="24" :md="12" :style="{height: '350px'}">
        <div class="avatar-upload-preview">
          <img :src="previews.url" :style="previews.img"/>
        </div>
        <div style="text-align: center;margin-top: 310px;">
          <el-upload
            accept="image/jpeg,image/gif,image/png"
            action="#"
            :show-file-list="false"
            :auto-upload="false"
            :on-change="onChange"
          >
            <template #default>
              <el-button type="primary" icon="el-icon-folder-add">选择图片</el-button>
            </template>
          </el-upload>
        </div>
      </el-col>
    </el-row>
    <template #footer>
      <div>
        <el-button type="primary" @click="upload">上传并保存</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script>


  export default {
    name: 'MyCropper',
    data() {
      return {
        dialogVisible: false,
        options: {
          img: '', // 原图文件
          autoCrop: true, // 默认生成截图框
          fixedBox: false, // 固定截图框大小
          canMoveBox: true, // 截图框可以拖动
          autoCropWidth: 260, // 截图框宽度
          autoCropHeight: 260, // 截图框高度
          fixed: true, // 截图框宽高固定比例
          fixedNumber: [1, 1], // 截图框的宽高比例
          centerBox: false, // 截图框被限制在图片里面
          full: true,
          outputType: 'png'
        },
        previews: {},
      }
    },
    methods: {
      initShow(img) {
        this.dialogVisible = true;
        this.options.img = img;
      },
      realTime(data) {
        this.previews = data
      },
      onChange(file) {
        const that = this;
        this.$refs['cropper'].clearCrop();
        let reader = new FileReader();
        reader.readAsDataURL(file.raw);
        reader.onload = e => {
          that.options.img = e.target.result; // base64
        }
      },
      upload() {
        const that = this
        that.$refs['cropper'].getCropData((data) => {
          that.$emit('saveImgUrl',data);
          that.previews = {};
          that.dialogVisible = false;
        })
      },
    },
  }
</script>

<style lang="scss" scoped>
  .avatar-upload-preview {
    position: absolute;
    //margin-left: 9px;
    top: 45%;
    transform: translate(25%, -50%);
    width: 260px;
    height: 260px;
    //box-shadow: 0 0 4px #ccc;
    overflow: hidden;

    img {
      width: 100%;
      height: 100%;
    }
  }
</style>

开发过程中一些问题总结

https://gitcode.net/mirrors/xyxiao001/vue-cropper 这是vue-cropper插件的详细API,可以看到具体参数具体用法

一个小注意点:如果el-avatar的src从后台获取图片流失败,头像框也就无法显示回显图片,但是使用上传图片裁剪功能后,saveImgUrl(data) { this.avatarPreview = data; this.form.avatar = data; },src资源更新,但是图片仍然不显示。 解决方法是在<el-avatar :key="avatarPreview">标签中加入key就可以了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 element-ui 中上传头像,您可以使用 el-upload 组件。以下是一个简单的示例代码: ```html <template> <div> <el-upload class="avatar-uploader" action="/your-upload-api" :show-file-list="false" :on-success="handleSuccess" :before-upload="beforeAvatarUpload"> <img v-if="imageUrl" :src="imageUrl" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </div> </template> <script> export default { data() { return { imageUrl: '' // 存储上传后的头像地址 }; }, methods: { handleSuccess(response) { // 上传成功后,将服务器返回的头像地址存储在 imageUrl 中 this.imageUrl = response.data.url; }, beforeAvatarUpload(file) { // 限制上传图片的类型和大小 const isJPG = file.type === 'image/jpeg'; const isPNG = file.type === 'image/png'; const isLt2M = file.size / 1024 / 1024 < 2; if (!isJPG && !isPNG) { this.$message.error('上传头像图片只能是 JPG 或 PNG 格式!'); return false; } if (!isLt2M) { this.$message.error('上传头像图片大小不能超过 2MB!'); return false; } return true; } } }; </script> <style> .avatar-uploader { display: inline-block; width: 100px; height: 100px; border-radius: 50%; border: 1px dashed #d9d9d9; background-color: #f2f2f2; overflow: hidden; text-align: center; } .avatar { width: 100%; height: 100%; object-fit: cover; } .avatar-uploader-icon { font-size: 32px; color: #8c939d; line-height: 100px; } </style> ``` 在这个示例中,el-upload 组件的 action 属性指向上传头像的 API 接口。在 handleSuccess 方法中,将服务器返回的头像地址存储在 imageUrl 中,然后在模板中使用 v-if 和 v-else 来展示上传的头像或加号图标。beforeAvatarUpload 方法用于限制上传图片的类型和大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值