vue+node.js手把手教你搭建一个直播平台(五)

hello,好久不见呀!
老铁们,国庆过去了,该开始敲代码啦!赶紧瞧过来,告诉你们一个秘密,小羽悄咪咪的更新了~

不用怕,这节的内容比较简单,刚刚跟祖国母亲过完生日,脑子里还是想着怎么玩呢,哈哈哈!!!所以这节主要讲最常见的登录注册接口接入【狗头保命】

1.api接口相关

在src/api/modules新建user.js文件。在src/api/index.js中引入user.js。

image-20201015013101267
/*
 * @description: 用户接口
 * @author: 小羽
 * @lastEditors: 小羽
 * @Date: 2020-08-31 15:39:08
 * @LastEditTime: 2020-09-03 10:01:01
 * @Copyright: 1.0.0
 */
import baseEnv from "@/assets/js/env.js"
import axios from "@/assets/js/http.js"

class User{
    /**
     * @description: 用户登录接口
     * @Date: 2020-09-03 10:00:32
     * @author: 小羽
     * @param {type} 
     * @return {type} 
     */
    userLogin(params){
        return axios.post(`${baseEnv.webUrl}/users/login`,params).then(res=>{
            return res.data
        })
    }

    /**
     * @description: 获取用户信息
     * @Date: 2020-08-31 16:03:52
     * @author: 小羽
     * @param {type} 
     * @return {type} 
     */
    getUserInfo(id="LNsKeo69KLCuGrbNg0nlg2jwQDQub28C"){
        return axios.get(`${baseEnv.webUrl}/users/getUserInfo`,{params:{id:id}}).then(res=>{
            return res.data
        })
    }

    /**
     * @description: 新增用户
     * @Date: 2020-08-31 16:06:33
     * @author: 小羽
     * @param {type} 
     * @return {type} 
     */
    addUser(params){
        return axios.post(`${baseEnv.webUrl}/users/addUser`,params).then(res=>{
            return res.data
        })
    }
}
const user = new User()
export default user
/*
 * @description: 
 * @author: 小羽
 * @github: https://github.com/lyff1006
 * @lastEditors: 小羽
 * @Date: 2020-09-17 23:45:35
 * @LastEditTime: 2020-09-18 00:06:12
 * @Copyright: 1.0.0
 */
import livingRoomApi from "./modules/livingRoom"
import userApi from "./modules/user"

const apiObj = {
    livingRoomApi,
    userApi
}
export default apiObj

2.新增用户store

像用户相关信息的这种数据,可能会有很多个页面会用到,属于公共数据来着,总不能我们每次都要从数据库里面拉取我们想要数据吧,这样就会浪费很多不必要的资源,那可怎么办呢?聪明的小伙伴们一听到公共数据就想到解决方案了。没错,是它,是它,就是它,我们的英雄vuex~

src/store/modules中新增user.js

image-20201015013230626
/*
 * @description: 
 * @author: 小羽
 * @lastEditors: 小羽
 * @Date: 2020-09-01 13:43:51
 * @LastEditTime: 2020-10-15 01:16:59
 * @Copyright: 1.0.0
 */
const state = {
    currentUser:{},
    token:""
}
const actions = {}
const mutations = {
    updateCurrentUser(state,data){
        state.currentUser = data
    },
    updateToken(state){
        state.token = localStorage.getItem("living_token")
    }
}
const getters = {}

export default {
    state,
    actions,
    mutations,
    getters
}

修改src/store/index.js,引入刚刚新增的user.js

/*
 * @description: vuex统一入口
 * @author: 小羽
 * @lastEditors: 小羽
 * @Date: 2020-09-01 13:41:36
 * @LastEditTime: 2020-10-15 01:17:43
 * @Copyright: 1.0.0
 */
import Vue from 'vue'
import Vuex from 'vuex'
import room from "./modules/room"
import user from "./modules/user"
Vue.use(Vuex)

export default new Vuex.Store({
    modules:{
        room,
        user
    }
})

3.登录注册切图

修改头部导航组件中的登录注册模块,修改的地方如下。主要就是加入了登录注册的弹窗。

image-20201015010707462
<div class="live-header-right">
            <Dropdown v-if="token&&currentUser.id">
                <section class="live-header-right-user">
                    <div class="live-header-right-user-avatar">
                        <img :src="currentUser.avatar"/>
                    </div>
                    <div class="live-header-right-user-name">
                        <div>{{currentUser.name}}</div>
                    </div>
                </section>
                <DropdownMenu slot="list">
                    <DropdownItem>
                        <div @click="userLogout">退出登录</div>
                    </DropdownItem>
                </DropdownMenu>
            </Dropdown>
            <section class="live-header-right-user" v-else>
                <div class="live-header-right-user-loginbtn" @click="loginPopupShow=true">登录/注册</div>
            </section>
        </div>
        <section>
            <Modal v-model="loginPopupShow" width="350px" :mask-closable="false" :footer-hide="true" :transfer="false">
                <Tabs>
                    <TabPane label="登录">
                        <Input name="account" style="margin:10px 0" prefix="ios-contact" placeholder="请输入账号" type="text" v-model="loginData.account" />
                        <Input name="password" style="margin:10px 0" prefix="ios-contact" placeholder="请输入密码" type="password" v-model="loginData.password"/>
                        <div align="right" style="margin-top:30px">
                            <Button type="primary" @click="userLogin">登录</Button>
                        </div>
                    </TabPane>
                    <TabPane label="注册">
                        <Form ref="registerData" :model="registerData" :rules="ruleRegistValidate" :label-width="60">
                            <FormItem label="昵称" prop="name">
                                <Input v-model="registerData.name" placeholder="请输入昵称" />
                            </FormItem>
                            <FormItem label="邮箱" prop="email">
                                <Input v-model="registerData.email" placeholder="请输入邮箱" />
                            </FormItem>
                            <FormItem label="密码" prop="password">
                                <Input v-model="registerData.password" placeholder="请输入密码" />
                            </FormItem>
                        </Form>
                        <div align="right">
                            <Button type="primary" @click="userRegister('registerData')">注册</Button>
                        </div>
                    </TabPane>
                </Tabs>
            </Modal>
        </section>

