Spring boot+Vue博客平台:文章列表展示、文章分类与标签管理模块实现

news2025/1/24 17:47:04

本文将详细介绍如何实现博客平台中的文章列表展示、文章分类与标签管理功能,包括前端的Vue组件设计和后端的Spring Boot接口实现。在阅读本文后,您将了解如何设计和实现高效、易用的文章列表展示、文章分类与标签管理功能。

一、文章列表展示

1.设计思路

在设计文章列表展示功能时,我们需要关注以下几点:

  • 支持分页功能,避免一次性加载过多数据
  • 提供文章预览,包括标题、摘要、作者、发布时间等信息
  • 支持按分类和标签筛选文章列表
  • 提供搜索功能,方便用户快速找到感兴趣的文章

2.技术实现

(1) 创建文章列表组件

在前端,使用Vue框架创建一个文章列表组件。该组件包括一个文章列表,每个文章项包含标题、摘要、作者、发布时间等信息。用户可以点击文章标题跳转到文章详情页。

<template>
  <div class="article-list">
    <div class="article-item" v-for="article in articles" :key="article.id">
      <h3>
        <router-link :to="{ name: 'article-detail', params: { articleId: article.id } }">{{ article.title }}</router-link>
      </h3>
      <p class="meta">By {{ article.author }} | {{ article.createdAt }}</p>
      <p class="excerpt">{{ article.excerpt }}</p>
    </div>
    <pagination @page-changed="fetchArticles" :total-pages="totalPages" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      articles: [],
      totalPages: 0,
    };
  },
  async created() {
    await this.fetchArticles(1);
  },
  methods: {
    async fetchArticles(page) {
      const { data } = await this.$http.get(`/articles?page=${page}`);
      this.articles = data.content;
      this.totalPages = data.totalPages;
    },
  },
};
</script>

(2) 实现文章列表接口

在后端,使用Spring Boot创建一个处理文章列表请求的接口。根据请求参数,获取指定页码的文章列表,并返回给前端。

@RestController
@RequestMapping("/articles")
public class ArticleController {
    @Autowired
    private ArticleRepository articleRepository;

    @GetMapping
    public ResponseEntity<?> getArticles(@RequestParam(defaultValue = "1") int page) {
        Pageable pageable = PageRequest.of(page - 1, 10, Sort.by(Sort.Direction.DESC, "createdAt"));
        Page<Article> articles = articleRepository.findAll(pageable);
        return ResponseEntity.ok(articles);
    }
}

二、文章分类与标签管理

1.设计思路

在设计文章分类与标签管理功能时,我们需要关注以下几点:

  • 支持用户自定义分类与标签
  • 支持为文章添加多个分类与标签
  • 支持按分类与标签筛选文章列表

2.技术实现

(1) 创建分类与标签管理组件

在前端,使用Vue框架创建一个分类与标签管理组件。该组件包括分类列表和标签列表,用户可以添加、删除和修改分类与标签。

<template>
  <div class="category-tag-management">
    <div class="categories">
      <h3>Categories</h3>
      <ul>
        <li v-for="category in categories" :key="category.id">
          {{ category.name }}
          <button @click="deleteCategory(category.id)">Delete</button>
        </li>
      </ul>
      <form @submit.prevent="addCategory">
        <input type="text" v-model="newCategory" placeholder="Add category" required />
        <button type="submit">Add</button>
      </form>
    </div>
    <div class="tags">
      <h3>Tags</h3>
      <ul>
        <li v-for="tag in tags" :key="tag.id">
          {{ tag.name }}
          <button @click="deleteTag(tag.id)">Delete</button>
        </li>
      </ul>
      <form @submit.prevent="addTag">
        <input type="text" v-model="newTag" placeholder="Add tag" required />
        <button type="submit">Add</button>
      </form>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      categories: [],
      tags: [],
      newCategory: "",
      newTag: "",
    };
  },
  async created() {
    await this.fetchCategoriesAndTags();
  },
  methods: {
    async fetchCategoriesAndTags() {
      const [categories, tags] = await Promise.all([
        this.$http.get("/categories"),
        this.$http.get("/tags"),
      ]);
      this.categories = categories.data;
      this.tags = tags.data;
    },
    async addCategory() {
      await this.$http.post("/categories", { name: this.newCategory });
      this.newCategory = "";
      await this.fetchCategoriesAndTags();
    },
    async deleteCategory(categoryId) {
      await this.$http.delete(`/categories/${categoryId}`);
      await this.fetchCategoriesAndTags();
    },
    async addTag() {
      await this.$http.post("/tags", { name: this.newTag });
      this.newTag = "";
      await this.fetchCategoriesAndTags();
    },
    async deleteTag(tagId) {
      await this.$http.delete(`/tags/${tagId}`);
      await this.fetchCategoriesAndTags();
    },
  },
};
</script>

