“This article has participated in the call for good writing activities, click to view: the back end, the big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!”

In this article, we will implement a simple front and back end separation function — student system, front-end using Vue+ElementUI, back-end using SpringBoot+MyBatis.

The article will not cover the technical content, but the whole process of front and back end development

Environment to prepare

Before we start development, let’s prepare the development environment. In order to avoid some errors, please keep the version of my environment consistent.

Download Node. js and go to nodejs.org/zh-cn/downl…

Download the 14.15.0 installation package, and then click next. After the installation is successful, verify the installation, open CMD, and run the following command:

node -v
Copy the code

If the version number is output, the installation is successful. Then configure Taobao image, which can speed up the download of dependencies:

npm config set registry https://registry.npm.taobao.org
Copy the code

This project is developed using vue-element-admin scaffolding as the base framework, so download it and go to GitHub: github.com/PanJiaChen/…

Download or clone the project, and decompress it to get a ready-made background management system. Open the CMD window, switch the path to the project, and execute the command:

npm i
Copy the code

NPM will help us download the dependencies needed by the project and wait for them to complete:

Warning is normal, as long as there is no error, now we can start the project, execute the command:

npm run dev
Copy the code

Click the login button directly to enter the background:

At present this background is still an empty shell, the next task is to implement it.

Scaffolding Project Introduction

If you are new to the scaffolding project of Vue, you must feel at a loss when you see so many files in the project. It doesn’t matter, let’s first analyze the project structure.

For Vue’s scaffolding project, it has an entry file main.js:

import Vue from 'vue'
import 'normalize.css/normalize.css' // A modern alternative to CSS resets
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import locale from 'element-ui/lib/locale/lang/en' // lang i18n
import '@/styles/index.scss' // global css
import App from './App'
import store from './store'
import router from './router'
import '@/icons' // icon
import '@/permission' // permission control

if (process.env.NODE_ENV === 'production') {
  const { mockXHR } = require('.. /mock')
  mockXHR()
}
Vue.use(ElementUI, { locale })
// If you want the Chinese version of Element-UI, declare it as follows
// Vue.use(ElementUI)

Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  store,
  render: h= > h(App)
})
Copy the code

The previous 11 lines introduce modules and components, so we don’t need to worry about them. Focus on lines 23 to 27. In these 5 lines, we create an instance of Vue, bind it to the DOM element with the ID app, and render it using the render attribute. So what it does is it renders the content of the App component onto the DOM element with the ID App, so where is the DOM element with the ID App?

It can be found in index.html in the public directory:

The code is as follows:

<! DOCTYPEhtml>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= webpackConfig.name %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <! -- built files will be auto injected -->
  </body>
</html>
Copy the code

It’s worth explaining that the scaffolding for Vue is typically SPA (Single Page Application) projects: single-page applications. So there’s only one page in the whole project, and the changes to the page are implemented by this DIV with the ID app; In main.js, it renders the App component into this div, so the content of the page is actually determined by the App component.

The App component can be found in the project root directory:

The code is as follows:

<template>
<div id="app">
  <router-view />
  </div>
</template>

<script>
  export default {
    name: 'App'
  }
</script>
Copy the code

A Vue component consists of three parts: template, script, and style. Template is used to display page content. There is only one label written here, and route-view is a routing label.

In the router directory there is an index.js, which is used to configure routing rules:

There is a lot of content in this file. Here is an excerpt for analysis:

export const constantRoutes = [
  {
    path: '/login'.component: () = > import('@/views/login/index'),
    hidden: true
  },

  {
    path: '/ 404'.component: () = > import('@/views/404'),
    hidden: true
  },

  {
    path: '/'.component: Layout,
    redirect: '/dashboard'.children: [{
      path: 'dashboard'.name: 'Dashboard'.component: () = > import('@/views/dashboard/index'),
      meta: { title: 'Dashboard'.icon: 'dashboard'}}}]]Copy the code

Path specifies the routing rule, Component specifies the component, and Vue monitors the address change in the address bar. When the address bar changes to /login, Vue replaces the route-view label with the component configured in Component.

Student information – front-end development

Just a brief introduction to Vue scaffolding project, next we will implement a student information management, first add routing rules:

{
    path: '/student'.component: Layout,
    children: [{path: 'index'.name: 'Student'.component: () = > import('@/views/student/index'),
        meta: {title: 'Student Information'.icon: 'form'}}},Copy the code

Add it to the constantRoutes property in the router directory index.js:

Here’s another line of code:

component: () = > import('@/views/student/index')
Copy the code

SRC /views/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue/index.vue

Index. vue reads as follows:

<template> <div> <script> export default {name: "index"} </script> <style scoped> </style>Copy the code

See how it looks:

Now that a menu item is defined, the next step is to write the right page. On the right side, we use a table to display students’ information. Go to the official website of Element-UI: element.eleme.cn/#/zh-CN/com… Find the table contents:

Copy and paste the table contents into index.vue in the student directory:

<template> <div> <el-table :data="tableData" stripe style="width: 100%"> <el-table-column prop=" ID "label=" student id" > </el-table-column> <el-table-column prop="name" label=" student name" > </el-table-column> <el-table-column prop="project" label=" professional "> </el-table-column> <el-table-column prop="class" Label =" class "> </el-table-column> </el-table> </div> </template> <script> export default {} </script> <style scoped> </style>Copy the code

Take a look at the page:

Now that we have the table, it’s time to prepare the data.

Student information – Backend development

Create a table of student information in the database:

create database class_system;

use class_system;

create table student(
	id varchar(10) primary key not null,
	name varchar(50) not null,
	project varchar(50) not null,
	class varchar(50) not null
);
Copy the code

The class should create a class table and establish a foreign key association. For convenience, we set it to character type and add some test data:

insert into student value ('1809100001'.'Joe'.'Computer Science and Technology'.'18 Computer Class 1 ');
insert into student value ('1809100002'.'bill'.'Computer Science and Technology'.'18 Computer Class 1 ');
insert into student value ('1809100003'.'Cathy'.'Computer Science and Technology'.'18 Computer Class 2 ');
Copy the code

Create a SpringBoot application and import the associated dependencies:

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.4.2</version>
</dependency>
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.10</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.35</version>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
Copy the code

Create entity class:

@Data
public class Student {

    private String id;
    private String name;
    private String project;
    // The class field name in the database is class. In Java, class conflicts with the keyword, so use the @tableField annotation to mark the relationship between the attribute and the field name
    @TableField("class")
    private String theClass;
}
Copy the code

Writing Mapper interfaces:

@Mapper
public interface StudentMapper extends BaseMapper<Student> {}Copy the code

Write the Service interface:

public interface StudentService{
    
    List<Student> findAll(a);
}
Copy the code

Write the implementation class of the Service interface:

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Override
    public List<Student> findAll(a) {
        return studentMapper.selectList(null); }}Copy the code

Configure the database information in application.yml:

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql:///class_system
Copy the code

Test the method to see if it works:

@SpringBootTest
class ClasssystemApplicationTests {

    @Autowired
    private StudentService studentService;

    @Test
    void contextLoads(a) { List<Student> students = studentService.findAll(); students.forEach(System.out::println); }}Copy the code

Running results:

Student(id=1809100001, name= Zhang SAN, project= Computer Science and technology, theClass=18The computer1Class) Student (id =1809100002, name= Li Si, project= Computer Science and Technology, theClass=18The computer1Class) Student (id =1809100003, name= wang Wu, project= Computer science and technology, theClass=18The computer2Class)Copy the code

To facilitate the connection between the front and back ends, here is a simple encapsulation of the response result:

@Data
public class R {

    private Integer code;
    private Map<String, Object> data = new HashMap<>();

    private R(a) {}public static R ok(a) {
        R r = new R();
        r.setCode(200);
        return r;
    }

    public static R error(a) {
        R r = new R();
        r.setCode(500);
        return r;
    }

    public R data(String key, Object value) {
        this.data.put(key, value);
        return this; }}Copy the code

Now we can write controllers:

@RestController
public class StudentController {

    @Autowired
    private StudentService studentService;

    @GetMapping("/getStudents")
    public R getStudents(a){
        List<Student> students = studentService.findAll();
        return R.ok().data("students",students); }}Copy the code

Start SpringBoot application, check the return result is correct, go to http://localhost:8080/getStudents:

At this point the development of the back end is complete.

Student information – Front and back integration

So far, we have realized the front end of the page display, back-end interface development, the next is to use the data interface into the front end project.

Start by modifying the.env.development file in the root directory of the front-end project:

Change the VUE_APP_BASE_API configuration value in the file to the address of our back-end application:

# base api
VUE_APP_BASE_API = 'http://localhost:8080'
Copy the code

But this will cause the login function of the front-end project to not work properly:

This is because the front-end project is a server-side implementation of the login written by mock. js itself, and when we changed BASE_API, the request path was tampered with, so modify the mock-server.js file in the Mock directory under the root directory:

Modify line 37 to read:

You also need to modify the user.js file under the SRC API:

Add the following to all three functions of the file:

When finished, restart the front-end project and you can log in to the background.

SRC/utils/request.js

Modify line 49 to read:

This allows the front-end project to receive the correct response from the back-end project.

Create student.js file in SRC/API directory:

import request from '@/utils/request'

export default{
  list(){
    return request({
      url:'/getStudents'.// Interface address
      method:'get'}}})Copy the code

Then call it in index.vue under Student:

<template> <div> <el-table :data="list" stripe style="width: 100%"> <el-table-column prop=" ID "label=" student id" > </el-table-column> <el-table-column prop="name" label=" student name" > </el-table-column> <el-table-column prop="project" label=" professional "> </el-table-column> <el-table-column prop="theClass" Label =" class "> </el-table-column> </el-table> </div> </template> <script> import studentApi from '@/ API /student.js' // Export default {data(){return{list:[]}}, // Lifecycle hook created(){this.fetchData() console.log(this.list)}, methods:{ fetchData(){ studentApi.list().then(response=>{ this.list = response.data.students }) } } } </script> <style scoped> </style>Copy the code

At this time to view the page effect, found a new problem:

This is a very common cross-domain problem in a back-end split project, and I’ll solve it in a simpler way by adding @crossorigin annotations to the Controller of the back-end project:

@RestController
@CrossOrigin
public class StudentController {... }Copy the code

Restart the back-end project and view the page effect:

At this point, a complete front and back end separation function is completed. I wonder if you are familiar with the development process of front and back end separation?