修改头部组件的js脚本如下

<script>
import {mapActions,mapMutations,mapGetters,mapState} from "vuex"
export default {
    name:"liveHeader",
    data(){
        return {
            searchInfo:"",
            loginData:{
                account:"",
                password:"",
            },
            registerData:{
                name:"",
                email:"",
                password:""
            },
            ruleRegistValidate:{
                name: [
                    { required: true, message: '昵称不能为空', trigger: 'blur' }
                ],
                email: [
                    { required: true, message: '邮箱不能为空', trigger: 'blur' },
                    { type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
                ],
                password: [
                    { required: true, message: '密码不能为空', trigger: 'blur' },
                    { type: 'string', min: 6,max:20, message: '密码长度为6~20', trigger: 'blur' }
                ],
            },
            loginPopupShow:false,
        }
    },
    computed:{
        ...mapState({
            currentUser:state=>state.user.currentUser,
            token:state=>state.user.token
        })
    },
    mounted(){
    },
    methods:{
        ...mapActions([
            "setRoomList"
        ]),
        ...mapMutations(["updateRoomList","updateCurrentUser","updateToken"]),

        /**
         * @description: 跳转到主页
         * @Date: 2020-09-03 00:45:46
         * @author: 小羽
         * @param {type} 
         * @return {type} 
         */
        gotoIndex(){
            this.$router.push({path:"/index"})
        },
        /**
         * @description: 获取用户信息
         * @Date: 2020-09-03 10:12:00
         * @author: XianPengFei
         * @param {type} 
         * @return {type} 
         */
        getUserInfo(){
            this.$api.userApi.getUserInfo().then(async res=>{
                await this.updateCurrentUser(res.data)
                this.loginPopupShow=false
                this.$Message.success({
                    background: false,
                    content: '登录成功'
                });
                console.log(this.currentUser)
            })
        },
        /**
         * @description: 用户登录
         * @Date: 2020-09-03 10:22:37
         * @author: XianPengFei
         * @param {type} 
         * @return {type} 
         */
        async userLogin(){
            console.log("userLogin -> this.loginData", this.loginData)
            await this.$api.userApi.userLogin(this.loginData).then(res=>{
                if(res.code===200){
                    let token = res.data
                    localStorage.setItem("living_token",token)
                    this.updateToken()
                }
            })
            this.getUserInfo()
        },
        /**
         * @description: 退出登录
         * @Date: 2020-09-03 11:23:58
         * @author: XianPengFei
         * @param {type} 
         * @return {type} 
         */
        userLogout(){
            localStorage.setItem("living_token","")
            this.updateToken()
            this.updateCurrentUser({})
            this.$Message.error({
                background: false,
                content: '退出登录'
            });
        },

        /**
         * @description: 用户注册
         * @Date: 2020-09-10 23:33:17
         * @author: 小羽
         * @param {type} 
         * @return {type} 
         */
        userRegister(name){
            console.log("userRegister -> this.$refs[name]", this.$refs[name])
            this.$refs[name].validate((valid) => {
                if (valid) {
                    //this.$Message.success('Success!');
                    let data = {
                        ...this.registerData,
                        age:18
                    }
                    this.$api.userApi.addUser(data).then(res=>{
                        console.log("userRegister -> res", res)
                        this.$Message.success("注册成功")
                    }).catch(err=>{
                        this.$Message.error("注册失败")
                    })
                } else {
                    this.$Message.error('验证失败!');
                }
            })
        },
    }
}
</script>

然后试一下,登录/退出功能正常。

image-20201015014017695
image-20201015014048138

再试一下注册功能,哦豁,报错了!!!
查看报错文件,401token异常的报错,小case啦,后端加上白名单就ok啦~

image-20201015014338131
image-20201015014425766
app.use(expressJwt({
  secret:"living_xiaoyu",
  algorithms:['HS256'],
  credentialsRequired:true, //是否校验
}).unless({
  path:['/users/login','/livingRoom/roomList','/livingRoom/roomListByType','/livingRoom/roomDetail','/users/addUser']
}))

小结

帅到睡不着的小羽在本期主要带老铁们,接入直播平台的用户相关api接口,内容比较容易,都是聪明的童鞋们,一看就懂~

但是小羽还是得厚着脸皮(这帅气的小脸都不要了,呜呜呜),硬着头皮来骗波点赞和关注~

下期预告,不出意外的话,讲解弹幕模块相关。

ps:纯原创,转载请标明出处

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342