(2) 实现分类与标签管理接口

在后端,使用Spring Boot创建一个处理分类与标签管理请求的接口。提供添加、删除和获取分类与标签的接口.

@RestController
@RequestMapping("/api/categories")
public class CategoryController {
    @Autowired
    private CategoryRepository categoryRepository;

    @PostMapping
    public ResponseEntity<?> createCategory(@Valid @RequestBody Category category) {
        categoryRepository.save(category);
        return ResponseEntity.status(HttpStatus.CREATED).body("Category created successfully.");
    }

    @GetMapping
    public ResponseEntity<?> getCategories() {
        List<Category> categories = categoryRepository.findAll();
        return ResponseEntity.ok(categories);
    }

    @DeleteMapping("/{categoryId}")
    public ResponseEntity<?> deleteCategory(@PathVariable Long categoryId) {
        categoryRepository.deleteById(categoryId);
        return ResponseEntity.ok("Category deleted successfully.");
    }
}

@RestController
@RequestMapping("/api/tags")
public class TagController {
    @Autowired
    private TagRepository tagRepository;

    @PostMapping
    public ResponseEntity<?> createTag(@Valid @RequestBody Tag tag) {
        tagRepository.save(tag);
        return ResponseEntity.status(HttpStatus.CREATED).body("Tag created successfully.");
    }

    @GetMapping
    public ResponseEntity<?> getTags() {
        List<Tag> tags = tagRepository.findAll();
        return ResponseEntity.ok(tags);
    }

    @DeleteMapping("/{tagId}")
    public ResponseEntity<?> deleteTag(@PathVariable Long tagId) {
        tagRepository.deleteById(tagId);
        return ResponseEntity.ok("Tag deleted successfully.");
    }
}

通过上述代码,我们实现了分类与标签管理接口。现在,用户可以通过这些接口来创建、获取和删除分类与标签。在实际项目中,还可以根据需要添加更多的分类与标签管理功能,例如修改分类与标签、按照分类或标签筛选文章等。

在这里,我们将补充修改分类与标签功能,并介绍如何按分类或标签筛选文章。

一、修改分类与标签功能

1.前端修改功能实现

在分类与标签管理组件中添加一个修改按钮,点击后弹出一个对话框让用户输入新的分类或标签名称。提交后,调用相应的修改接口。

<!-- 修改分类对话框 -->
<template>
  <div class="edit-dialog">
    <div class="dialog-mask" @click="$emit('close')"></div>
    <div class="dialog-content">
      <h3>Edit Category</h3>
      <form @submit.prevent="editCategory">
        <input type="text" v-model="newName" placeholder="Enter new name" required />
        <button type="submit">Save</button>
      </form>
    </div>
  </div>
</template>

<script>
export default {
  props: ['categoryId'],
  data() {
    return {
      newName: "",
    };
  },
  methods: {
    async editCategory() {
      await this.$http.put(`/api/categories/${this.categoryId}`, { name: this.newName });
      this.newName = "";
      this.$emit('close');
      this.$emit('updated');
    },
  },
};
</script>

2.后端修改功能实现

CategoryControllerTagController中添加修改分类和标签的接口。

// CategoryController
@PutMapping("/{categoryId}")
public ResponseEntity<?> updateCategory(@PathVariable Long categoryId, @Valid @RequestBody Category newCategory) {
    Optional<Category> optionalCategory = categoryRepository.findById(categoryId);
    if (optionalCategory.isPresent()) {
        Category category = optionalCategory.get();
        category.setName(newCategory.getName());
        categoryRepository.save(category);
        return ResponseEntity.ok("Category updated successfully.");
    } else {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Category not found.");
    }
}

