SpringBoot+Vue前后端分离简易开发

5 篇文章 0 订阅
3 篇文章 0 订阅

本文主要是学习于B站的Spring Boot+Vue前后端分离开发,技术主要采用Springboot + Vue + Element Ui,来完成基本的数据表格操作。

前端

界面



代码

main.js
import Vue from 'vue'
import './plugins/axios'
import App from './App.vue'
import router from './router'
import store from './store'
import './plugins/element.js'

//element-ui的全部组件
import ElementUI from 'element-ui'
//element-ui的css
import 'element-ui/lib/theme-chalk/index.css'
//使用elementUI
Vue.use(ElementUI)

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
router

index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import List from '../views/PageOne'
import Add from '../views/PageTwo'
import Update from '../views/PageThree.vue'
import PageFour from '../views/PageFour.vue'
import Index from '../views/index.vue'

Vue.use(VueRouter)

const routes = [{
    path: "/",
    name: "用户管理",
    component: Index,
    redirect: "/List",
    show: true,
    children: [{
        path: "/List",
        name: "查询用户",
        component: List
      },
      {
        path: "/Add",
        name: "添加用户",
        component: Add
      },
      {
        path: "/update",
        name: "修改用户",
        component: Update
      }
    ]
  },
  {
    path: "/authority",
    name: "权限管理",
    // 利用v-show隐藏此模块
    show: false
  }
]

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

export default router
App.vue
<template>
  <div>
    <router-view></router-view>
  </div>
</template>

<style>
.el-header {
  background-color: #b3c0d1;
  color: #333;
  line-height: 60px;
}

.el-aside {
  color: #333;
}
</style>

<script>
export default {
  data() {
    const item = {
      date: "2016-05-02",
      name: "王小虎",
      address: "上海市普陀区金沙江路 1518 弄"
    };
    return {
      tableData: Array(20).fill(item)
    };
  }
};
</script>
views

index.vue

<template>
  <div>
    <!-- 构建整个页面框架 -->
    <el-container style="height: 500px; border: 1px solid #eee">
      <!-- 构建左侧菜单 -->
      <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
        <!-- 左侧菜单内容,
        常用属性 :default-openeds默认展开的菜单,通过菜单的index直来关联
        default-active:默认选中的菜单,通过菜单的index值来关联-->
        <!-- <el-menu :default-openeds="['1', '3']">
          可展开的菜单,常用属性,index:菜单的下标,文本类型,不能是数值类型
          <el-submenu index="1">
            对应el-submenu的菜单名
            <template slot="title">
              i:设置菜单图标,通过class属性实则. 如:el-icon-menu,el-icon-message,el-icon-setting
              <i class="el-icon-message"></i>导航一
            </template>
            菜单的子节点,不可再展开,常用属性. index:菜单的下标,文本类型,不能是数值类型
            <el-menu-item index="1-1">选项1</el-menu-item>
            <el-menu-item index="1-2">选项2</el-menu-item>
            <el-submenu index="1-3">
              <template slot="title">
                <i class="el-icon-message"></i>选项3
              </template>
              <el-menu-item index="1-3-1">选项3-1</el-menu-item>
            </el-submenu>
          </el-submenu>
        </el-menu> -->

        <!-- menu 与 router的绑定:
          1.<el-menu>标签添加router属性
          2.在页面中添加<router-view>标签,它是一个容器,动态渲染你选择的router
          3.<el-menu-item>标签的index值就是要跳转的router
           -->
        <el-menu router :default-openeds="['0', '1']">
          <!-- Custom elements in iteration require 'v-bind:key' directives. -->
          <!-- 在el-menu-item 及el-submenu 标签上面,必须要加上 index属性,如果没有则报错。 
          :key属性为了避免点击菜单全部展开-->
          <el-submenu v-for="(item,index)  in $router.options.routes" :index="index + ''" :key="index + ''" v-show="item.show">
            <template slot="title"><i class="el-icon-message"></i>{{index}}-{{item.name}}</template>
            <el-menu-item v-for="(item2,index2) in item.children"
              :class="$route.path == item2.path ? 'isActive':''" :index="item2.path" v-bind:key="index + '-' + index2">
              <!-- <router-link :to="/路径"></router-link> -->
              {{item2.name}}
            </el-menu-item>
          </el-submenu>
        </el-menu>
      </el-aside>

      <el-container>
        <el-header style="text-align: right; font-size: 12px">
          <el-dropdown>
            <i class="el-icon-setting" style="margin-right: 15px"></i>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item>查看</el-dropdown-item>
              <el-dropdown-item>新增</el-dropdown-item>
              <el-dropdown-item>删除</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
          <span>王小虎</span>
        </el-header>

        <!-- 构建页面主体内容 -->
        <el-main>
          <!-- <el-table :data="tableData">
            <el-table-column prop="date" label="日期" width="140"></el-table-column>
            <el-table-column prop="name" label="姓名" width="120"></el-table-column>
            <el-table-column prop="address" label="地址"></el-table-column>
          </el-table>-->
          <router-view></router-view>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<style scoped>
