Vue博客搭建(15)个人中心1

219 阅读3分钟

现在我们可以登录注册发文章,但是怎么看自己都写了什么文章呢?我们需要一个个人中心。个人中心还存储着用户的个性签名、生日和头像等。

嵌套路由

一般来讲,一个人的个人空间链接为/space/:userid,“我的文章”链接为/space/:userid/articleList。可以想到在个人空间链接下面还有很多个嵌套的子路由。Vue-router自然是支持的,也很简单。我们只要在对应的路由节点组件中添加一个childeren数组,内容就和通常的节点一样即可。

const routes =[
    {path: '/', component: home},
    {path: '/register', component: register},
    {path: '/login', component: login},
    {path: '/articleEditor', component: articleEditor},
    {path: '/article/:id', component: articleReading},
    {path:'/space/:id',component: space, children:[
        {path:'articles', component: articleList},
        
    ]}
]

在登录的时候才会显示个人中心的按钮。但是这里存在一个问题:我们目前只有用户的邮箱,并没有用户的ID,这边打算使用MD5后的邮箱的前10位作为ID(你也不想顶着邮箱上网吧),因此这边需要扩展一下后端,使其包用户id。

app.get('/test',(req, res)=>{
    const sql = 'alter table useraccount add id varchar(10)';
    connection.query(sql,(err,result)=>{
        console.log(result);
    })
})

app.post('/register',(req, res)=>{
    const captcha = req.body.captcha;
    if(!checkCaptcha(captcha, req.session.captcha)){
        req.session.captcha ='';
        res.status(400).send('验证码错误');
        return;
    }
    const email = req.body.email;
    const username = req.body.username;
    let password = req.body.password;
    password = SHA512(password).toString();
    const id = MD5(email).toString().slice(0,10);
    const addSql=`insert into useraccount (email, username, password, id) values(?,?,?,?)`;
    const selectSql = `select * from useraccount where email = '${email}'`;
    connection.query(selectSql,(err,result)=>{
        if(result.length!==0){
            res.status(400).send('邮箱已被占用');
        }else{
            connection.query(addSql,[email, username, password, id],(err)=>{
            if(err){
                res.status(500).send(`注册失败, ${err}`);
            }else{
                res.send('注册成功');
            }
    })
        }
    })
})

既然我们已经有了id,那么前端便不应该存储用户邮箱了,而应该是用户的id。因此我们需要推翻上一篇文章中的前端代码。虽然看上去有一些重复劳动,但是这便是敏捷开发带来的额外负担,我们不得不承受。同时为了防止数据库报错,我们还需要清空原数据库中的数据(反正都是些测试数据),SQL中清空数据表的语句为truncate table TABLENAME。这里就不给出具体代码了。

前期的准备工作都做完了,我们就可以创建用户中心页面了。用户中心页面中也需要一个router-view作为嵌套路由的页面显示。

<script setup>
import { useRoute } from 'vue-router';

const route = useRoute()

</script>

<template>
    <h1>个人中心</h1>
    <router-view></router-view>
</template>

<style scoped>
h1{
    margin-top: 0;
}

</style>

导航守卫

非本人用户和本人用户空间所需要的功能是不一样的,这就导致我们不能用同一套组件传入不同的id。我们需要先创建一个mySpace.vue组件,然后创建对应的路由。并且当/space/:id中的id等于目前登录的id时,路由就会将链接重定向至/mySpace

Vue-Router自然也支持这个功能,这便是导航守卫。可以注册全局导航守卫,也可以给特定的路由注册专属的导航守卫。目前route的代码比较多了,可以单独抽离出来成为一个route.js

导航守卫的优点在哪呢?就在于它会在路由跳转前就进行对应的判断,而不是路由跳转之后再进行判定,因此不用再加载对应页面的资源。在实际的生产环境中,很少会单独给一个路由设定守卫,通常都使用全局守卫,因此我们先给/articleEditor添加守卫,代替页面本身的登录判断。

const userAccountStore = useUserAccountStore();

router.beforeEach( (to, from)=>{
    if(to.path === '/articleEditor' && !userAccountStore.isLogged){
        alert('您还未登录,请先登录!');
        return false;
    }
})

发现会报错,报错的竟然是pinia。这是因为vue插件是异步加载的,pinia还没有被挂载到实例上,而vue-router就被加载了,这就会报错。因此我们先把pinia实例引入到route.js上,这样就可以遵循正确的顺序了。这是store.js的代码:

import {createPinia} from 'pinia'

const pinia = createPinia();

export{
    pinia
}

route.js中把引入pinia修改一下即可。

import { pinia } from '../stores/store'

const userAccountStore = useUserAccountStore(pinia);

此时我们就可以判定个人空间了,如果即将访问的个人空间id是自己的,那么就会被重定向到/mySpace页面。