基于SpringBoot + Vue的个人博客系统07——文章列表和文章详情
简介由于本人不是专业的前端,所以写出来的界面可能会稍微有些丑陋,甚至有些地方的写法不是很专业,还请大家见谅主界面JS 部分首先是 js 逻辑部分我们先在@/http/request.js中定义获取文章信息的方法// 此处省略 axios 的封装,前面的文章中有export default {getArticles(page, limit) {return instance.get(urls.art
简介
由于本人不是专业的前端,所以写出来的界面可能会稍微有些丑陋,甚至有些地方的写法不是很专业,还请大家见谅
主界面
JS 部分
首先是 js 逻辑部分
我们先在@/http/request.js
中定义获取文章信息的方法
// 此处省略 axios 的封装,前面的文章中有
export default {
getArticles(page, limit) {
return instance.get(urls.articles, {
params: {
page: page,
limit: limit
}
}).then(res => res.data);
}
}
然后,下面是Home.vue
中的 js 部分
<script>
import request from "@/http/request";
export default {
name: "Home",
data() {
return {
carousel: {
title: "竹林客栈",
desc: "分享知识,分享生活,分享感动",
urls: [
"https://tvax1.sinaimg.cn/mw1024/bfe05ea9ly1fxgu8jys3fj21hc0u0k0j.jpg",
"https://tvax1.sinaimg.cn/large/bfe05ea9ly1fxgunx09dtj21hc0u0q81.jpg",
"https://tvax1.sinaimg.cn/large/bfe05ea9ly1fxgv2t92yyj21hc0u0qb9.jpg"
]
},
pageInfo: {}
};
},
created() {
request
.getArticles(1, 5)
.then(res => {
if (res.code === 0) {
this.pageInfo = res.data;
} else {
this.$notify.error({
title: "提示",
message: res.msg
});
}
})
.catch(err => {
console.log(err);
this.$notify.error({
title: "提示",
message: "网络忙,文章获取失败"
});
});
}
};
</script>
说明:
- 在 data 中定义 carousel 用于展示轮播图信息,这里先写成固定的,以后我们可以再改成从后端获取
- data 中的 pageInfo 表示一页文章信息
- 然后就是 created 函数在实例已创建,模板还未渲染的时候执行,用于获取文章信息,如果出现错误就弹出提示信息
HTML部分
下面就是数据在页面上的展示,基本就是一些 CSS 和 HTML ,需要注意的是:
- 分类和标签使用了
router-link
标签包裹,这样可以实现点击文字跳转到对应分类或者标签的效果 - 文章标题使用
router-link
跳转的时候把文章 id 作为路径参数传递过去,这样的话在文章详情页面就可以获取到文章 id ,进而根据文章 id 获取文章信息。 - 其中在标题的渲染的时候使用了 v-html 而不是 v-text,是为了方便后期实现根据关键字搜索功能(因为根据实现根据关键字搜索功能的时候,可能需要将某些关键字标红,需要设置行间css样式)
- 文章列表和个人信息部分采用 Element-UI 的分栏布局,详情可参考:https://element.eleme.cn/#/zh-CN/component/layout
<template>
<div>
<el-carousel indicator-position="none" height="400px" arrow="nerver" :interval="5000">
<el-carousel-item v-for="item in carousel.urls" :key="item">
<div class="item-box">
<img :src="item" class="carimg" />
<div class="desc-box">
<h1>{{ carousel.title }}</h1>
<p>{{ carousel.desc }}</p>
</div>
</div>
</el-carousel-item>
</el-carousel>
<el-row :gutter="20">
<el-col :span="14" :offset="2">
<el-card v-for="article in pageInfo.records" :key="article.id">
<div slot="header">
<router-link class="main-text" :to="'/post/' + article.id" v-html="article.title"></router-link>
<div class="article-info">
<el-tag effect="dark" size="mini">原创</el-tag>
浏览量:{{article.views}} 分类:
<router-link
class="link secondary-text"
:to="'/category/'+article.category"
>{{article.category}}</router-link>
</div>
</div>
<div class="tabloid">{{article.tabloid}}</div>
<i class="el-icon-user-solid article-icon">{{article.author}}</i>
<i class="el-icon-date article-icon">{{article.gmtCreate}}</i>
<i class="el-icon-price-tag article-icon">
<router-link
class="tag"
v-for="(tag,index) in article.tags"
:key="index"
v-text="tag"
:to="'/tag/'+tag"
></router-link>
</i>
</el-card>
</el-col>
<el-col :span="6">
<el-card>个人信息</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
// ......上面已经说过,不再赘述
</script>
<style scoped>
.item-box {
position: relative;
width: 100%;
height: 100%;
}
.carimg {
width: 100%;
height: 100%;
overflow: hidden;
object-fit: cover;
}
.desc-box {
position: absolute;
bottom: 0;
left: 50%;
top: 50%;
width: 500px;
height: 40px;
margin-left: -250px;
margin-top: -20px;
text-align: center;
}
.el-card {
margin-top: 20px;
}
.article-info {
margin-top: 10px;
color: #909399;
font-size: 13px;
}
.article-icon,
.article-icon .tag {
color: #909399;
font-size: 13px;
margin-right: 10px;
text-decoration: none;
}
.article-icon .tag:hover {
color: #409eff;
cursor: pointer;
}
.tabloid {
color: #606266;
font-size: 14px;
margin-bottom: 10px;
}
</style>
页面效果
文章详情
1、在 @/http/request.js
中封装根据 id 获取文章信息的方法
getArticleByID(id) {
return instance.get(urls.article + "/" + id).then(res => res.data);
}
2、新建 Article.vue 用于展示页面详情
<template>
<el-row>
<el-col :span="20" :offset="2">
<el-card>{{article}}</el-card>
</el-col>
</el-row>
</template>
<script>
import request from "@/http/request";
export default {
name: "Article",
data() {
return {
article: {}
};
},
created() {
request
.getArticleByID(this.$route.params.id)
.then(res => {
if (res.code === 0) {
this.article = res.data;
} else {
this.$notify.error({
title: "提示",
message: res.msg
});
}
})
.catch(err => {
console.log(err);
this.$notify.error({
title: "提示",
message: "网络忙,文章详情获取失败"
});
});
}
};
</script>
<style scoped>
.el-card {
margin-top: 15px;
padding: 20px;
}
</style>
说明:
- 当组件创建的时候获取文章信息
- 使用
this.$route.params
可以获取路由的路径参数,即文章 id
3、在路由 @/router/index.js
中注册 Article.vue 组件对应的路由
{
path: "/post/:id",
name: "Article",
component: () => import("@/views/Article.vue"),
meta: {
title: "文章详情",
},
},
4、将 markdown 转为 html
markdown 转 html 有很多种方法,可以在前端做转换,也可以在后端转换,这里我们采用前端转换,使用Showdown.js
我们可以使用在项目中导入 js 文件的形式转换,也可以使用大佬封装好的 Vue 组件,这里我们使用一个叫做 VueShowdown 的组件,文档:https://vue-showdown.js.org/zh/guide/
首先,安装 VueShowdown 以及它的插件
npm install vue-showdown
npm install showdown-highlight # 代码高亮插件,只是转化,并没有对应 css
npm install highlight # 引入 highlight.js 主要是想使用,代码高亮的 css
在 main.js 中引入相应的 css,不然高亮不生效, highlight.js 中自带很多 css 高亮样式,这里我们使用 github 样式
import 'highlight.js/styles/github.css'
在 main.js 中注册组件
import { VueShowdown } from 'vue-showdown'
Vue.component('VueShowdown', VueShowdown)
使用组件:
<template>
<el-row>
<el-col :span="20" :offset="2">
<el-card>
<VueShowdown
:markdown="article.content"
flavor="vanilla"
:options="{ emoji: true, tables: true }"
:extensions="extensions"
/>
</el-card>
</el-col>
</el-row>
</template>
说明:
- options 中配置开启 emoji 表情和表格解析
注意此时的data中的 article需要修改为如下格式,不然会报错。
data() {
return {
article: { content: "" },
extensions: [showdownHighlight]
};
},
此时,我们的markdown可以转换为html,代码也可以高亮了。但是原生的 html 样式有些丑,这个时候,我们就可以使用一个好看的css样式来美化项目,这里我们使用的是github-markdown-css
安装:
npm install github-markdown-css
在main.js中引入,这里这里的 github-markdown.css 和上面引入的 highlight.js/styles/github.css 不同,后者只有高亮效果
import 'github-markdown-css/github-markdown.css';
说明:
- 这里的css名称以及路径都可以在 node_modules 目录中找到,如下图中 CSS 文件的路径为
github-markdown-css/github-markdown.css
所以在main.js
中导入的路径就为github-markdown-css/github-markdown.css
最后,在需要使用该样式的外层加入class="markdown-body"
即可
<template>
<el-row>
<el-col :span="20" :offset="2">
<el-card class="markdown-body">
<h1>{{article.title}}</h1>
<blockquote>{{'作者:' + article.author + ' | 创建时间:' + article.gmtCreate + ' | 浏览数:' + article.views + ' | 分类:' + article.category + ' | 标签:' + article.tags.join("、")}}</blockquote>
<VueShowdown
:markdown="article.content"
flavor="vanilla"
:options="{ emoji: true, tables: true }"
:extensions="extensions"
/>
</el-card>
</el-col>
<el-backtop></el-backtop>
</el-row>
</template>
说明:
- 上面的 CSS 文件也可以在
index.html
中直接引入,但是不建议这样用,因为容易出现在某个组件中直接刷新,CSS 文件加载不出来的情况 - el-backtop 为Element-UI 提供的回顶部组件
- 标题和文章信息暂时就用 h1 和 blockquote 来展示了,随后可能会进行美化
效果图:
表格渲染:
参考代码:https://gitee.com/qianyucc/QBlog2/tree/v-5.0
更多推荐
所有评论(0)