vue+node.js手把手教你搭建一個(gè)直播平臺(tái)(五)

hello,好久不見呀!
老鐵們,國慶過去了,該開始敲代碼啦!趕緊瞧過來,告訴你們一個(gè)秘密,小羽悄咪咪的更新了~

不用怕,這節(jié)的內(nèi)容比較簡單,剛剛跟祖國母親過完生日,腦子里還是想著怎么玩呢,哈哈哈?。?!所以這節(jié)主要講最常見的登錄注冊(cè)接口接入【狗頭保命】

1.api接口相關(guān)

在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

像用戶相關(guān)信息的這種數(shù)據(jù),可能會(huì)有很多個(gè)頁面會(huì)用到,屬于公共數(shù)據(jù)來著,總不能我們每次都要從數(shù)據(jù)庫里面拉取我們想要數(shù)據(jù)吧,這樣就會(huì)浪費(fèi)很多不必要的資源,那可怎么辦呢?聰明的小伙伴們一聽到公共數(shù)據(jù)就想到解決方案了。沒錯(cuò),是它,是它,就是它,我們的英雄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統(tǒng)一入口
 * @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.登錄注冊(cè)切圖

修改頭部導(dǎo)航組件中的登錄注冊(cè)模塊,修改的地方如下。主要就是加入了登錄注冊(cè)的彈窗。

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">登錄/注冊(cè)</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="請(qǐng)輸入賬號(hào)" type="text" v-model="loginData.account" />
                        <Input name="password" style="margin:10px 0" prefix="ios-contact" placeholder="請(qǐng)輸入密碼" type="password" v-model="loginData.password"/>
                        <div align="right" style="margin-top:30px">
                            <Button type="primary" @click="userLogin">登錄</Button>
                        </div>
                    </TabPane>
                    <TabPane label="注冊(cè)">
                        <Form ref="registerData" :model="registerData" :rules="ruleRegistValidate" :label-width="60">
                            <FormItem label="昵稱" prop="name">
                                <Input v-model="registerData.name" placeholder="請(qǐng)輸入昵稱" />
                            </FormItem>
                            <FormItem label="郵箱" prop="email">
                                <Input v-model="registerData.email" placeholder="請(qǐng)輸入郵箱" />
                            </FormItem>
                            <FormItem label="密碼" prop="password">
                                <Input v-model="registerData.password" placeholder="請(qǐng)輸入密碼" />
                            </FormItem>
                        </Form>
                        <div align="right">
                            <Button type="primary" @click="userRegister('registerData')">注冊(cè)</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: 跳轉(zhuǎn)到主頁
         * @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: 用戶注冊(cè)
         * @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("注冊(cè)成功")
                    }).catch(err=>{
                        this.$Message.error("注冊(cè)失敗")
                    })
                } else {
                    this.$Message.error('驗(yàn)證失敗!');
                }
            })
        },
    }
}
</script>

然后試一下,登錄/退出功能正常。

image-20201015014017695
image-20201015014048138

再試一下注冊(cè)功能,哦豁,報(bào)錯(cuò)了?。?!
查看報(bào)錯(cuò)文件,401token異常的報(bào)錯(cuò),小case啦,后端加上白名單就ok啦~

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

小結(jié)

帥到睡不著的小羽在本期主要帶老鐵們,接入直播平臺(tái)的用戶相關(guān)api接口,內(nèi)容比較容易,都是聰明的童鞋們,一看就懂~

但是小羽還是得厚著臉皮(這帥氣的小臉都不要了,嗚嗚嗚),硬著頭皮來騙波點(diǎn)贊和關(guān)注~

下期預(yù)告,不出意外的話,講解彈幕模塊相關(guān)。

ps:純?cè)瓌?chuàng),轉(zhuǎn)載請(qǐng)標(biāo)明出處

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容