1. 项目概述
2026年最新版的SpringBoot+Vue个人博客系统,是一个前后端分离的现代化Web应用。这个技术栈组合在2026年依然保持着强大的生命力,SpringBoot 4.x版本在微服务支持、云原生适配方面有了显著提升,而Vue 3.x的Composition API和性能优化也让前端开发体验更上一层楼。
我选择这个技术组合主要基于三个考量:首先,SpringBoot的自动配置和起步依赖能快速搭建后端服务,其内嵌Tomcat容器简化了部署流程;其次,Vue的响应式特性和组件化开发完美匹配博客这类内容型网站的需求;最后,这两个框架都有丰富的生态系统,遇到问题可以快速找到解决方案。
博客系统的基础功能模块包括:
- 用户认证(JWT实现)
- 文章管理(CRUD+Markdown编辑器)
- 分类标签系统
- 评论互动模块
- 数据统计看板
特别提示:2026年的SpringBoot默认要求JDK21+,需要注意开发环境配置。Vue3也推荐使用Vite作为构建工具而非传统的Webpack。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 后端SpringBoot 4.x实现
后端采用经典的MVC分层架构:
code复制com.example.blog
├── config # 配置类
├── controller # 控制器层
├── service # 业务逻辑层
├── repository # 数据访问层
├── model # 实体类
└── util # 工具类
数据库选用MySQL 8.0,主要表结构设计:
sql复制CREATE TABLE `article` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`title` VARCHAR(100) NOT NULL,
`content` LONGTEXT NOT NULL,
`view_count` INT DEFAULT 0,
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_time` DATETIME ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
安全方面采用Spring Security + JWT方案:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()));
return http.build();
}
}
2.2 前端Vue3组合式API
前端项目结构:
code复制src/
├── assets # 静态资源
├── components # 公共组件
├── composables # 组合式函数
├── router # 路由配置
├── stores # Pinia状态管理
├── styles # 全局样式
└── views # 页面组件
典型组件示例(ArticleList.vue):
vue复制<script setup>
import { ref, onMounted } from 'vue'
import { fetchArticles } from '@/api/article'
const articles = ref([])
onMounted(async () => {
articles.value = await fetchArticles()
})
</script>
<template>
<div v-for="article in articles" :key="article.id">
<h2>{{ article.title }}</h2>
<div v-html="article.content"></div>
</div>
</template>
3. 核心功能实现细节
3.1 Markdown编辑器集成
采用Toast UI Editor作为编辑器核心:
javascript复制import Editor from '@toast-ui/editor'
import '@toast-ui/editor/dist/toastui-editor.css'
const editor = new Editor({
el: document.querySelector('#editor'),
height: '500px',
initialEditType: 'markdown',
previewStyle: 'vertical'
})
后端处理Markdown转换HTML:
java复制public String markdownToHtml(String markdown) {
MutableDataSet options = new MutableDataSet();
Parser parser = Parser.builder(options).build();
Node document = parser.parse(markdown);
HtmlRenderer renderer = HtmlRenderer.builder(options).build();
return renderer.render(document);
}
3.2 文章分类与标签系统
实现多对多关系:
java复制@Entity
public class Article {
@ManyToMany
@JoinTable(name = "article_tag",
joinColumns = @JoinColumn(name = "article_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id"))
private Set<Tag> tags = new HashSet<>();
}
前端标签云组件实现:
vue复制<template>
<div class="tag-cloud">
<span
v-for="tag in tags"
:key="tag.id"
:style="{ fontSize: getFontSize(tag.count) }"
@click="filterByTag(tag.id)"
>
{{ tag.name }}
</span>
</div>
</template>
4. 性能优化实践
4.1 后端缓存策略
采用Spring Cache + Redis:
java复制@Cacheable(value = "articles", key = "#id")
public Article getArticleById(Long id) {
return articleRepository.findById(id).orElseThrow();
}
配置示例:
yaml复制spring:
cache:
type: redis
redis:
host: localhost
port: 6379
4.2 前端懒加载与代码分割
路由级代码分割:
javascript复制const routes = [
{
path: '/article/:id',
component: () => import('@/views/ArticleDetail.vue')
}
]
图片懒加载指令:
javascript复制app.directive('lazy', {
mounted(el) {
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
el.src = el.dataset.src
observer.unobserve(el)
}
})
observer.observe(el)
}
})
5. 部署与监控
5.1 Docker容器化部署
后端Dockerfile示例:
dockerfile复制FROM eclipse-temurin:21-jdk
COPY target/blog-backend-0.0.1.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
前端Dockerfile:
dockerfile复制FROM nginx:alpine
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
5.2 Prometheus监控集成
SpringBoot Actuator配置:
yaml复制management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
metrics:
export:
prometheus:
enabled: true
6. 常见问题解决方案
6.1 跨域问题处理
SpringBoot配置:
java复制@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080")
.allowedMethods("*");
}
};
}
6.2 大文件上传处理
分段上传前端实现:
javascript复制const uploadFile = async (file) => {
const chunkSize = 5 * 1024 * 1024 // 5MB
const chunks = Math.ceil(file.size / chunkSize)
for (let i = 0; i < chunks; i++) {
const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize)
await uploadChunk(chunk, i, file.name)
}
}
后端接收处理:
java复制@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) {
String fileName = file.getOriginalFilename();
Path path = Paths.get("uploads/" + fileName);
Files.write(path, file.getBytes());
return "Upload success";
}
7. 安全防护措施
7.1 XSS防护
Vue默认已提供XSS防护,对于需要渲染HTML的内容:
vue复制<div v-html="sanitizedHtml"></div>
<script setup>
import DOMPurify from 'dompurify'
const sanitizedHtml = computed(() => {
return DOMPurify.sanitize(rawHtml)
})
</script>
7.2 CSRF防护
SpringSecurity配置:
java复制http.csrf(csrf -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringRequestMatchers("/api/public/**")
)
8. 扩展功能实现
8.1 暗黑模式切换
使用CSS变量实现:
css复制:root {
--bg-color: #ffffff;
--text-color: #333333;
}
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #f0f0f0;
}
Vue切换逻辑:
javascript复制const isDark = ref(false)
watch(isDark, (val) => {
document.documentElement.setAttribute('data-theme', val ? 'dark' : 'light')
localStorage.setItem('theme', val ? 'dark' : 'light')
})
8.2 文章搜索功能
Elasticsearch集成:
java复制@Document(indexName = "articles")
public class ArticleDocument {
@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String content;
}
搜索服务实现:
java复制public List<Article> search(String keyword) {
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "content"))
.build();
return elasticsearchOperations.search(query, Article.class)
.stream()
.map(SearchHit::getContent)
.collect(Collectors.toList());
}
在实现过程中,我发现SpringBoot 4.x对GraalVM原生镜像的支持更加完善,可以考虑使用native-image工具将应用编译为原生可执行文件,这能显著提升启动速度和降低内存占用。不过需要注意,某些反射操作需要提前在配置文件中声明。
Vue3的组合式API相比Options API确实更灵活,特别是在复用逻辑时,可以将相关功能封装成组合式函数。但对于刚接触Vue的开发者,可能需要一些适应时间。建议在项目中统一使用一种风格,避免混用造成混乱。
