Spring+Vue(小demo)


1 前端

前端使用 vue + element ui + echarts + axios

1.0 搭建前端环境

1.0.1 NodeJs安装

下载 - 解压 - 配置环境变量 - 验证

C:\Users\MJoe>node -v
v14.17.0

C:\Users\MJoe>npm -v
6.14.13

1.0.2 VueCli安装

npm install -g @vue/cli
// 验证
C:\Users\MJoe>vue --version
@vue/cli 4.5.13

1.1 vue ui 构建vue项目

C:\Users\MJoe> vue ui

安装element ui axios 插件 和 echarts 依赖

1.2 使用idea打开项目

在idea中使用vue.js 首先安装Vue插件

main.js 文件中首先设置 axios baseURL

axios.defaults.baseURL='http://82.156.203.xxx:8181' // 后端ip+port

router/index.js设置路由

import Vue from 'vue'
import VueRouter from 'vue-router'
import Base from "@/views/Base";
import FruitManage from "@/views/FruitManage";
import Index from "@/views/Index";
import FruitAdd from "@/views/FruitAdd";
import FruitBar from "@/views/FruitBar";
import FruitUpdate from "@/views/FruitUpdate";

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: '管理',
    component: Base,
    redirect: '/index',
    children: [
      {
        path: '/index',
        name: '首页',
        show: false,
        component: Index
      },
      {
        path: '/FruitManage',
        name: '查看',
        show: true,
        component: FruitManage
      },
      {
        path: '/FruitAdd',
        name: "新增",
        show: true,
        component: FruitAdd
      },
      {
        path: '/FruitBar',
        name: '柱形图',
        show: true,
        component: FruitBar
      },
      {
        path: '/FruitUpdate',
        name: '更新',
        show: false,
        component: FruitUpdate
      }
    ]
  }

]

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

export default router

App.vue 设置 前端浏览器的最下面一层的vue




Base.vue 设置总体container






FruitManage.vue




FruitAdd.vue







FruitUpdate.vue







FruitBar.vue






前端 <---数据----> 后端

前端使用axios请求后端数据,可以携带数据,格式为JSON

axios.post("/fruit/add",this.ruleForm)     // 其中ruleForm为JSON对象传入到后端

后端使用方法参数的方式接收JSON数据后,使用注解@RequestBody转化为一个entity对象

@PostMapping("/add")
public Boolean fruitAdd(@RequestBody Fruit fruit){
    int insert = fruitMapper.insert(fruit);
    if (insert == 0){
        return false;
    }else return true;
}

2 后端

springboot + mybatisplus + mysql

2.1 新建springboot项目

添加 mybatis-plus依赖集成到springboot

        
            com.baomidou
            mybatis-plus-boot-starter
            3.4.3
        

2.2 新建Fruit数据库

create database fruit;

use fruit;

create table Fruit(
    id int not null auto_increment primary key ,
    name varchar(10) not null ,
    number int not null ,
    picture text
)engine = innodb charset =utf8;

2.3 使用mybatisX生成代码插件

生成 mapper service mapper.xml

2.4 application.yml

server:
  port: 8181
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://82.156.203.105:3306/fruit?useUnicode=true&characterEncoding=utf-8
    username: root
    password: ma1234
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

2.5 MybatisplusConfig (mp配置)

package com.mjoe.fruit_backend.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ClassName : MPConfig
 * @Description : mybatisplusconfig
 * @Author : MJoeBoyae
 * @Date: 2021-06-23 16:42
 */

@Configuration
@MapperScan("com.mjoe.fruit_backend.mapper")
public class MPConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

2.6 跨域问题解决

package com.mjoe.fruit_backend.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @ClassName : CorsConfig
 * @Description : 跨域问题
 * @Author : MJoeBoyae
 * @Date: 2021-06-23 17:01
 */
@Configuration
public class CorsConfig{
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                 .allowCredentials(false)
                 .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                 .allowedOriginPatterns("*");
            }
        };
    }
}

2.7 FruitController实现增删改查

package com.mjoe.fruit_backend.controller;

import com.mjoe.fruit_backend.VO.BarView;
import com.mjoe.fruit_backend.entity.Fruit;
import com.mjoe.fruit_backend.mapper.FruitMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.security.PublicKey;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName : FruitContrller
 * @Description : FruitController
 * @Author : MJoeBoyae
 * @Date: 2021-06-23 16:43
 */
@Controller
@ResponseBody
@RequestMapping("/fruit")
public class FruitContrller {

