Springboot+vue实现基本增查demo,前端小白初学vue

Springboot+vue实现基本增查demo,前端小白初学vue

前言

由于本人之前是做后端的,因此本篇后端说明可能较少;主要还是记录下出次学习vue的心得。后端实现springboot+mybatis+mysql;前端vue.
功能介绍:1.报表数据的新增、查询
2.省市区联动

后台搭建

项目结构:
在这里插入图片描述

  1. pom文件引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>test</name>
    <description>Demo project for Spring Boot</description>

    <!--<properties>-->
        <!--<java.version>11</java.version>-->
    <!--</properties>-->

    <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>
        <!--  mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.1.6</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- logback -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  1. 配置文件
server:
  port: 8080

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/myvue?useUnicode=true&characterEncoding=UTF8&useSSL=true&serverTimezone=UTC
    driver-class-name: com.mysql.jdbc.Driver

#mybatis配置
mybatis:
  mapper-locations: classpath:mapping/*.xml
  type-aliases-package: com.example.test.domain

#日志配置
logging:
  config: classpath:logback.xml
  level:
    com.example.test: debug

  1. 其他demo不在贴代码,文章篇后会附上github地址
    。。。。。。.

前端搭建

1.首先创建一个空文件夹myvue(名字可随意)
在这里插入图片描述
2.win+R->cmd->进入项目目录依次执行命令:vue init webpack projectName、cd projectName、npm install、npm run dev如图所示,前提你已经安装node.js,没有就百度
在这里插入图片描述
3.打开浏览器输入:http://localhost:8080
在这里插入图片描述
4.IDE打开创建的项目–>myvue,我用的是HBulderX
在这里插入图片描述

前端开发记录

1.在项目根目录安装axios执行命令npm install axios,安装element ui 执行命令npm i element-ui -S
axios:解决跨域问题;
element ui:ui组件,地址:https://element.eleme.cn/#/zh-CN/
2.修改App.vue

<template>
  <div id="app">
    <el-row type="flex" justify="center">
      <el-col :xs="24" :sm="22" :md="20" :lg="20" :xl="18">
        <router-view/>
      </el-col>
    </el-row>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
      return {
      }
  },
  methods: {
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  margin: 0px;
  padding: 0px;
}
</style>

3.修改main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import elementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import 'element-ui/lib/theme-chalk/display.css'

Vue.use(elementUI)

import axios from 'axios'
Vue.prototype.axios = axios

import qs from 'qs';
Vue.prototype.qs = qs;

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

4.修改HelloWorld.vue

<template>
  <div>
    <!-- 查询form -->
      <el-form :model="searchForm" ref="searchForm" class="demo-form-inline"  label-width="100px" size="medium" >
        <el-row>
          <el-col :span="8">
            <el-form-item label="姓名" prop="personName">
              <el-input
                v-model="searchForm.personName"
                class="search_name"
                placeholder="输入姓名查询" style="width: 70%;" >
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="个人定位" prop="personAttr">
              <el-select v-model="searchForm.personAttr">
                <el-option label="技术型" value="技术型"></el-option>
                <el-option label="业务型" value="业务型"></el-option>
                <el-option label="营销型" value="营销型"></el-option>
                <el-option label="管理型" value="管理型"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="入职日期">
              <el-date-picker
                    v-model="searchForm.personDate"
                    align="right"
                    type="date"
                    value-format="yyyy-MM-dd HH:mm:ss"
                    placeholder="选择日期"
                    :picker-options="pickerOptions1">
              </el-date-picker>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="8">
            <el-form-item label="省" prop="province">
              <el-select @change="selectChanged" v-model="searchForm.province" placeholder="请选择">
                <el-option
                  v-for="item in provinces"
                  :key="item.cityNum"
                  :label="item.cityName"
                  :value="item.cityNum">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="市" prop="city">
              <el-select @change="selectChanged" v-model="searchForm.city" placeholder="请选择">
                <el-option
                  v-for="item in citys"
                  :key="item.cityNum"
                  :label="item.cityName"
                  :value="item.cityNum">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="区" prop="regional">
              <el-select v-model="searchForm.regional" placeholder="请选择">
                <el-option
                  v-for="item in regionals"
                  :key="item.cityNum"
                  :label="item.cityName"
                  :value="item.cityNum">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :push="16">
            <el-button
              type="info"
              @click="onSearch()"
              class="el-icon-search">查询
            </el-button>
            <el-button
              class="el-icon-refresh"
              type="info"
              @click="reset('searchForm')">重置
            </el-button>
            <el-button
              class="el-icon-circle-plus-outline"
              type="info"
              @click="dialogVisible = true">添加
            </el-button>
          </el-col>
        </el-row>
      </el-form>
<!-- 数据table -->
      <el-table
        :data="tableData"
        highlight-current-row
        border
        style="width: 100%">
        <el-table-column
          label="姓名">
          <template slot-scope="scope">
            <span>{{ scope.row.personName }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="性别">
          <template slot-scope="scope">
            <span>{{ scope.row.personSex }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="年龄">
          <template slot-scope="scope">
            <span>{{ scope.row.personAge }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="入职日期">
          <template slot-scope="scope">
            <i class="el-icon-time hidden-sm-and-down"></i>
            <span>{{ scope.row.personDate }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="个人规划">
          <template slot-scope="scope">
            <span>{{ scope.row.personPlan }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="个人定位">
          <template slot-scope="scope">
            <span>{{ scope.row.personAttr }}</span>
          </template>
        </el-table-column>
      </el-table>
<!-- 增加 -->
      <el-form :model="addForm" :rules="rules" ref="addForm" label-position="right" label-width="100px" class="demo-ruleForm" size="medium">
        <el-dialog
          title="基础信息"
          :append-to-body='true'
          :visible.sync="dialogVisible"
          width="70%"
          :before-close="handleClose">
          <el-input type="hidden" v-model="addForm.personName"/>
          <el-row>
            <el-col :span="8">
              <el-form-item label="姓名" prop="personName">
                <el-input v-model="addForm.personName"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="性别" prop="personSex">
                <el-select v-model="addForm.personSex" placeholder="请选择性别" style="width: 100%;">
                  <el-option label="男" value="男"></el-option>
                  <el-option label="女" value="女"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="年龄" prop="personAge">
                <el-input v-model="addForm.personAge"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="8">
              <el-form-item label="入职日期" prop="personDate">
                <el-date-picker type="datetime" placeholder="选择日期" v-model="addForm.personDate" value-format="yyyy-MM-dd HH:mm:ss" :picker-options="pickerOptions1" style="width: 100%;"></el-date-picker>
              </el-form-item>
            </el-col>
            <el-col span="8">
              <el-form-item label="邮箱" prop="personEmail">
                <el-input v-model="addForm.personEmail"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="联系方式" prop="personPhone">
                <el-input v-model="addForm.personPhone"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="个人规划" prop="personPlan">
                <el-input v-model="addForm.personPlan"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="自我定位" prop="personAttr">
                <el-checkbox-group v-model="addForm.personAttr">
                  <el-checkbox label="技术型" ></el-checkbox>
                  <el-checkbox label="业务型" ></el-checkbox>
                  <el-checkbox label="营销型" ></el-checkbox>
                  <el-checkbox label="管理型" ></el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="公司所在地址"  >
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="8">
              <el-form-item label="省">
                <el-select @change="selectChanged" v-model="addForm.province" placeholder="请选择">
                  <el-option
                    v-for="item in provinces"
                    :key="item.cityNum"
                    :label="item.cityName"
                    :value="item.cityNum">
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="市">
                <el-select @change="selectChanged" v-model="addForm.city" placeholder="请选择">
                  <el-option
                    v-for="item in citys"
                    :key="item.cityNum"
                    :label="item.cityName"
                    :value="item.cityNum">
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="区">
                <el-select v-model="addForm.regional" placeholder="请选择">
                  <el-option
                    v-for="item in regionals"
                    :key="item.cityNum"
                    :label="item.cityName"
                    :value="item.cityNum">
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item>
            <center>
              <el-button @click="cancel()" size="medium">关 闭</el-button>
              <el-button @click="addPerson('addForm')" type="primary" size="medium">保 存</el-button>
            </center>
          </el-form-item>
        </el-dialog>
      </el-form>
      <br>
      <!-- 翻页组件 -->
      <div class="pages">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="currentPage"
          :page-sizes="[5, 10, 15, 20]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total">
        </el-pagination>
      </div>
  </div>
</template>

<script>
    export default {
        data() {
            return {
                //添加form
                addForm: {
                    personName: '',//姓名
                    personSex: '',//性别
                    personAge: '',//年龄
                    personDate: '',//入职日期
                    personEmail: '',//邮箱
                    personPhone: '',//联系方式
                    personPlan: '',//个人规划
                    personAttr: [],//个人定位
                    province: '',//省
                    city: '',//市
                    regional: ''//区
                },
                rules: {
                    personName: [
                        { required: true, message: '请输入姓名', trigger: 'blur' },
                        { min: 2, max: 7, message: '长度在 2 到 7 个字符', trigger: 'blur' }
                    ],
                    personAge: [
                        { required: true, message: '请输入年龄', trigger: 'blur' },
                        { min: 1,max: 2, message: '长度大于 5 个字符', trigger: 'blur' }
                    ],
                },
                //时间选择
                pickerOptions1: {
                    disabledDate(time) {
                        return time.getTime() > Date.now();
                    }
                },
                //报表数据集合
                tableData: [],
                search: '',
                dialogVisible: false,
                pageSize: 5,
                currentPage: 1,
                total: 0,
                //查询form
                searchForm: {
                  personName: '',//用户姓名
                  personAttr: '',//个人定位
                  personDate: '',//入职时间
                  province: '',//省
                  city: '',//市
                  regional: ''//区
                },
                disablePage: false,
                provinces: [],//省
                citys: [],//市
                regionals: []//区
            }
        },
        methods: {
            handleSizeChange(val) {
              console.log(`每页 ${val} 条`);
              this.pageSize=val;
            },
            handleCurrentChange(val) {
                console.log(`当前页: ${val}`);
                this.currentPage=val;
                this.onSearch();
            },
            //增加页面关闭事件
            handleClose(done) {
                this.$confirm('确认关闭?')
                    .then(_ => {
                        done();
                    })
                    .catch(_ => {});
            },
            //增加页面取消事件
            cancel() {
                this.dialogVisible = false;
                this.emptyUserData();
            },
            emptyUserData(){
                this.addForm = {
                    personName: '',//姓名
                    personSex: '',//性别
                    personAge: '',//年龄
                    personDate: '',//入职日期
                    personEmail: '',//邮箱
                    personPhone: '',//联系方式
                    personPlan: '',//个人规划
                    personAttr: '',//个人定位
                    province: '',//省
                    city: '',//市
                    regional: ''//区
                }
            },
            //增加用户与服务器交互
            addPerson(addForm) {
               this.$refs[addForm].validate((valid) => {
                 if (valid) {
                   this.addPersonSubmit();
                   this.dialogVisible = false;
                 } else {
                   console.log('error submit!!');
                   return false;
                 }
               });
            },
            //form提交事件
            addPersonSubmit() {
              let postData = this.qs.stringify({
                  personName: this.addForm.personName,//姓名
                  personSex: this.addForm.personSex,//性别
                  personAge: this.addForm.personAge,//年龄
                  personDate: this.addForm.personDate,//入职日期
                  personEmail: this.addForm.personEmail,//邮箱
                  personPhone: this.addForm.personPhone,//联系方式
                  personPlan: this.addForm.personPlan,//个人规划
                  personAttr: this.addForm.personAttr.join(","),//个人定位
                  province: this.addForm.province,//省
                  city: this.addForm.city,//市
                  regional: this.addForm.regional
              });
              this.axios({
                  // headers: {
                  //     'Content-Type': 'application/json;charset=utf-8'
                  // },
                  method: 'post',
                  //http://127.0.0.1:8080
                  url:'/api/person/save',
                  data:postData
              }).then(response =>
              {
                  var code = response.data.code;
                  if(code == 200){
                    this.currentPage = 1;
                    this.$message({
                        type: 'success',
                        message: '已添加!'
                    });
                    this.onSearch();
                  }else{
                    this.$message({
                        type: 'error',
                        message: response.data.msg
                    });
                  }
              }).catch(error =>
              {
                  console.log(error);
              });

            },
            //获取所属城市
            selectCitys(cityParentNum,cityLeave) {
              //http://127.0.0.1:8080
                this.axios.get('/api/city/findList',{
                  params: {
                        cityParentNum: cityParentNum,
                        cityLeave: cityLeave,
                        }
                }).then(response =>
                {
                    console.log(response.data);
                    let data = response.data.data;
                    //判断城市等级,将对应的数据放到对应的集合,同时初始化子城市
                    if(cityLeave == '1'){
                      this.provinces = data;
                    }else if(cityLeave == '2'){
                      this.searchForm.city = '';
                      this.citys = data;
                      this.searchForm.regional = '';
                    }else{
                      this.searchForm.regional = '';
                      this.regionals = data;
                    }
                }).catch(error =>
                {
                    console.log(error);
                });
            },
            //省市区级联选中事件
            selectChanged(cityNum) {
              console.log(cityNum);
              var cityLeave = '2';
              console.log('error'+cityNum.length);
              if(cityNum.length > 4){
                cityLeave = '3';
              }
              this.selectCitys(cityNum,cityLeave);
            },
            //查询按钮
            onSearch() {
                let postData = this.qs.stringify({
                    personName: this.searchForm.personName,
                    personAttr: this.searchForm.personAttr,
                    personDate: this.searchForm.personDate,
                    province: this.searchForm.province,
                    city: this.searchForm.city,
                    regional: this.searchForm.regional,
                    pageNum: this.currentPage,
                    pageSize: this.pageSize,
                });
                console.log("postData:"+postData);
                this.axios({
                    method: 'post',
                    //http://127.0.0.1:8080
                    url: '/api/person/findList',
                    data: postData
                }).then(response =>
                {
                    console.log("person/findList:"+response);
                    this.tableData = response.data.rows;
                    this.disablePage = true;
                    this.total = response.data.total;
                }).catch(error =>
                {
                    console.log(error);
                });
            },

            //重置
            reset(searchForm) {
              this.$refs[searchForm].resetFields()
            }
        },
        created() {
            this.onSearch();
            this.selectCitys('0','1');
        },
    }
</script>
<style scoped>
  .search_name{
    width: 200px;
  }
  .pages{
    margin: 0px;
    padding: 0px;
    text-align: right;
  }
</style>

5.标签记录
el-row:element具有和bootstrap类似的栅格布局,分为24份,:span 进行划分。

		<el-row>
            <el-col :span="8">
              <el-form-item label="姓名" prop="personName">
                <el-input v-model="addForm.personName"></el-input>
              </el-form-item>
            </el-col>
         </el-row>

前后端交互

1.配置请求代理
在这里插入图片描述
修改proxyTable:

proxyTable: {
      '/api/*': {
         target:"http://localhost:8080/",
         chunkOrigins: true,// 允许跨域
        pathRewrite:{
              '^/api': '/api' // 路径重写,使用"/api"代替target.
         }
       }
    },

踩坑说明:
网上查了很多,大多是以下写法:

proxyTable: {
        '/api':{
        target:'http://xxxx.com',
        changeOrigin: true,
        pathRewrite: {
          '^/api': '/'
        }
      }
    }

但我的跨域代理请求并没有生效,改为上面那种写法就可以了。
2.发送get请求
get请求,后端接口不能使用@RequestBody标注参数。

			selectCitys(cityParentNum,cityLeave) {
              //http://127.0.0.1:8080
                this.axios.get('/api/city/findList',{
                  params: {
                        cityParentNum: cityParentNum,
                        cityLeave: cityLeave,
                        }
                }).then(response =>
                {
                    console.log(response.data);
                }).catch(error =>
                {
                    console.log(error);
                });
            },

3.发送post请求

			addPersonSubmit() {
              let postData = this.qs.stringify({
                  personName: this.addForm.personName,//姓名
                  ...
              });
              this.axios({
                  // headers: {
                  //     'Content-Type': 'application/json;charset=utf-8'
                  // },
                  method: 'post',
                  //http://127.0.0.1:8080
                  url:'/api/person/save',
                  data:postData
              }).then(response =>
              {
                  var code = response.data.code;
                  if(code == 200){
                    this.currentPage = 1;
                    this.$message({
                        type: 'success',
                        message: '已添加!'
                    });
                  }else{
                    this.$message({
                        type: 'error',
                        message: response.data.msg
                    });
                  }
              }).catch(error =>
              {
                  console.log(error);
              });

            },

在用post请求遇到点问题,无法传递json参数,后台用@RequestBody标准也不行。难…难…难…

项目地址
后端:https://github.com/wenbingege/test.git
前台:https://github.com/wenbingege/myvue.git
前台代码下载后可执行以下命令运行:npm install、npm run dev

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值