vue更换头像功能,支持编辑区域

简单的更换头像并不是什么难事,难的是更换头像的时候可编辑头像展示区域,如下图所示
vue更换头像功能,支持编辑区域_第1张图片
下面是简单的实现

<el-upload
     class="avatar-uploader"
     ref="fileUpload"
     action=""
     :show-file-list="false"
     :before-upload="beforeAvatarUpload"
     :http-request="fileUpload"
   >
     <el-avatar class="vertical-align-middle el-avatar-default img-size" :src="circleUrl"></el-avatar>
   </el-upload>
<dialog-cropper :cropper-show.sync="cropperShow" :cropperImg="cropperImg" @upload="fileUpload"></dialog-cropper>

<script>
import * as uploadApi from "@/api/uploader";
import dialogCropper from "@/components/dialogCropper";
export default() {
 components: {dialogCropper},
	data() {
		return {
			circleUrl: "",
			cropperShow: false,
			cropperImg: "",
		}
	},
	methods: {
		beforeAvatarUpload(file) {
	      this.cropperImg = URL.createObjectURL(file);
	      this.cropperShow = true;
	      return false;
	    },
	   //更换头像
	    fileUpload(res) {
	      let file = event.file;
	      let fileType = 1; // 图片1,音频2,视频3,文件4
	      uploadApi
	        .simpleUploader(res.data, res.type, 1)
	        .then((res) => {
	          this.circleUrl = res.url;
	        })
	        .catch((err) => {
	          this.$message.error("上传失败,请重新上传");
	        })
	        .finally(() => {
	          this.cropperShow = false;
	        });
	    }
	}
}
</script>

upload.js

import request from "@/utils/request";

const getAliOSSCreds = (params) => {
  return request({
    url: "admin/base/getOssToken",
    method: "get",
    params
  });
};
export const getUploadToken = ossType => {
  return getAliOSSCreds({
    type: ossType
  });
};

const generateUUID = () => {
  var d = new Date().getTime();
  if (window.performance && typeof window.performance.now === "function") {
    d += performance.now(); // use high-precision timer if available
  }
  var uuid = "xxxxxxxxxxxxxxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    var r = (d + Math.random() * 16) % 16 | 0;
    d = Math.floor(d / 16);
    return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
  });
  return uuid;
};

export const simpleUploader = (data, fileType, ossType) => {
  return new Promise((resolve, reject) => {
    getUploadToken(ossType)
      .then(res => {
        const oss = require("ali-oss");
        let client = new oss({
          region: res.region,
          secure: true,
          accessKeyId: res.accessKeyId,
          accessKeySecret: res.accessKeySecret,
          stsToken: res.securityToken,
          bucket: res.bucket,
          endpoint: res.endpoint
        });
        let key = res.dir + "/" + generateUUID() + "." + fileType;
        client
          .put(key, dataURLtoBlob(data))
          .then(res => {
            resolve(res);
          })
          .catch(res => {
            reject(res);
          });
      })
      .catch(res => {
        reject(res);
      });
  });
};

export const dataURLtoBlob = dataurl => {
  let arr = dataurl.split(",");
  //注意base64的最后面中括号和引号是不转译的
  let _arr = arr[1].substring(0, arr[1].length - 2);
  let mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(_arr),
    n = bstr.length,
    u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], {
    type: mime
  });
};

export default {
  simpleUploader
};

/components/dialogCropper 目录下的 dialogCropper.vue文件

<template>
  <el-dialog
    :visible="cropperShow"
    width="440px"
    :close-on-click-modal="false"
    :show-close="false"
    @open="onOpenDialogHandle"
  >
    <h3 slot="title">上传头像</h3>
    <div class="vue-cropper-layer">
      <vueCropper
        ref="cropper"
        class="cropper"
        autoCrop
        centerBox
        fixed
        :img="cropperImg"
        autoCropWidth="200px"
        autoCropHeight="200px"
        outputType="jpeg"
      ></vueCropper>
    </div>
    <div class="cropper-btn">
      <el-button type="primary" @click="confirm" :loading="loading">上传</el-button>
      <el-button @click="cancel" :disabled="loading">取消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import {VueCropper} from "vue-cropper";
export default {
  name: "dialogCropper",
  components: {
    VueCropper
  },
  props: {
    cropperShow: {
      default: true,
      type: Boolean
    },
    cropperImg: {}
  },
  data() {
    return {
      option: {
        size: 0,
        outputType: "",
        centerBox: false
      },
      loading: false
    };
  },
  methods: {
    confirm() {
      this.$refs.cropper.getCropData(data => {
        this.$emit("upload", {
          data,
          type: "jpg"
        });
        this.loading = true;
      });
    },
    // 取消
    cancel() {
      this.$emit("update:cropperShow", false);
    },
    onOpenDialogHandle() {
      this.loading = false;
    }
  }
};
</script>

<style scoped>
.vue-cropper-layer {
  width: 400px;
  height: 400px;
  margin: 0 0 15px;
}
.cropper-btn {
  text-align: center;
}
</style>

大功告成
vue更换头像功能,支持编辑区域_第2张图片

你可能感兴趣的:(Vue)