// TagController
@PutMapping("/{tagId}")
public ResponseEntity<?> updateTag(@PathVariable Long tagId, @Valid @RequestBody Tag newTag) {
    Optional<Tag> optionalTag = tagRepository.findById(tagId);
    if (optionalTag.isPresent()) {
        Tag tag = optionalTag.get();
        tag.setName(newTag.getName());
        tagRepository.save(tag);
        return ResponseEntity.ok("Tag updated successfully.");
    } else {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Tag not found.");
    }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/413660.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑蓝屏错误MACHINE-CHECK-EXCEPTION重装系统教程

电脑蓝屏错误MACHINE-CHECK-EXCEPTION重装系统教程分享。最近有用户电脑遇到了蓝屏问题&#xff0c;正常使用电脑的时候常常会出现了蓝屏错误代码“MACHINE-CHECK-EXCEPTION”。那么遇到这个问题要怎么去进行系统的重装呢&#xff1f;来看看以下的具体操作方法教学吧。 准备工作…

JVM/GC/CMS

CMS (Concurrent Mark Sweep) jdk1.4后期版本开始引入的新gc算法ParNew(新生代) CMS(老年代)组合使用使用标记-清除算法目标&#xff1a;适合于B/S等对响应时间要求高的场景缺点&#xff1a;运行结束产生大量空间碎片缺点&#xff1a;由于分配给用户使用的老年代空间不足造成…

一文快速回顾 Servlet、Filter、Listener

什么是Servlet&#xff1f; 前置知识&#xff1a; Web 服务器&#xff1a;可以指硬件上的&#xff0c;也可以指软件上的。从硬件的角度来说&#xff0c; Web 服务器指的就是一台存储了网络服务软件的计算机&#xff1b;从软件的角度来说&#xff0c; Web 服务器指的是一种软件…

使用codon加速你的python程序

使用codon加速你的python程序 作为高性能 Python 编译器&#xff0c;Codon 可将 Python 代码编译为本机机器代码&#xff0c;而无需任何运行时开销。在单线程上&#xff0c;Python 的典型加速大约为 10-100 倍或更多。Codon 的性能通常与 C/C 的性能相当。与 Python 不同&#…

Three.js教程:第一个3D场景

推荐&#xff1a;将NSDT场景编辑器加入你3D工具链其他工具系列&#xff1a;NSDT简石数字孪生下面的代码完整展示了通过three.js引擎创建的一个三维场景&#xff0c;在场景中绘制并渲染了一个立方体的效果&#xff0c;为了大家更好的宏观了解three.js引擎&#xff0c; 尽量使用了…

【linux】进程和线程的几种状态及状态切换

文章目录一、进程的状态1.1 进程的三种状态1.2 三种状态转换图1.3 三种状态之间的转换1.4 linux下的进程进程状态二、线程的状态三、总结一、进程的状态 1.1 进程的三种状态 进程状态&#xff1a;一个进程的生命周期可以划分为一组状态&#xff0c;这些状态刻画了整个进程。进…

安装spacy+zh_core_web_sm避坑指南

目录 一、spacy简介 二、安装spacy 三、安装zh_core_web_sm 四、安装en_core_web_sm 五、效果测试 5.1 英文测试 5.2 中文测试 一、spacy简介 spacy是Python自然语言处理&#xff08;NLP&#xff09;软件包&#xff0c;可以对自然语言文本做词性分析、命名实体识别、依赖…

Java数组的四种拷贝方式

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

ERTEC200P-2 PROFINET设备完全开发手册(3-2)

周期数据分为两大类&#xff0c;输出数据OutputData和输入数据InputData&#xff0c;输出数据是PLC发送给设备的&#xff1b;输入数据是设备发送给PLC。如果采用标准接口&#xff08;SI&#xff09;&#xff0c;读取输出数据和写入输入数据都是一次初始化数据读写调用和一次/多…

【ChatGPT】多国“围堵”,万人抵制,AI发展的红线到底在哪?

个人主页&#xff1a;【&#x1f60a;个人主页】 文章目录前言Chatgpt&#x1f4bb;&#x1f4bb;&#x1f4bb;多国拟发ChatGPT禁令&#x1f232;&#x1f232;&#x1f232;开端发展高潮联名抵制自我辩解&#x1f39b;️&#x1f39b;️&#x1f39b;️名家争言比尔盖茨&…

TiDB进阶篇-TiKV架构

简介 简要的介绍下TiKV的架构。 底层存储RocksDB RocksDB的写操作 在写入WAL的时候为了防止操作系统写入的时候有缓存&#xff0c;要设置操作系统的参数sync_logtrue&#xff0c;也就是说只要有数据就执行刷写到磁盘&#xff0c;就不会存储到操作系统的缓存了。MemTable的数据…

【Python】无限逼近求积分

✨博文作者 wangzirui32 &#x1f496; 喜欢的可以 点赞 收藏 关注哦~~ &#x1f449;本文首发于CSDN&#xff0c;未经许可禁止转载 Hello&#xff0c;大家好&#xff0c;我是wangzirui32&#xff0c;今天我们来学习如何用Python无限逼近求积分&#xff0c;开始学习吧&#xff…

krita源码提供了Tarball 和KDE Repository两套源码的区别

krita系列文章目录 文章目录krita系列文章目录前言一、Tarball 和KDE Repository区别是什么&#xff1f;二、使用步骤前言 krita官方主页 krita官方下载界面 krita源码提供了Tarball 和KDE Repository两套源码&#xff0c;我一下就懵圈了&#xff0c;不知道两者的区别 一…

第二章 自然语言处理与单词的分布式表示

目录2.1 自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;2.2 同义词词典2.2.1 WordNet2.2.2 同义词词典的问题2.3 基于计数的方法2.3.1 基于 Python的语料库的预处理2.3.2 单词的分布式表示2.3.3 分布式假设2.3.4 共现矩阵2.3.5 向量间的相似…

有哪些中西合璧的建筑设计?

所谓中西合璧&#xff0c;中即中华文化&#xff0c;体系繁多&#xff0c;源远流长&#xff0c;浩如烟海&#xff0c;是世界三大文化体系之一&#xff0c;在历史上曾是东亚文化的中心&#xff0c;一度影响欧洲&#xff1b;西即西方文化&#xff0c;西方物质文明和精神文明&#…

【JSP学习笔记】1.JSP 教程、简介及开发环境搭建

前言 本章介绍JSP的教程、简介及开发环境搭建。 JSP 教程 JSP 与 PHP、ASP、ASP.NET 等语言类似&#xff0c;运行在服务端的语言。 JSP&#xff08;全称Java Server Pages&#xff09;是由 Sun Microsystems 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户…

2022国赛30:windows脚本题解析

大赛试题内容: ( 九) ) 脚本 【任务描述】 为了减少重复性任务的工作量,节省人力和时间,请采用脚本,实现快速批量的操作。 1.在 windows4 上编写 C:\CreateFile.ps1 的 powershell 脚本,创建20 个文件 C:\test\File00.txt 至 C:\test\File19.txt,如果文件存在,则首先删除…

