Vue博客搭建(11)文章浏览

658 阅读2分钟

我们之前做了很多页面,包括注册登录和上传,但是目前并不能查看博客文章。因此这次我们需要做一个文章浏览页面。

动态路由匹配与文章获取

通常来讲,我们在浏览博客的时候访问的链接都是/article/id,而不是article?id=id,这就代表了我们不能通过链接传参的方式来获取对应的博客,而应该使用动态路由匹配。在pages文件夹下新建一个articleReading.vue组件,然后在路由中这样写:

{path: '/article/:id', component: articleReading}

当我们访问/article/1/article/2的时候访问的就都是同一个路由了。对应的参数会绑定到$router对象中,想要显示链接中传入的id便可以直接调用对应的属性即可,像这样。

<template>
    读文章{{ $route.params.id }}
</template>

搞到了文章id后,便可以在前后端分别写好对应的代码了,前端通过server/getArtile链接获取文章,后端通过传入的id来寻找对应的文章发送回去。这里的HTTP使用的是get指令而不是post,并不能包含body,因此我们依旧是通过传参的形式来获取文章。下面是后端的代码,很简单,注意一下express是如何传参的就可以了。

app.get('/getArticle/:id',(req, res)=>{
    const id = req.params.id;
    const selectSql = `select * from articles where id = '${id}'`;
    connection.query(selectSql, (err, result)=>{
        if(result.length === 0){
            res.status(404).end();
        }else{
            const article = result[0];
            res.send(article);
        }
    })
})

为了配合后端的express的参数形式,我们前端的代码最好就像这样:

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

const route = useRoute();

let article ={
    title: '默认文章',
    id: '0000000000000000',
    author: '0',
    createTime: 0,
    content: '文章内容',
    likes: 0,
}

axios.get(`/server/getArticle/${route.params.id}`)
.then((response)=>{
    article = response.data;
})
.catch((err)=>{
    alert(err);
})

console.log(route.params.id);

</script>

<template>
    读文章{{ article.author }}
    {{ article.content }}
</template>

这里的默认文章是为了配合JavaScript的作用域而设置的,同时也可以在页面未渲染完成时起到占位符的作用。

文章渲染

我们获取到了文章的全部内容后就需要进行渲染了。我们之前使用的是bytemd的编辑器,因此这边可以配套使用它的渲染。内容渲染结束后还有作者、创建时间、标题和点赞数的渲染。其中时间渲染我们使用luxon包来进行,这是一款开源的时间渲染包,直接导入时间戳就可以在前端把时间渲染成我们需要的格式。

<script setup>
import axios from 'axios';
import { useRoute } from 'vue-router';
import { Viewer } from '@bytemd/vue-next';
import { nextTick, ref } from 'vue';
import {DateTime} from 'luxon'

import 'bytemd/dist/index.css'

const route = useRoute();

let article =ref({
    title: '默认文章',
    id: '0000000000000000',
    author: '0',
    createTime: 0,
    content: '文章内容',
    likes: 0,
})

axios.get(`/server/getArticle/${route.params.id}`)
.then((response)=>{
    article.value = response.data;
    nextTick();
})
.catch((err)=>{
    alert(err);
})


</script>

<template>
    <h1>{{ article.title }}</h1>
    <div>
        作者:{{ article.author }}
    </div>
    <Viewer :value ="article.content" />
    <div>
        创建于{{ DateTime.fromMillis(Number(article.createTime)).toLocaleString(DateTime.DATE_MED)}}
    </div>
</template>

首页文章

能够创建文章后,我们就可以在首页看文章咯。首先在后端写一个获取随机博客的接口/getRandomArticle。目前无需考虑效率和其它问题

app.get('/getRandomArticle',(req, res)=>{
    const selectSql = `select * from articles`
    connection.query(selectSql,(err,result)=>{
        if(err){
            res.status(500).send(`${err}`);
        }else{
            const index = Math.floor((Math.random()*result.length));
            const article = result[index];
            article.content = article.content.slice(0,20);
            // 取前20个字作为预览内容。
            res.send(article);
        }
    })
})

还记得前端的articlePreview组件么,接下来我们就要对它进行修改,当组件创建时,获取随机博客,根据博客的信息来生成博客预览。

<script setup>
import axios from 'axios';
import { ref } from 'vue';
import { useRouter } from 'vue-router';

const article = ref({
    title: '默认文章',
    id: '0000000000000000',
    author: '0',
    createTime: 0,
    content: '文章内容',
    likes: 0,
});
const router = useRouter()

axios.get('/server/getRandomArticle')
.then((response)=>{
    article.value = response.data;
})

function linkToArticle(){
    router.push(`/article/${article.value.id}`)
}

</script>

<template>
    <div @click="linkToArticle">
        {{ article.title }}
        {{ article.content }}
        
    </div>
</template>

<style>
</style>

至此一个基本的博客系统就做完了。在下一篇文章中我们将会开始进行外观的优化,也就是css的部分。