.isActive:hover {
  color: aquamarine;
  font-weight: bold;
}
</style>

PageOne.vue-页面展示数据表

<template>
  <!-- 必须都套在一个div里 -->
  <div>
    <el-table :data="tableData" border style="width: 50%">
      <el-table-column fixed prop="id" label="编号" width="150"></el-table-column>
      <el-table-column prop="name" label="姓名" width="120"></el-table-column>
      <el-table-column prop="gender" label="性别" width="120"></el-table-column>
      <el-table-column prop="age" label="年龄" width="120"></el-table-column>
      <el-table-column fixed="right" label="操作" width="100">
        <template slot-scope="scope">
          <el-button @click="edit(scope.row)" type="text" size="small">修改</el-button>
          <el-button @click="deleteUserById(scope.row)" type="text" size="small">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <!-- :total 默认每页十条记录数,总记录数是100,就是十页
    :page-size: 每页数据量(即记录数),默认10-->
    <el-pagination
      background
      layout="prev, pager, next"
      :page-size="pageSize"
      :total="total"
      @current-change="page"
    ></el-pagination>
  </div>
</template>

<script>
export default {
  name: "PageOne",
  methods: {
    edit(row) {
      this.$router.push({
        path: '/update',
        query: {
          id: row.id
        }
      })
    },
    deleteUserById(row) {
      alert(row.id)
      const _this = this;
      axios
        .delete("http://localhost:8181/user/delete?id=" + row.id)
        .then(function(resp) {
          alert("成功");
          window.location.reload();
        }).catch(err => {
          alert("失败")
        });
    },
    page(currentPage) {
      const _this = this;
      axios
        .get("http://localhost:8181/user/findAll/" + (currentPage - 1) + "/6")
        .then(function(resp) {
          _this.tableData = resp.data.content;
          _this.pageSize = resp.data.size;
          _this.total = resp.data.totalElements;
        });
    }
  },
  data() {
    return {
      pageSize: 1,
      total: 17,
      tableData: []
    };
  },
  created() {
    const _this = this;
    axios.get("http://localhost:8181/user/findAll/0/5").then(function(resp) {
      _this.tableData = resp.data.content;
      _this.pageSize = resp.data.size;
      _this.total = resp.data.totalElements;
    });
  }
};
</script>

<style scoped>
</style>

PageTwo-页面添加功能

