基于SpringBoot和Vue的个人博客系统,附源码
今天介绍一个博客项目,是基于SpringBoot和Vue的前后端分离项目,前台界面炫酷无比、科技感十足,后台管理端功能丰富。
项目特点
前台参考"Hexo"的"Butterfly"设计,美观简洁,响应式体验好。
后台参考"element-admin"设计,侧边栏,历史标签,面包屑自动生成。
采用Markdown编辑器,写法简单。
评论支持表情输入回复等,样式参考Valine。
添加音乐播放器,支持在线搜索歌曲。
前后端分离部署,适应当前潮流。
接入第三方登录,减少注册成本。
支持发布说说,随时分享趣事。
留言采用弹幕墙,更加炫酷。
支持代码高亮和复制,图片预览,深色模式等功能,提升用户体验。
搜索文章支持高亮分词,响应速度快。
新增文章目录、推荐文章等功能,优化用户体验。
新增在线聊天室,支持撤回、语音输入、统计未读数量等功能。
新增aop注解实现日志管理。
支持动态权限修改,采用RBAC模型,前端菜单和后台权限实时更新。
后台管理支持修改背景图片,博客配置等信息,操作简单,支持上传相册。
代码支持多种搜索模式(Elasticsearch或MYSQL),支持多种上传模式(OSS或本地),可支持配置。
代码遵循阿里巴巴开发规范,利于开发者学习。
技术介绍
前端: vue + vuex + vue-router + axios + vuetify + element + echarts
后端: SpringBoot + nginx + docker + SpringSecurity + Swagger2 + MyBatisPlus + Mysql + Redis + elasticsearch + RabbitMQ + MaxWell + Websocket
其他: 接入QQ,微博第三方登录,接入腾讯云人机验证、websocket
部分代码展示
<template>
<div>
<!-- banner -->
<div class="home-banner" :style="cover">
<div class="banner-container">
<!-- 联系方式 -->
<h1 class="blog-title animated zoomIn">
{{ blogInfo.websiteConfig.websiteName }}
</h1>
<!-- 一言 -->
<div class="blog-intro">
{{ obj.output }} <span class="typed-cursor">|</span>
</div>
<!-- 联系方式 -->
<div class="blog-contact">
<a
v-if="isShowSocial('qq')"
class="mr-5 iconfont iconqq"
target="_blank"
:href="
'http://wpa.qq.com/msgrd?v=3&uin=' +
blogInfo.websiteConfig.qq +
'&site=qq&menu=yes'
"
/>
<a
v-if="isShowSocial('github')"
target="_blank"
:href="blogInfo.websiteConfig.github"
class="mr-5 iconfont icongithub"
/>
<a
v-if="isShowSocial('gitee')"
target="_blank"
:href="blogInfo.websiteConfig.gitee"
class="iconfont icongitee-fill-round"
/>
</div>
</div>
<!-- 向下滚动 -->
<div class="scroll-down" @click="scrollDown">
<v-icon color="#fff" class="scroll-down-effects">
mdi-chevron-down
</v-icon>
</div>
</div>
<!-- 主页文章 -->
<v-row class="home-container">
<v-col md="9" cols="12">
<!-- 说说轮播 -->
<v-card class="animated zoomIn" v-if="talkList.length > 0">
<Swiper :list="talkList" />
</v-card>
<v-card
class="animated zoomIn article-card"
style="border-radius: 12px 8px 8px 12px"
v-for="(item, index) of articleList"
:key="item.id"
>
<!-- 文章封面图 -->
<div :class="isRight(index)">
<router-link :to="'/articles/' + item.id">
<v-img
class="on-hover"
width="100%"
height="100%"
:src="item.articleCover"
/>
</router-link>
</div>
<!-- 文章信息 -->
<div class="article-wrapper">
<div style="line-height:1.4">
<router-link :to="'/articles/' + item.id">
{{ item.articleTitle }}
</router-link>
</div>
<div class="article-info">
<!-- 是否置顶 -->
<span v-if="item.isTop == 1">
<span style="color:#ff7242">
<i class="iconfont iconzhiding" /> 置顶
</span>
<span class="separator">|</span>
</span>
<!-- 发表时间 -->
<v-icon size="14">mdi-calendar-month-outline</v-icon>
{{ item.createTime | date }}
<span class="separator">|</span>
<!-- 文章分类 -->
<router-link :to="'/categories/' + item.categoryId">
<v-icon size="14">mdi-inbox-full</v-icon>
{{ item.categoryName }}
</router-link>
<span class="separator">|</span>
<!-- 文章标签 -->
<router-link
style="display:inline-block"
:to="'/tags/' + tag.id"
class="mr-1"
v-for="tag of item.tagDTOList"
:key="tag.id"
>
<v-icon size="14">mdi-tag-multiple</v-icon>{{ tag.tagName }}
</router-link>
</div>
<!-- 文章内容 -->
<div class="article-content">
{{ item.articleContent }}
</div>
</div>
</v-card>
<!-- 无限加载 -->
<infinite-loading @infinite="infiniteHandler">
<div slot="no-more" />
</infinite-loading>
</v-col>
<!-- 博主信息 -->
<v-col md="3" cols="12" class="d-md-block d-none">
<div class="blog-wrapper">
<v-card class="animated zoomIn blog-card mt-5">
<div class="author-wrapper">
<!-- 博主头像 -->
<v-avatar size="110">
<img
class="author-avatar"
:src="blogInfo.websiteConfig.websiteAvatar"
/>
</v-avatar>
<div style="font-size: 1.375rem;margin-top:0.625rem">
{{ blogInfo.websiteConfig.websiteAuthor }}
</div>
<div style="font-size: 0.875rem;">
{{ blogInfo.websiteConfig.websiteIntro }}
</div>
</div>
<!-- 博客信息 -->
<div class="blog-info-wrapper">
<div class="blog-info-data">
<router-link to="/archives">
<div style="font-size: 0.875rem">文章</div>
<div style="font-size: 1.25rem">
{{ blogInfo.articleCount }}
</div>
</router-link>
</div>
<div class="blog-info-data">
<router-link to="/categories">
<div style="font-size: 0.875rem">分类</div>
<div style="font-size: 1.25rem">
{{ blogInfo.categoryCount }}
</div>
</router-link>
</div>
<div class="blog-info-data">
<router-link to="/tags">
<div style="font-size: 0.875rem">标签</div>
<div style="font-size: 1.25rem">{{ blogInfo.tagCount }}</div>
</router-link>
</div>
</div>
<!-- 收藏按钮 -->
<a class="collection-btn" @click="tip = true">
<v-icon color="#fff" size="18" class="mr-1">mdi-bookmark</v-icon>
加入书签
</a>
<!-- 社交信息 -->
<div class="card-info-social">
<a
v-if="isShowSocial('qq')"
class="mr-5 iconfont iconqq"
target="_blank"
:href="
'http://wpa.qq.com/msgrd?v=3&uin=' +
blogInfo.websiteConfig.qq +
'&site=qq&menu=yes'
"
/>
<a
v-if="isShowSocial('github')"
target="_blank"
:href="blogInfo.websiteConfig.github"
class="mr-5 iconfont icongithub"
/>
<a
v-if="isShowSocial('gitee')"
target="_blank"
:href="blogInfo.websiteConfig.gitee"
class="iconfont icongitee-fill-round"
/>
</div>
</v-card>
<!-- 网站信息 -->
<v-card class="blog-card animated zoomIn mt-5 big">
<div class="web-info-title">
<v-icon size="18">mdi-bell</v-icon>
公告
</div>
<div style="font-size:0.875rem">
{{ blogInfo.websiteConfig.websiteNotice }}
</div>
</v-card>
<!-- 网站信息 -->
<v-card class="blog-card animated zoomIn mt-5">
<div class="web-info-title">
<v-icon size="18">mdi-chart-line</v-icon>
网站资讯
</div>
<div class="web-info">
<div style="padding:4px 0 0">
运行时间:<span class="float-right">{{ time }}</span>
</div>
<div style="padding:4px 0 0">
总访问量:<span class="float-right">
{{ blogInfo.viewsCount }}
</span>
</div>
</div>
</v-card>
</div>
</v-col>
</v-row>
<!-- 提示消息 -->
<v-snackbar v-model="tip" top color="#49b1f5" :timeout="2000">
按CTRL+D 键将本页加入书签
</v-snackbar>
</div>
</template>
正文到此结束
- 本文标签: Java Spring Boot vue
- 版权声明: 本站原创文章,于2022年06月12日由程序猿大波发布,转载请注明出处