    @Autowired
    FruitMapper fruitMapper;


    @GetMapping("/manage")
    public List fruitManage(){
        List fruits = fruitMapper.selectList(null);
        return fruits;
    }

    @PostMapping("/add")
    public Boolean fruitAdd(@RequestBody Fruit fruit){
        int insert = fruitMapper.insert(fruit);
        if (insert == 0){
            return false;
        }else return true;
    }

    @GetMapping("/manageById/{id}")
    public Fruit manageById(@PathVariable("id") int id){
        Fruit fruit = fruitMapper.selectById(id);
        return fruit;
    }

    @PostMapping("/update")
    public boolean fruitUpdate(@RequestBody Fruit fruit){

        int i = fruitMapper.updateById(fruit);
        if (i == 0){
            return false;
        }else return true;

    }

    @DeleteMapping("/deleteById/{id}")
    public boolean fruitDelete(@PathVariable("id") int id){
        int i = fruitMapper.deleteById(id);
        if (i == 0){
            return false;
        }else return true;
    }

    @GetMapping("/barView")
    public BarView varView(){
        List fruits = fruitMapper.selectList(null);
        BarView barView = new BarView();

        List names = new ArrayList<>();
        List numbers = new ArrayList<>();

        for (Fruit fruit : fruits) {
            names.add(fruit.getName());
            numbers.add(fruit.getNumber());
        }

        barView.setNames(names);
        barView.setNumbers(numbers);

        return barView;
    }

}

2.8 VO封装(view object)

前端使用Echarts.js绘制交互图,根据option选项中标签和数据的的格式,在后台封装成对应的VO对象

前端option选项:

option = {
    xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    yAxis: {
        type: 'value'
    },
    series: [{
        data: [120, 200, 150, 80, 70, 110, 130],
        type: 'bar'
    }]
};

图像和option中,可以得到:

  1. xAxis轴对应的数据是从xAxis中的data拿出来的,格式为List,对应mysql 表中的列: name
  2. 数据使从series的data中取出,格式也为List,对应与mysql表中的列:number

所以封装一个BarView对象,用于取出mysql表中的name和number,类型均为List

package com.mjoe.fruit_backend.VO;

import lombok.Data;

import java.util.List;

/**
 * @ClassName : BarView
 * @Description : bar对象
 * @Author : MJoeBoyae
 * @Date: 2021-06-23 18:19
 */
@Data
public class BarView {
    private List names;
    private List numbers;
}

在controller中定义特定的请求handler

    @GetMapping("/barView")
    public BarView varView(){
        List fruits = fruitMapper.selectList(null);
        BarView barView = new BarView();

        List names = new ArrayList<>();
        List numbers = new ArrayList<>();

        for (Fruit fruit : fruits) {
            names.add(fruit.getName());
            numbers.add(fruit.getNumber());
        }

        barView.setNames(names);
        barView.setNumbers(numbers);

        return barView;
    }

3 部署前端-后端到docker

3.1 部署后端

首先使用maven打包工具,将后端项目打包成jar包

编写Dockerfile文件用于构建镜像

FROM java:8

MAINTAINER MJoeBoyae

COPY *.jar app.jar

EXPOSE 8181

ENTRYPOINT ["java","-jar","app.jar"]

将Dockerfile文件和jar包上传到服务器(服务器默认已经安装好docker环境,并会使用)

cd到该目录下后,执行docker build命令

docker build -t fruidback:v1 .

使用docker run 运行该镜像,并使用宿主机8181端口映射容器内的8181端口

docker run -d --name fruidbackend -p 8181:8181 fruidback:v1

3.2 部署前端

基于nginx方式,部署vue项目

首先运行npm run build构建该vue项目,生成dist文件夹

编写Dockerfile文件,运用构建vue镜像

# 设置基础镜像,这里使用最新的nginx镜像,前面已经拉取过了
FROM nginx
# 定义作者 Edison
MAINTAINER MJoe

EXPOSE 80
# 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面
COPY dist/  /usr/share/nginx/html/

上传dist文件夹Dockerfile文件到服务端后,cd到该文件夹下,使用docker build命令构建镜像

docker build -t fruitvue .

使用docker run 运行该镜像,并使用宿主机4030端口映射容器内的80端口(底层使用了Nginx)

docker run -d --name fruidvue -p 4030:80 fruitvue:v1

4 测试

访问:http://82.156.203.105:4030/

tips:由于使用了history模式,所以不能直接在浏览器刷新页面(404)

相关