<template>
<!-- 头像、用户名、性别编辑页面 -->
<el-dialog
v-dialogDrag
title="修改个人信息"
width="640px"
:visible.sync="visible"
:append-to-body="true"
:close-on-click-modal="false"
>
<div class="imgBox">
<div class="left">
<div class="text" v-show="!flag">
<label class="el-button long-button el-button--primary" for="uploads">
{{
$t('user.selectImg')
}}
</label>
<input
ref="imgInput"
type="file"
id="uploads"
:value="imgFile"
style="position: absolute; clip: rect(0 0 0 0)"
accept="image/png, image/jpeg, image/gif, image/jpg"
@change="uploadImg($event, 1)"
/>
<p>{{ $t('user.imgHint') }}</p>
</div>
<div v-show="flag">
<vueCropper
style="width: 400px; height: 400px"
ref="cropper"
:img="option.img"
:autoCrop="option.autoCrop"
:centerBox="option.centerBox"
:fixedNumber="option.fixedNumber"
:infoTrue="option.infoTrue"
:fixed="option.fixed"
@realTime="preview"
></vueCropper>
</div>
</div>
<div class="right">
<div>
<img v-show="imgUrl" :src="imgUrl" id="newPic1" />
</div>
<div>
<img v-show="imgUrl" :src="imgUrl" id="newPic2" />
</div>
<p v-show="!flag" style="color: #969696; margin-top: 127px">{{ $t('user.preview') }}</p>
<el-button
v-show="flag"
style="margin-top: 127px"
type="primary"
@click="reuploadImg"
>重新上传</el-button>
</div>
</div>
<div slot="footer" class="dialog-footer">
<div>
<span>{{ $t('global.userName') }}:</span>
<el-input
class="wd200"
maxlength="20"
show-word-limit
v-model="listParams.nickName"
autocomplete="off"
></el-input>
</div>
<div>
<el-button class="long-button" @click="visible = false">取消</el-button>
<el-button class="long-button" type="primary" :loading="btnLoading" @click="submit">
{{
$t('global.confirmBtn')
}}
</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
import { updateUserInfo, upload } from '@/api/userCenter/personalCenter'
export default {
name: 'info-edit',
props: {},
components: {},
data() {
return {
visible: false,
fileList: [],
// 是否选了图片,true:显示‘重新上传’,false:显示‘预览’
flag: false,
btnLoading: false,
// 选择图片
text: this.$t('user.u6'),
// 预览图片地址
imgUrl: '',
listParams: {
type: 2,
nickName: '', // 用户名
avatar: null // 头像url
},
option: {
img: '', //图片地址
fixed: true, //开启截图框宽高固定比例
fixedNumber: [1, 1], //截图框的宽高比例
autoCrop: true, //默认生成截图框
centerBox: true //截图框是否被限制在图片里面
},
fileName: '', //本机文件地址
imgFile: ''
}
},
mounted() {},
methods: {
// 重新选择头像图片
reuploadImg() {
this.$refs.imgInput.click()
},
// 预览
preview() {
// 获取Blob类型的图片数据
this.$refs.cropper.getCropBlob((data) => {
let img = window.URL.createObjectURL(data)
this.imgUrl = img
})
},
//选择本地图片
uploadImg(e, num) {
this.flag = true
//上传图片
let file = e.target.files[0]
this.fileName = file.name
if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
alert(this.$t('user.imgHint2'))
return false
}
let reader = new FileReader()
reader.onload = (e) => {
let data = null
if (typeof e.target.result === 'object') {
// 把Array Buffer转化为blob 如果是base64不需要
data = window.URL.createObjectURL(new Blob([e.target.result]))
} else {
data = e.target.result
}
if (num === 1) {
this.option.img = data
} else if (num === 2) {
this.example2.img = data
}
}
// 转化为base64
// reader.readAsDataURL(file)
// 转化为blob
reader.readAsArrayBuffer(file)
},
// --------------------------------
init(name, avatar) {
this.visible = true
this.listParams.nickName = name
this.option.img = ''
this.imgUrl = avatar
this.listParams.avatar = avatar
this.flag = false
this.btnLoading = false
},
submit() {
if (!/^[0-9a-zA-Z\u4e00-\u9fa5]{2,20}$/.test(this.listParams.nickName)) {
this.$message.error(this.$t('global.nameHint'))
return false
} else {
if (this.flag) {
this.getImgUrl()
return false
}
this.btnLoading = true
this.updateUserInfo()
}
},
updateUserInfo() {
updateUserInfo(this.listParams).then((res) => {
this.btnLoading = false
if (res) {
this.$message.success('修改成功')
// 更新用户名和头像
this.$store.dispatch('user/getInfo')
this.visible = false
this.$emit('refresh')
}
})
},
// 获取图片地址
getImgUrl() {
let formData = new FormData()
formData.append('category', 1)
// 获取Blob数据
this.$refs.cropper.getCropBlob((data) => {
formData.append('file', data, this.fileName)
upload(formData).then((res) => {
if (JSON.stringify(res) !== '{}') {
this.listParams.avatar = res
this.updateUserInfo()
}
})
})
}
}
}
</script>
<style lang="scss" scoped>
.imgBox {
width: 600px;
height: 400px;
display: flex;
background-color: #f6f9fe;
.left {
flex: 2;
> div {
width: 100%;
height: 100%;
}
.text {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 12px;
color: #969696;
}
}
.right {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
border-left: 1px solid #ffffff;
> div {
border-radius: 50%;
overflow: hidden;
border: 1px solid #ffffff;
background-color: #f0f0f0;
img {
width: 100%;
height: 100%;
}
}
> div:nth-child(1) {
width: 80px;
height: 80px;
margin-top: 60px;
}
> div:nth-child(2) {
width: 40px;
height: 40px;
margin-top: 40px;
}
}
}
.dialog-footer {
display: flex;
justify-content: space-between;
}
</style>
可以调整图片位置和大小裁剪自己想要的图片区域
右边预览的图片就是选择的头像区域
注:$t('’)
是使用了vue-i18n做了中英文翻译,所以不是直接写的汉字
参考文档链接:
1、Vue项目图片剪切上传—vue-cropper的使用
npm install vue-cropper --save-dev