Servlet初始化参数设置\获取,全局初始化参数的设置、获取

之前在学习SpringMVC、SpringSecurity时&#xff0c;会用到Filter&#xff0c;需要对Filter进行参数配置&#xff0c;而Filter本质上也是一个Servlet&#xff0c;然后对Servlet设置初始化参数已经忘记了&#xff0c;所以打算重新回顾并整理Servlet这一部分的内容&#xff08;虽…

[Netty源码] 编码和解码相关问题 (十二)

文章目录1.编码和解码的介绍2.相关继承3.解码器分析3.1 ByteToMessageDecoder基类3.2 FixedLengthFrameDecoder3.3 LineBasedFrameDecoder3.4 DelimiterBasedFrameDecoder3.5 LengthFieldBasedFrameDecoder4.编码器分析4.1 解码过程分析4.2 writeAndFlush方法分析4.3 MessageTo…

2007-2020年国际产权指数InternationalPropertyRightsIndex(IPRI)IPRI

2007-2020年国际产权指数InternationalPropertyRightsIndex(IPRI)IPRI 1、来源&#xff1a;国际产权联合会 International Poverty Right Alliance 2、时间&#xff1a;2007-2020 3、范围&#xff1a;全球 4、指标说明&#xff1a; country、region、score、annual change…