前言

SpringBoot+Vue是一款常见且适用性很强的组合,今天我们将会结合两者的优势,实现一个功能简单但很实用的公告功能。

前置知识介绍

在阅读本篇文章之前,您需要具备以下知识和技能:

  • 熟悉SpringBoot框架;
  • 熟悉Vue框架;
  • 熟悉前后端交互过程;
  • 了解axios库的使用;
  • 熟悉HTML/CSS/JavaScript。

项目概述

项目的主要功能是实现一个公告展示页面,管理员可以在后台发布公告,前台用户可以浏览公告内容。具体实现包括后端的公告管理模块和前端的公告展示模块。

后端实现

创建SpringBoot项目

首先,我们需要新建一个SpringBoot项目,可以使用SpringBoot官方提供的脚手架工具——Spring Initializr来创建项目。在脚手架页面中,选择需要的依赖项,例如MySQL、Spring Web和MyBatis等,可以根据自己的需要来选择。完成创建后,可以打开主类文件进行简单配置:

@SpringBootApplication
@MapperScan("com.example.demo.mapper") // mapper类扫描路径
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

数据库表设计

本项目需要的数据库表只有一张,用于存放公告的信息。表的结构如下:

CREATE TABLE `notice` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` varchar(255) NOT NULL,
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

其中,id为自增长主键,content为公告内容,create_time为公告发布时间。

DAO层实现

DAO(Data Access Object)即数据访问层,是作为数据访问的桥梁,与数据库进行交互。在我们这个项目中,需要通过DAO层来做增删改查等操作。

我们可以使用MyBatis框架来编写DAO层代码。具体实现过程如下:

首先,需要在resources目录下新建mapper文件夹,并在该文件夹下新建NoticeMapper.xml文件,该文件用于存放SQL语句。在该文件中,新建对照表结构的SQL语句,例如:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.NoticeMapper">
    <select id="findAll" resultType="Notice">
        select * from notice
    </select>
    <delete id="deleteById" parameterType="int">
        delete from notice where id = #{id}
    </delete>
    <insert id="insert" parameterType="Notice">
        insert into notice(content) values(#{content})
    </insert>
</mapper>

注:这里只是一部分示例SQL语句,没有给全部。

其中,标签的namespace属性指定了要执行的mapper接口的全限定名。在该文件中,我们可以定义一些数据访问的方法,例如findAll(查询所有),deleteById(根据id删除),insert(插入一条记录)等。

接下来,在mapper目录下新建NoticeMapper.java文件,该文件为DAO层代码文件,用于与数据库交互执行SQL语句。

@Mapper
public interface NoticeMapper {
    List<Notice> findAll();

    Notice findById(int id);

    int deleteById(int id);

    int insert(Notice notice);
}

在接口中,定义了访问数据库的方法,例如findAll(查询所有),findById(根据id查询),deleteById(根据id删除),insert(插入一条记录)等。这些方法的实现由MyBatis框架自动生成,我们只需要声明即可。

Service和Controller层实现

Service层即服务层,一般包含业务逻辑,对数据进行处理并返回结果。Controller层即控制层,用于接收请求并响应结果,将前端请求传递给Service层。

在本项目中,我们需要完成的是公告的增删改查四个操作。因此,需要定义NoticeService接口,根据业务逻辑来编写代码。

public interface NoticeService {
    List<Notice> findAll();

    Notice findById(int id);

    int deleteById(int id);

    int insert(Notice notice);
}

在接口中,定义了访问数据库的方法,这些方法在Service层中实现。实现类中,通过调用NoticeMapper接口中的方法实现对数据库的访问。

@Service
public class NoticeServiceImpl implements NoticeService {

    @Autowired
    private NoticeMapper noticeMapper;

    @Override
    public List<Notice> findAll() {
        return noticeMapper.findAll();
    }

    @Override
    public Notice findById(int id) {
        return noticeMapper.findById(id);
    }

    @Override
    public int deleteById(int id) {
        return noticeMapper.deleteById(id);
    }

    @Override
    public int insert(Notice notice) {
        return noticeMapper.insert(notice);
    }
}

最后,在Controller层中,需要编写方法来响应前端请求。在本项目中,我们需要响应四个请求,分别是GET请求(查询所有公告)、GET请求(根据id查询)、DELETE请求(根据id删除)、POST请求(插入一条记录)。

@RestController
@RequestMapping("/api/notice")
public class NoticeController {

    @Autowired
    private NoticeService noticeService;

    @GetMapping("/findAll")
    public List<Notice> findAll() {
        return noticeService.findAll();
    }

    @GetMapping("/findById/{id}")
    public Notice findById(@PathVariable("id") int id) {
        return noticeService.findById(id);
    }

    @DeleteMapping("/deleteById/{id}")
    public int deleteById(@PathVariable("id") int id) {
        return noticeService.deleteById(id);
    }

    @PostMapping("/insert")
    public int insert(@RequestBody Notice notice) {
        return noticeService.insert(notice);
    }
}

在Controller层中,使用@Autowired注解来注入Service层对象,从而调用Service层中的方法,并通过@RequestMapping指定请求地址和请求方法。

至此,后端的代码就已经完成了。

前端实现

准备工作

在本项目中,前端采用Vue框架进行开发。我们需要先使用Vue脚手架工具——Vue CLI来创建项目。运行下面的命令来创建项目:

vue create notice-frontend

在项目创建完成后,进入项目文件夹并启动项目:

cd notice-frontend
npm run serve

页面布局

我们需要一个页面来展示公告列表,一个页面来展示单个公告的详细信息,并且可以点击“添加公告”按钮来添加新公告。

公告列表页面

在src/components目录下新建NoticeList.vue文件,该文件用于展示公告列表,并可点击任意一条公告的标题以查看详细信息。代码如下:

<template>
  <div>
    <h2>公告列表</h2>
    <div v-for="notice in notices" :key="notice.id">
      <router-link :to="'/notice-detail/'+notice.id">
        <h3>{{notice.content}}</h3>
      </router-link>
    </div>
  </div>
</template>

<script>
export default {
  name: 'NoticeList',
  data() {
    return {
      notices: [],
    }
  },
  mounted() {
    this.getNotices();
     },
  methods: {
    getNotices() {
      axios.get('/api/notice/findAll').then((res) => {
        this.notices = res.data;
      });
    },
  },
};
</script>

在页面中,我们使用了Vue的模板语法来动态渲染公告列表。使用v-for遍历notices数组,将每一条公告展示出来。其中,使用了Vue Router中的router-link组件将公告标题包装成一个超链接,点击后可以跳转到对应的公告详情页面。

在mounted方法中,调用getNotices方法来获取所有的公告信息。使用axios库发送GET请求,请求地址为“/api/notice/findAll”。接收后端返回的所有公告信息,并将其存储在notices数组中,最终在页面展示出来。

公告详情页面

在src/components目录下新建NoticeDetail.vue文件,该文件用于展示单条公告的详细信息,同时可以删除该条公告。代码如下:

<template>
  <div>
    <h2>公告详情</h2>
    <h3>{{notice.content}}</h3>
    <button @click="deleteNotice">删除</button>
  </div>
</template>

<script>
export default {
  name: 'NoticeDetail',
  data() {
    return {
      notice: {},
    }
  },
  mounted() {
    this.getNotice();
  },
  methods: {
    getNotice() {
      axios.get('/api/notice/findById/' + this.$route.params.id).then((res) => {
        this.notice = res.data;
      });
    },
    deleteNotice() {
      axios.delete('/api/notice/deleteById/' + this.$route.params.id).then((res) => {
        if (res.data === 1) {
          this.$router.push('/');
        } else {
          alert('删除失败!');
        }
      });
    },
  },
};
</script>

在页面中,我们先使用Vue模板语法来展示公告的内容,使用h3标签展示公告标题。

与公告列表页面类似,我们也需要使用axios发送GET请求来获取单条公告的详细信息,在mounted方法中调用getNotice方法。注意,在URL中使用$route.params.id来获取动态路由中的id参数。将返回的公告信息存储在notice对象中,最终在页面中展示出来。

再看deleteNotice方法,当用户点击删除按钮时,该方法会发送一个DELETE请求,请求地址为“/api/notice/deleteById/”+id。其中,id同样从动态路由中获取。如果删除成功,则跳转回公告列表页面;否则弹出“删除失败!”的提示。

添加公告页面

在src/components目录下新建AddNotice.vue文件,该文件用于添加一条新公告。代码如下:

<template>
  <div>
    <h2>添加公告</h2>
    <form @submit.prevent="handleSubmit">
      <textarea v-model="notice.content" placeholder="请输入公告内容"></textarea>
      <button type="submit">提交</button>
    </form>
  </div>
</template>

<script>
export default {
  name: 'AddNotice',
  data() {
    return {
      notice: {
        content: '',
      },
    };
  },
  methods: {
    handleSubmit() {
      axios.post('/api/notice/insert', this.notice).then((res) => {
        if (res.data === 1) {
          this.$router.push('/');
        } else {
          alert('添加失败!');
        }
      });
    },
  },
};
</script>

在页面中,我们使用Vue模板语法展示页面标题,并创建了一个表单用于获取用户输入的公告内容。通过textarea和v-model指令来实现数据双向绑定,表示公告内容由用户输入。

当用户点击提交按钮时,handleSubmit方法会发送一个POST请求,请求地址为“/api/notice/insert”。注意,请求数据需要传递notice对象。如果添加成功,则跳转回公告列表页面;否则弹出“添加失败!”的提示。

路由配置

在src/router/index.js文件中,配置路由信息:

import Vue from 'vue';
import VueRouter from 'vue-router';
import NoticeList from '../components/NoticeList.vue';
import NoticeDetail from '../components/NoticeDetail.vue';
import AddNoticefrom '../components/AddNotice.vue';

Vue.use(VueRouter);

const routes = [
  {
    path: '/',
    component: NoticeList,
  },
  {
    path: '/notice-detail/:id',
    component: NoticeDetail,
  },
  {
    path: '/add-notice',
    component: AddNotice,
  },
];

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
});

export default router;

在路由信息中,配置了三个路由:

  • “/”表示公告列表页面,对应的组件为NoticeList;
  • “/notice-detail/:id”表示公告详情页面,动态路由中包含一个id参数,对应的组件为NoticeDetail;
  • “/add-notice”表示添加公告页面,对应的组件为AddNotice。

如果用户访问未定义的路由,则会跳转到默认的“/”页面。

页面引入

在App.vue文件中,将各个页面引入并渲染出来:

<template>
  <div id="app">
    <router-link to="/">公告列表</router-link>
    <router-link to="/add-notice">添加公告</router-link>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App',
};
</script>

以上代码中,我们在页面中使用了Vue Router提供的router-link组件来实现页面跳转。同时,在页面中使用了Vue Router提供的router-view组件来动态展示不同页面的内容。

至此,前端的代码就已经完成了。

总结

本文介绍了如何使用SpringBoot+Vue框架来实现公告功能。在后端,使用了SpringBoot框架进行开发,并使用MyBatis框架实现数据访问层的操作。在前端,使用了Vue框架进行开发,并使用axios库进行前后端交互。通过具体实现,我们可以深入了解到SpringBoot和Vue的开发流程,掌握前后端交互的方式和方法。

Logo

前往低代码交流专区

更多推荐