<template>
  <div>
    <!-- ref:不能少,相当于form表单的name属性 -->
    <el-form
      :model="ruleForm"
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="demo-ruleForm"
    >
      <el-form-item label="用户姓名" prop="name">
        <el-input v-model="ruleForm.name"></el-input>
      </el-form-item>
      <el-form-item label="用户性别" prop="gender">
        <el-input v-model="ruleForm.gender"></el-input>
      </el-form-item>
      <el-form-item label="用户年龄" prop="age">
        <el-input v-model="ruleForm.age"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
        <el-button @click="test()">Test</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  name: "PageTwo",
  data() {
    return {
      ruleForm: {
        name: "",
        age: "",
        gender: ""
        // region: "",
        // date1: "",
        // date2: "",
        // delivery: false,
        // type: [],
        // resource: "",
        // desc: ""
      },
      // 定义rules对象,在rules对象中设置表单各个选项的校验规则:
      // trigger:触发事件,如 blur失焦
      rules: {
        id: [
          { required: true, message: "请输入用户编号", trigger: "blur" },
          { min: 1, max: 5, message: "长度在 1 到 5 个字符", trigger: "blur" }
        ],
        name: [
          { required: true, message: "请输入用户名称", trigger: "blur" },
          { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" }
        ],
        region: [
          { required: true, message: "请选择活动区域", trigger: "change" }
        ]
      }
    };
  },
  methods: {
    test() {
      // 不能拼接 "内容" +,会变成Object
      console.log(this.ruleForm);
    },
    submitForm(formName) {
      const _this = this;
      this.$refs[formName].validate(valid => {
        if (valid) {
          // axios.post('http://localhost:8181/user/add', this.ruleForm)
          //   .then(function (response) {
          //     console.log(response);
          //   })
          axios({
            url: "http://localhost:8181/user/add",
            params: {
              name: this.ruleForm.name,
              age: this.ruleForm.age,
              gender: this.ruleForm.gender
            },
            method: "post"
          }).then(res => {
            _this.$alert("《" + _this.ruleForm.name + "》添加成功", "消息", {
              confirmButtonText: "确定",
              callback: action => {
                _this.$router.push("/List");
              }
            });
          });
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    }
  }
};
</script>

PageThree-页面修改功能

<template>
  <div>
    <!-- ref:不能少,相当于form表单的name属性 -->
    <el-form
      :model="ruleForm"
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="demo-ruleForm"
    >
      <el-form-item label="用户编号">
        <el-input v-model="ruleForm.id"></el-input>
      </el-form-item>
      <el-form-item label="用户姓名" prop="name">
        <el-input v-model="ruleForm.name"></el-input>
      </el-form-item>
      <el-form-item label="用户性别" prop="gender">
        <el-input v-model="ruleForm.gender"></el-input>
      </el-form-item>
      <el-form-item label="用户年龄" prop="age">
        <el-input v-model="ruleForm.age"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">修改</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  name: "PageThree",
  data() {
    return {
      ruleForm: {
        id: "",
        name: "",
        age: "",
        gender: ""
        // region: "",
        // date1: "",
        // date2: "",
        // delivery: false,
        // type: [],
        // resource: "",
        // desc: ""
      },
      // 定义rules对象,在rules对象中设置表单各个选项的校验规则:
      // trigger:触发事件,如 blur失焦
      rules: {
        id: [
          { required: true, message: "请输入用户编号", trigger: "blur" },
          { min: 1, max: 5, message: "长度在 1 到 5 个字符", trigger: "blur" }
        ],
        name: [
          { required: true, message: "请输入用户名称", trigger: "blur" },
          { min: 2, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" }
        ],
        region: [
          { required: true, message: "请选择活动区域", trigger: "change" }
        ]
      }
    };
  },
  methods: {
    submitForm(formName) {
      const _this = this;
      this.$refs[formName].validate(valid => {
        if (valid) {
          // axios.post('http://localhost:8181/user/add', this.ruleForm)
          //   .then(function (response) {
          //     console.log(response);
          //   })
          axios({
            url: "http://localhost:8181/user/update",
            params: {
              id: this.ruleForm.id,
              name: this.ruleForm.name,
              age: this.ruleForm.age,
              gender: this.ruleForm.gender
            },
            method: "put"
          }).then(res => {
            _this.$alert("《" + _this.ruleForm.name + "》修改成功", "消息", {
              confirmButtonText: "确定",
              callback: action => {
                _this.$router.push("/List");
              }
            });
          });
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    }
  },
  created() {
    const _this = this;
    alert(this.$route.query.id);
    axios
      .get("http://localhost:8181/user/findById/" + this.$route.query.id)
      .then(function(response) {
        _this.ruleForm = response.data;
      });
  }
};
</script>

后端

UserInfo.java

package cn.blue.demo.entity;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * @author Blue
 * @date 2020/2/11
 **/
@Data
@Entity
public class UserInfo {
    /**
     * 设置自增
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String gender;

    private Integer age;
}

UserInfoRepository.java

package cn.blue.demo.repository;

import cn.blue.demo.entity.UserInfo;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * @author Blue
 * @date 2020/2/11
 **/
public interface UserInfoRepository extends JpaRepository<UserInfo, Integer> {
    //右键 goto,创建测试类
}

UserInfoController.java

package cn.blue.demo.controller;

import cn.blue.demo.entity.UserInfo;
import cn.blue.demo.repository.UserInfoRepository;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author Blue
 * @date 2020/2/11
 **/
@RestController
@RequestMapping("/user")
public class UserInfoController {
    @Autowired
    private UserInfoRepository userInfoRepository;

    /**
     *
     * @param page 当前页数
     * @param size 每页显示数据量
     * @return 用户列表信息;倘若让其直接通过访问user就请求此方法就是404
     */
    @GetMapping("/findAll/{page}/{size}")
    public Page<UserInfo> findAll(@PathVariable("page") Integer page, @PathVariable("size") Integer size) {
        PageRequest pageRequest = PageRequest.of(page, size);
        return userInfoRepository.findAll(pageRequest);
    }

    @PostMapping("/add")
    @ResponseBody
    public String add(UserInfo userInfo) {
        UserInfo user = userInfoRepository.save(userInfo);
        if (user != null) {
            return "success";
        } else {
            return "error";
        }
    }

    @GetMapping("findById/{id}")
    public UserInfo findById(@PathVariable("id") Integer id) {
        return userInfoRepository.findById(id).get();
    }

    @PutMapping("/update")
    public String update(UserInfo userInfo) {
        if(userInfoRepository.save(userInfo) != null) {
            return "success";
        } else{
            return "error";
        }
    }

    @DeleteMapping("/delete")
    public String delete(@RequestParam("id") Integer id) {
        try {
            UserInfo userInfo = new UserInfo();
            userInfo.setId(id);
            userInfoRepository.delete(userInfo);
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            return "error";
        }
    }
}

配置类CorsConfig: 解决跨域问题

package cn.blue.demo.config;

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

/**
 * @author Blue
 * @date 2020/2/11
 * 解决跨域的问题
 **/
@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }
}

pom.xml

<dependencies>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <scope>runtime</scope>
      <optional>true</optional>
  </dependency>
  <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
  </dependency>
  <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
  </dependency>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      <exclusions>
          <exclusion>
              <groupId>org.junit.vintage</groupId>
              <artifactId>junit-vintage-engine</artifactId>
          </exclusion>
      </exclusions>
  </dependency>
</dependencies>

My Blog: https://coderblue.cn/
Github:https://github.com/onecoderly
My Project:https://coderblue.cn/project/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值