You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
4.1 KiB

6 years ago
<template>
<dialog-form :loading="loading" title="上传头像" :value="value" width="50%" @close="cancel">
<el-row class="avatar-cropper">
<div class="img-wrapper">
<vue-cropper
ref="cropper"
:img="img"
:info="false"
autoCrop
autoCropHeight="200px"
autoCropWidth="200px"
fixedBox
full
outputType="png"
@wheel.native.prevent="scale"
/>
</div>
<input
ref="input"
accept="image/png, image/jpeg, image/gif, image/jpg"
style="display: none"
type="file"
@change="chooseImage"
>
</el-row>
<template v-slot:footer>
<el-button plain size="small" @click="$refs.input.click()">选择图片</el-button>
<el-button plain size="small" @click="closeDialog"> </el-button>
<el-button size="small" type="primary" @click="confirm"> </el-button>
</template>
</dialog-form>
6 years ago
</template>
<script>
import {VueCropper} from 'vue-cropper'
import DialogForm from '@/components/DialogForm'
import dialogMixin from "@/mixins/dialogMixin"
6 years ago
import {elError, elSuccess} from "@/utils/message"
import {autoCompleteUrl, upload} from "@/utils/file"
6 years ago
import {updateAvatar} from "@/api/account"
6 years ago
export default {
name: "Avatar",
mixins: [dialogMixin],
components: {VueCropper, DialogForm},
props: {
value: Boolean
},
6 years ago
data() {
return {
loading: false,
img: '',
name: ''
}
},
6 years ago
methods: {
chooseImage(e) {
if (this.loading) return
this.clear()
let file = e.target.files[0]
if (!file.type.includes('image')) {
return elError('请上传图片')
}
if (file.size > 1048576) {
return elError('上传的图片不能大于1M')
}
this.name = file.name
let reader = new FileReader()
reader.onload = e => {
this.img = window.URL.createObjectURL(new Blob([e.target.result]))
}
reader.readAsArrayBuffer(file)
},
confirm() {
6 years ago
if (!this.img) return elError('请先上传图片')
if (this.loading) return
this.loading = true
this.$refs.cropper.getCropBlob(data => {
upload(new Blob([data]), this.name)
.then(({key}) => updateAvatar(key))
.then(({key, msg}) => {
this.$store.commit('user/avatar', autoCompleteUrl(key))
6 years ago
this.$store.dispatch('user/refresh')
elSuccess(msg)
})
.finally(() => this.cancel())
6 years ago
})
},
clear() {
this.loading = false
this.$refs.cropper.clearCrop()
if (this.img) window.URL.revokeObjectURL(this.img)
this.img = ''
this.name = ''
},
scale(e) {
const eventDelta = e.wheelDelta || -(e.detail || 0) * 40
this.$refs.cropper.changeScale(eventDelta / 120)
},
cancel() {
this.closeDialog()
this.clear()
6 years ago
}
}
}
</script>
<style lang="scss">
.avatar-cropper {
.cropper-crop-box {
border: 1px solid #39f;
border-radius: 50%;
overflow: hidden;
}
6 years ago
.img-wrapper {
height: 500px;
width: 100%;
6 years ago
display: inline-block;
border: 1px solid #ebebeb;
}
}
</style>