@vue项目中实现头像上传的功能型组件

功能需求

实现个人中心的头像上传功能:

1、用户未上传过头像,展示设定好的默认头像(区分男女)

2、支持格式png、jpg、jpeg

3、图片大小:小于等于2M

4、个人中心头像上传成功需要实现与项目导航栏头像的联动效果

5、不符合规则加入对应的吐司提示

需求分析

1、因为有展示默认头像的需求,所以需要判断用户是否上传过头像,由接口获取用户个人信息并将头像信息保存在vuex,在前端页面通过计算属性映射vuex里的头像数据加以判断。

2、在选择文件的回调函数中做格式,大小的判断。根据具体情况做吐司提示效果(本文的吐司属于自开发吐司组件,element ui等皆有提供类似功能,根据具体业务需求开发)

3、因为我们的头像数据存放在vuex中,所以我们只需要在上传成功的时候把vuex里的头像数据改为上传成功接口返回的头像路径,导航栏的头像数据来源为vuex,就能实现上传头像和导航栏的联动效果

开发流程

1、在页面的生命周期函数里发起个人信息请求,拿到头像数据放在vuex里

2、在上传头像组件的计算属性里获取vuex里的头像数据,判断是默认头像(如果是默认头像,还需却要性别信息老判断男女)还是自定义头像

3、使用input标签实现上传文件的功能

废话不多讲,上代码

<template>
    <div class="teacherInfohBox">
        <div class="avatarW" v-if="!avatar">  //此处为默认头
            <img v-if="userGenderCode == 'UA01' " src="../../assets/img/setting/02_03.png" alt="">
            <img v-if="userGenderCode == 'UA02' " src="../../assets/img/setting/01_03.png" alt="">
        </div>
        <div class="avatarW" v-if="avatar">  //此处为自定义头像
            <img :src="avatar" alt="">
        </div>
        <span @click="uploadHeadImg">更换头像</span>
        <input
            type="file"
            accept="image/jpeg, image/jpg, image/png"  //用户打开文件选择框默认展示的文件格式,其他格式的文件会做隐藏,但用户仍能选择,所以在上传的时候得做二次验证
            @change.stop="handleFile"  //回调函数
            class="hiddenInput"
        >
    </div>
</template>


<script>
import { mapState , mapActions ,mapMutations } from 'vuex';
const OSS = require('ali-oss');  //引入oss
export default {
    data() {
        return {
            avatarUrl:null //本地头像路径
        }
    },
    methods: {
        uploadHeadImg(){ //点击上传头像按钮的事件
            this.$el.querySelector(".hiddenInput").click()  //事件转移
        },
        handleFile(e) { //上传头像的事件函数
            this.$store.dispatch('getOssInfo',{type:"avatar"}).then(() => {  //先获取oss文件上传的通行证
                var client = new OSS({  //构造oss
                    region:this.ossInfo.region,
                    accessKeyId:this.ossInfo.accessKeyId,
                    accessKeySecret:this.ossInfo.accessKeySecret,
                    stsToken:this.ossInfo.securityToken,
                    bucket:this.ossInfo.atchBucket
                })
                let $target = e.target || e.srcElement;
                let file = $target.files[0];
                var reader = new FileReader();  //图片渲染所需
                if(file){ //限制上传文件的大小
                    let size = 2*1024*1024  //文件限制的大小
                    let type = file.type.split('/')[1]  //上传文件的格式
                    let name = this.ossInfo.atchRemoteDirPath + '/' + file.name  //上传头像的格式
                    if(file.size > size){
                        this.$toast.warning("大小超出限制")
                    }else if(type != 'png' && type != 'jpeg' && type != 'jpg'){
                        this.$toast.warning("图片格式不正确")
                    }else{
                        client.put(name,file).then((res) => { //这是往oss传图片之后成功的回调
                            this.avatarUrl = res.url.substring(7,)
                            this.upLoadAvatar({     //往服务端发上传头像的请求
                                atchFmt: file.type.split('/')[1],
                                atchRemotePath: res.name,
                                atchBucket: this.ossInfo.atchBucket,
                                atchSize: file.size
                            }).then(() => {
                                this.$toast.success("上传成功")
                                this.setAvatar(this.avatarUrl) //更改vuex里的头像数据
                                reader.readAsDataURL(file); //这里需要考虑情况是否是点击更换页面就变头像,还是先调上传头像接口,待接口返回成功后再改变页面上的头像
                            })
                        }).catch((err) => {
                            console.log("err")
                        })
                    }
                }
            })
        },
        ...mapMutations(['setAvatar']),  //vuex里修改头像路径的同步方法
        ...mapActions(['upLoadAvatar'])  //调用后端上传头像的接口的异步方法
    },
    computed: {
        ...mapState({ //获取个人中心的用户性别
            userGenderCode:state => state.set.userList.userGenderCode,  //获取用户信息,主要输头像和性别信息
            ossInfo:state => state.set.ossInfo,  //获取oss配置信息
            avatar:state => state.set.avatar  //获取头像信息
        })
    }
}
</script>

<style lang="scss" scoped>
@import "../../assets/css/_tools.scss";
.teacherInfohBox{
    height: 236px;
    text-align: center;
    @include por;
    .hiddenInput {
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        display: none;
        @include poa;
    }
    &>span{
        font-size: 10px;
        top: 10px;
        left: 475px;
        text-decoration: underline;
        @include c9;
        @include poa;
        @include finger;
    }
    .avatarW{
        left: 50%;
        transform: translate(-50%);
        margin-top:20px;
        width: 107px;
        height: 107px;
        border: 1px solid #33b6ae;
        border-radius: 50%;
        display: flex;
        justify-content: center;
        align-items: center;
        @include poa;
        img{
            height: 92px;
            width: 92px;
            border-radius: 50%;
        }
    }
}
</style>

##附oss对象存储SDK链接:https://help.aliyun.com/document_detail/64041.html?spm=a2c4g.11186623.2.15.37ec15cdNTBg6r#concept-64041-zh

Logo

前往低代码交流专区

更多推荐