# 前言
主要通過后端 Spring Boot 技術(shù)和前端 Vue 技術(shù)來簡單開發(fā)一個demo碍论,實(shí)現(xiàn)增刪改查兼犯、分頁功能以及了解Springboot搭配vue完成前后端分離項目的開發(fā)流程。
## 開發(fā)棧
### 前端
? - 開發(fā)工具:vscode
? - 開發(fā)框架:vue + axios
? - 包管理工具: npm
? - 打包工具:webpack
### 后端
? - 開發(fā)工具:IDEA
? - 開發(fā)框架:Springboot + mybatis
? - 打包工具:maven
? - 數(shù)據(jù)庫:
## 后端開發(fā)環(huán)境搭建
1、File->New->Project...

2端盆、選擇 Spring Initializr ,然后選擇默認(rèn)的 url 點(diǎn)擊next

3费封、勾選Spring Web焕妙、SQL模板,next

4孝偎、點(diǎn)擊finish访敌,搭建完成

## 后端開發(fā)過程
### 后端框架
開發(fā)過程從底層數(shù)據(jù)庫開始往上編程

1、更新pom.xml如下:
先導(dǎo)入項目相應(yīng)的依賴:數(shù)據(jù)庫:jdbc衣盾、mysql dever;網(wǎng)頁:web
```
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
? ? <modelVersion>4.0.0</modelVersion>
? ? <groupId>com.example</groupId>
? ? <artifactId>demo</artifactId>
? ? <version>0.0.1-SNAPSHOT</version>
? ? <name>springboot-mybatis</name>
? ? <!-- Spring Boot 啟動父依賴 -->
? ? <parent>
? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? <artifactId>spring-boot-starter-parent</artifactId>
? ? ? ? <version>2.1.3.RELEASE</version>
? ? </parent>
? ? <properties>
? ? ? ? <mybatis-spring-boot>1.2.0</mybatis-spring-boot>
? ? ? ? <mysql-connector>5.1.39</mysql-connector>
? ? </properties>
? ? <dependencies>
? ? ? ? <!-- Spring Boot Web 依賴 -->
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? <artifactId>spring-boot-starter-web</artifactId>
? ? ? ? </dependency>
? ? ? ? <!-- Spring Boot Test 依賴 -->
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? <artifactId>spring-boot-starter-test</artifactId>
? ? ? ? ? ? <scope>test</scope>
? ? ? ? </dependency>
? ? ? ? <!-- Spring Boot Mybatis 依賴 -->
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.mybatis.spring.boot</groupId>
? ? ? ? ? ? <artifactId>mybatis-spring-boot-starter</artifactId>
? ? ? ? ? ? <version>${mybatis-spring-boot}</version>
? ? ? ? </dependency>
? ? ? ? <!-- MySQL 連接驅(qū)動依賴 -->
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>mysql</groupId>
? ? ? ? ? ? <artifactId>mysql-connector-java</artifactId>
? ? ? ? ? ? <version>${mysql-connector}</version>
? ? ? ? </dependency>
? ? ? ? <!-- Junit -->
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>junit</groupId>
? ? ? ? ? ? <artifactId>junit</artifactId>
? ? ? ? ? ? <version>4.12</version>
? ? ? ? </dependency>
? ? </dependencies>
</project>
```
2寺旺、先在properties文件中添加數(shù)據(jù)庫鏈接,更新demo\src\main\resources\application.properties
```
## 數(shù)據(jù)源配置
##//jdbc.mysql://是指JDBC連接方式, JDBC就是用于在Java語言編程中與數(shù)據(jù)庫連接的API;localhost:是指你的本機(jī)IP地址Q势决,在本地等同于127.0.0.1.3306 :數(shù)據(jù)庫所使用的端口號默認(rèn)3306;study:就是你要連接的數(shù)據(jù)庫的地址(后面如果為jdbc阻塑、 test則同理)JDBC代表Java數(shù)據(jù)庫連接Q (Java Database Connectivity)
spring.datasource.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
## Mybatis 配置
mybatis.typeAliasesPackage=org.spring.springboot.domain
mybatis.mapperLocations=classpath:mapper/*.xml
## 端口
server.port=8081
```
3、根據(jù)數(shù)據(jù)庫中的表格形式建立相應(yīng)實(shí)體類果复,新建 demo\src\main\java\com\example\demo\entity\User.java
```
package com.example.entity;
import lombok.Data;
@Data//@Data注解的主要作用是提高代碼的簡潔陈莽,使用這個注解可以省去實(shí)體類中大量的get()、 set()、 toString()等方法走搁。
public class User {
? ? private int userId;
? ? private String userDate;
? ? private String userName;
? ? private String userAddress;
? ? //省略get() and set()
}
```
4独柑、實(shí)體類寫完后,創(chuàng)建mapper文件夾(dao層(也叫mapper層或持久層)mapper層是操作數(shù)據(jù)庫的一層私植。想要訪問數(shù)據(jù)庫并且操作忌栅,只能通過mapper層向數(shù)據(jù)庫發(fā)送sql語句,將這些通過接口傳給service層曲稼,對數(shù)據(jù)庫進(jìn)行操作索绪。新建demo\src\main\java\com\example\demo\mapper\UserMapper.java
```
package com.example.mapper;
import com.example.entity.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper//@Mapper注解用于標(biāo)識個接口是mybatis的Mapper接口, Spring會自動掃描這個注解并將其實(shí)例化為一個Mapper對象贫悄,從而可以在代碼中直接使用Mapper接口中定義的方法來操作數(shù)據(jù)庫瑞驱。
public interface UserMapper {
? ? public List<User> findUserByName(String userName);
? ? public List<User> ListUser();//這里L(fēng)istUser是定義的方法
? ? public List<User> queryPage(Integer startRows);
? ? public int getRowCount();
? ? public int insertUser(User user);
? ? public int delete(int userId);
? ? public int Update(User user);
}
```
5、新建demo\src\main\resources\mapper\UserMapper.xml
```
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE mapper PUBLIC
? ? ? ? "-//mybatis.org//DTD com.example.Mapper 3.0//EN"
? ? ? ? "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
? ? <resultMap id="result" type="com.example.entity.User">
? ? ? ? <result property="userId" column="userId" />
? ? ? ? <result property="userDate" column="userDate" />
? ? ? ? <result property="userName" column="userName" />
? ? ? ? <result property="userAddress" column="userAddress"/>
? ? </resultMap>
? ? <select id="ListUser" resultMap="result">
? ? ? ? SELECT * FROM user
? ? </select>
? ? <select id="findUserByName" resultMap="result" parameterType="String">
? ? ? ? SELECT * FROM user
? ? ? ? where userName like concat(concat('%',#{userName}),'%')
? ? ? ? order by userId desc
? ? </select>
? ? <select id="queryPage" resultMap="result"? parameterType="Integer">
? ? ? ? select * from user
? ? ? ? order by userId desc
? ? ? ? ? ? limit #{startRows},5
? ? </select>
? ? <select id="getRowCount" resultType="Integer">
? ? ? ? select count(*) from user
? ? </select>
? ? <insert id="insertUser" parameterType="com.example.entity.User">
? ? ? ? INSERT INTO user
? ? ? ? (
? ? ? ? ? ? userId,userDate,userName,userAddress
? ? ? ? )
? ? ? ? VALUES (
? ? ? ? ? ? ? ? ? #{userId},
? ? ? ? ? ? ? ? ? #{userDate, jdbcType=VARCHAR},
? ? ? ? ? ? ? ? ? #{userName, jdbcType=VARCHAR},
? ? ? ? ? ? ? ? ? #{userAddress, jdbcType=VARCHAR}
? ? ? ? ? ? ? )
? ? </insert>
? ? <delete id="delete" parameterType="int">
? ? ? ? delete from user where userId=#{userId}
? ? </delete>
? ? <update id="Update" parameterType="com.example.entity.User">
? ? ? ? update user
? ? ? ? set user.userDate=#{userDate},user.userName=#{userName},user.userAddress=#{userAddress}
? ? ? ? where user.userId=#{userId}
? ? </update>
</mapper>
```
6窄坦、新建demo\src\main\java\com\example\demo\service\UserService.java
```
package com.example.service;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Service;
import java.util.List;
@Service//@Service注解用于告訴Spring容器唤反,被注解的類是一個服務(wù)類。它是Spring框架中的一個組件掃描注解嫡丙,用于自動掃描并創(chuàng)建實(shí)例拴袭,以便在應(yīng)用程序中使用。
public class UserService {
? ? @Autowired//在需要進(jìn)行依賴注入的類中曙博, 使用 @Autowired 注解來標(biāo)記需要注入的成員變量拥刻、構(gòu)造函數(shù)或者方法。
? ? private UserMapper userMapper;
? ? public List<User> findByName(String userName) {
? ? ? ? return userMapper.findUserByName(userName);
? ? }//findByName是用于相應(yīng)前端的方法父泳,findUserByName是用于調(diào)用數(shù)據(jù)庫sql語句的方法
? ? public List<User> queryPage(Integer startRows) {
? ? ? ? return userMapper.queryPage(startRows);
? ? }
? ? public int getRowCount() {
? ? ? ? return userMapper.getRowCount();
? ? }
? ? public User insertUser(User user) {
? ? ? ? userMapper.insertUser(user);
? ? ? ? return user;
? ? }
? ? public List<User> ListUser(){
? ? ? ? return userMapper.ListUser();
? ? }
? ? public int Update(User user){
? ? ? ? return userMapper.Update(user);
? ? }
? ? public int delete(int userId){
? ? ? ? return userMapper.delete(userId);
? ? }
}
```
7般哼、新建demo\src\main\java\com\example\demo\controller\UserCtrl.java
```
package com.example.controller;
import com.example.entity.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@EnableAutoConfiguration//@EnableAutoConfiguration 注解是用來啟動 Spring 應(yīng)用程序上下文時進(jìn)行自動配置,它會嘗試猜測和配置項目可能需要的 Bean
@RestController@//具體來說惠窄,@RestController注解用于標(biāo)記一個類蒸眠,表明該類是一個控制器,并且其下的方法都將返回數(shù)據(jù)作為響應(yīng)杆融。使用@RestController注解時楞卡,不再需要在方法上添加@ResponseBody注解,因為@RestController默認(rèn)將所有方法的返回值自動序列化為響應(yīng)體脾歇。
public class UserCtrl {
? ? @Autowired
? ? private UserService userservice;
? ? @RequestMapping(value = "@/delete", method = RequestMethod.POST)
? ? public Integer delete(Integer userId) {
? ? ? ? System.out.println(userId);
? ? ? ? int result = userservice.delete(userId);
? ? ? ? return result;
? ? }
? ? @RequestMapping(value = "@/update", method = RequestMethod.POST)
? ? @ResponseBody
? ? public String update(User user) {
? ? ? ? int result = userservice.Update(user);
? ? ? ? if (result >= 1) {
? ? ? ? ? ? return "修改成功";
? ? ? ? } else {
? ? ? ? ? ? return "修改失敗";
? ? ? ? }
? ? }
? ? @RequestMapping(value = "@/insert", method = RequestMethod.POST)
? ? public User insert(User user) {
? ? ? ? return userservice.insertUser(user);
? ? }
? ? @RequestMapping("@/ListUser")
? ? @ResponseBody
? ? public List<User> ListUser() {
? ? ? ? return userservice.ListUser();
? ? }
? ? @RequestMapping("@/ListByName")
? ? @ResponseBody
? ? public List<User> ListUserByName(String userName) {
? ? ? ? return userservice.findByName(userName);
? ? }
? ? /**
? ? * 分頁
? ? * @return
? ? */
? ? @RequestMapping(value="@/page")
? ? @ResponseBody
? ? public List<User> page(Integer page){
? ? ? ? int pageNow = page == null ? 1 : page;
? ? ? ? int pageSize = 5;
? ? ? ? int startRows = pageSize*(pageNow-1);
? ? ? ? List<User> list = userservice.queryPage(startRows);
? ? ? ? return list;
? ? }
? ? /**
? ? * rows
? ? * @return
? ? */
? ? @RequestMapping(value="@/rows")
? ? @ResponseBody
? ? public int rows(){
? ? ? ? return userservice.getRowCount();
? ? }
}
```
8蒋腮、啟動MySQL數(shù)據(jù)庫,新建或執(zhí)行如下表:

9藕各、執(zhí)行sql文件
```
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`? (
? `userId` int(20) NOT NULL AUTO_INCREMENT,
? `userDate` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
? `userName` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
? `userAddress` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
? PRIMARY KEY (`userId`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 71 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (15, '2019-09-29T03:17:12.000Z', '王老三', '上海市普陀區(qū)金沙江路 1515 弄');
INSERT INTO `user` VALUES (16, '2019-09-29T03:27:05.000Z', '張小四', '上海市普陀區(qū)金沙江路 1514 弄');
INSERT INTO `user` VALUES (17, '2019-09-29T03:30:04.000Z', '王老五', '上海市普陀區(qū)金沙江路 1513弄');
INSERT INTO `user` VALUES (18, '2019-09-29T03:33:15.000Z', '小六子', '上海市普陀區(qū)金沙江路 1512弄');
INSERT INTO `user` VALUES (20, '2019-09-29T03:33:15.000Z', '王老八', '上海市普陀區(qū)金沙江路 1512弄');
INSERT INTO `user` VALUES (21, '2019-09-29T05:42:52.000Z', '王大拿', '上海市普陀區(qū)金沙江路 1511弄');
INSERT INTO `user` VALUES (22, '2019-09-29T05:43:50.000Z', '小九九', '上海市普陀區(qū)金沙江路 1510弄');
INSERT INTO `user` VALUES (23, '2019-09-29T05:43:50.000Z', '劉詩詩', '上海市普陀區(qū)金沙江路 1499弄');
INSERT INTO `user` VALUES (24, '2019-09-29T05:46:07.000Z', '扎昂四四', '上海市大灣區(qū)科技路');
INSERT INTO `user` VALUES (25, '2019-09-29T05:46:07.000Z', '扎昂四四新東方', '上海市大灣區(qū)科技路2001號');
INSERT INTO `user` VALUES (26, '2019-09-29T05:46:07.000Z', '王小虎', '上海市大灣區(qū)科技路2002號');
INSERT INTO `user` VALUES (27, '2019-09-29T05:46:07.000Z', '抽拉吧唧', '上海市大灣區(qū)科技路2003號');
INSERT INTO `user` VALUES (28, '2019-09-29T05:46:07.000Z', '年啦編輯', '上海市大灣區(qū)科技路2004號');
INSERT INTO `user` VALUES (29, '2019-09-29T05:46:07.000Z', '你多少', '上海市普陀區(qū)金沙江路 1211弄');
INSERT INTO `user` VALUES (30, '2019-09-29T05:46:07.000Z', '反發(fā)達(dá)', '上海市普陀區(qū)金沙江路 1212弄');
INSERT INTO `user` VALUES (31, '2019-09-29T05:51:20.000Z', '發(fā)官方', '上海市普陀區(qū)金沙江路 1213弄');
INSERT INTO `user` VALUES (32, '2019-09-29T05:51:20.000Z', '方還有', '上海市普陀區(qū)金沙江路 1214弄');
INSERT INTO `user` VALUES (33, '2019-09-29T05:51:20.000Z', '過不分', '上海市普陀區(qū)金沙江路 1498弄');
INSERT INTO `user` VALUES (34, '2019-09-29T05:51:20.000Z', '菜市場', '上海市普陀區(qū)金沙江路 1497弄');
INSERT INTO `user` VALUES (35, '2019-09-29T05:51:20.000Z', '權(quán)威的', '上海市普陀區(qū)金沙江路 1496弄');
INSERT INTO `user` VALUES (36, '2019-09-29T05:55:09.000Z', '岡反對的', '上海市大灣區(qū)科技路2001號');
INSERT INTO `user` VALUES (37, '2019-09-29T05:55:09.000Z', '岡反對', '上海市大灣區(qū)科技路2003號');
INSERT INTO `user` VALUES (38, '2019-09-29T05:55:09.000Z', '偶哦里面', '上海市大灣區(qū)科技路2004號');
INSERT INTO `user` VALUES (39, '2019-09-29T05:55:09.000Z', '偶哦韓大蘇打', '上海市大灣區(qū)科技路2005號');
INSERT INTO `user` VALUES (40, '2019-09-29T05:55:09.000Z', '偶哦勻', '上海市大灣區(qū)科技路2006號');
INSERT INTO `user` VALUES (41, '2019-09-29T05:55:09.000Z', '敢哦勻', '上海市大灣區(qū)科技路2006號');
INSERT INTO `user` VALUES (42, '2019-09-29T05:55:09.000Z', '敢孩', '上海市大灣區(qū)科技路2006號');
INSERT INTO `user` VALUES (43, '2019-09-29T05:55:09.000Z', '敢女孩', '上海市大灣區(qū)科技路2007號');
INSERT INTO `user` VALUES (45, '2019-09-29T05:55:09.000Z', '工行行', '上海市大灣區(qū)科技路2008號');
INSERT INTO `user` VALUES (46, '2019-09-29T05:55:09.000Z', '家好嗎', '上海市大灣區(qū)科技路2008號');
INSERT INTO `user` VALUES (47, '2019-09-29T05:55:09.000Z', '的程度', '上海市大灣區(qū)科技路2009號');
INSERT INTO `user` VALUES (48, '2019-09-29T05:55:09.000Z', '稱得上', '上海市大灣區(qū)科技路2009號');
INSERT INTO `user` VALUES (49, '2019-09-29T05:55:09.000Z', '韓國和', '上海市大灣區(qū)科技路2010號');
INSERT INTO `user` VALUES (50, '2019-09-29T05:55:09.000Z', '韓好', '上海市大灣區(qū)科技路2010號');
INSERT INTO `user` VALUES (51, '2019-09-29T05:55:09.000Z', '韓吧', '上海市大灣區(qū)科技路2011號');
INSERT INTO `user` VALUES (52, '2019-09-29T05:55:09.000Z', '韓吧吧', '上海市大灣區(qū)科技路2012號');
INSERT INTO `user` VALUES (53, '2019-09-29T05:55:09.000Z', '長度是', '上海市大灣區(qū)科技路2013號');
INSERT INTO `user` VALUES (54, '2019-09-29T05:55:09.000Z', '比如合', '上海市大灣區(qū)科技路2014號');
INSERT INTO `user` VALUES (55, '2019-09-29T05:55:09.000Z', '如合境', '上海市大灣區(qū)科技路2015號');
INSERT INTO `user` VALUES (56, '2019-09-29T05:55:09.000Z', '如合國', '上海市大灣區(qū)科技路2016號');
INSERT INTO `user` VALUES (57, '2019-09-29T05:55:09.000Z', '如更好', '上海市大灣區(qū)科技路2017號');
INSERT INTO `user` VALUES (58, '2019-09-29T05:55:09.000Z', '如更法', '上海市大灣區(qū)科技路2018號');
INSERT INTO `user` VALUES (59, '2019-09-29T05:55:09.000Z', '反對', '上海市大灣區(qū)科技路2019號');
INSERT INTO `user` VALUES (60, '2019-09-29T05:55:09.000Z', '如國部', '上海市大灣區(qū)科技路2019號');
INSERT INTO `user` VALUES (61, '2019-09-29T06:04:15.000Z', '奇熱網(wǎng)', '上海市普陀區(qū)金沙江路 1496弄');
INSERT INTO `user` VALUES (62, '2019-09-29T06:04:33.000Z', '反對法', '上海市普陀區(qū)金沙江路 1495弄');
INSERT INTO `user` VALUES (63, '2019-09-29T06:04:33.000Z', '的風(fēng)格', '上海市普陀區(qū)金沙江路 1494弄');
INSERT INTO `user` VALUES (64, '2019-09-29T06:04:33.000Z', '廣泛同', '上海市大灣區(qū)科技路2020號');
INSERT INTO `user` VALUES (65, '2019-09-10T06:04:33.000Z', '但仍然', '上海市普陀區(qū)金沙江路 1493弄');
INSERT INTO `user` VALUES (66, '2019-09-29T06:10:28.000Z', 'vdfv', '放到電飯鍋的');
INSERT INTO `user` VALUES (67, '2019-09-14T16:00:00.000Z', '朱老六', '上海市高新區(qū)上海中心');
INSERT INTO `user` VALUES (69, '2019-09-10T16:00:00.000Z', '是的', ' 學(xué)生的三十四分');
INSERT INTO `user` VALUES (70, '2019-09-29T07:51:44.000Z', '張小子', '上海市浦東區(qū)1234號');
SET FOREIGN_KEY_CHECKS = 1;
```
9池摧、后端就寫完了,頁面展示如下

10激况、run 'DemoApplication'啟動項目作彤,控制臺沒報錯就用瀏覽器測試一下膘魄,在瀏覽器中輸入http://localhost:8081/page?page=3 如果能出現(xiàn)如下字符串就??,已安裝postman的可以每個方法都試一下:
## 前端開發(fā)環(huán)境搭建
1竭讳、win+R->cmd->進(jìn)入項目目錄依次執(zhí)行命令:vue init webpack projectName创葡、cd projectName、npm install代咸、npm run dev如圖所示:

2蹈丸、打開瀏覽器輸入:http://localhost:8080,效果如圖:

3呐芥、Vue-cli項目結(jié)構(gòu)如圖:

## 前端開發(fā)過程
### 創(chuàng)建前端項目后,項目首先從根組件App.vue開始執(zhí)行奋岁,
- 在App.vue中的<template>...</template>使用 <router-view/> 來顯示當(dāng)前路由匹配到的組件思瘟。
- 在你的 main.js 文件中創(chuàng)建并掛載 Vue 應(yīng)用,同時使用你配置的路由闻伶。
- 在router文件夾創(chuàng)建一個 router.js 文件滨攻,用于配置路由。
1蓝翰、在項目根目錄安裝axios執(zhí)行命令npm install axios光绕,安裝element ui 執(zhí)行命令npm i element-ui -S 2、更新vue01\src\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畜份、更新vue01\src\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诞帐、更新vue01\src\components\HelloWorld.vue
```
<template>##template表示頁面上所展示的功能
? <div>
? ? ? <el-form :inline="true" class="demo-form-inline">
? ? ? ? ? <el-form-item>
? ? ? ? ? ? <el-input
? ? ? ? ? ? ? v-model="search"
? ? ? ? ? ? ? class="search_name"
? ? ? ? ? ? ? size="mini"
? ? ? ? ? ? ? placeholder="輸入姓名查詢">
? ? ? ? ? ? </el-input>
? ? ? ? ? </el-form-item>
? ? ? ? ? <el-form-item>
? ? ? ? ? ? <el-button
? ? ? ? ? ? ? type="text"
? ? ? ? ? ? ? @click="onSearch()"
? ? ? ? ? ? ? class="el-icon-search">查詢
? ? ? ? ? ? </el-button>
? ? ? ? ? </el-form-item>
? ? ? ? ? <el-form-item>
? ? ? ? ? ? <el-button
? ? ? ? ? ? ? class="el-icon-refresh"
? ? ? ? ? ? ? type="text"
? ? ? ? ? ? ? @click="refreshData">刷新
? ? ? ? ? ? </el-button>
? ? ? ? ? </el-form-item>
? ? ? ? ? <el-form-item>
? ? ? ? ? ? <el-button
? ? ? ? ? ? ? class="el-icon-circle-plus-outline"
? ? ? ? ? ? ? type="text"
? ? ? ? ? ? ? @click="dialogVisible = true">添加
? ? ? ? ? ? </el-button>
? ? ? ? ? </el-form-item>
? ? ? </el-form>
? ? ? <el-table
? ? ? ? :data="tableData"
? ? ? ? highlight-current-row
? ? ? ? border
? ? ? ? style="width: 100%">
? ? ? ? <el-table-column
? ? ? ? ? label="編號">
? ? ? ? ? <template slot-scope="scope">
? ? ? ? ? ? <span>{{ scope.row.userId }}</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.userDate }}</span>
? ? ? ? ? </template>
? ? ? ? </el-table-column>
? ? ? ? <el-table-column
? ? ? ? ? label="姓名">
? ? ? ? ? <template slot-scope="scope">
? ? ? ? ? ? <el-popover trigger="hover" placement="right">
? ? ? ? ? ? ? <p>姓名: {{ scope.row.userName }}</p>
? ? ? ? ? ? ? <p>住址: {{ scope.row.userAddress }}</p>
? ? ? ? ? ? ? <p>日期:{{ scope.row.userDate }}</p>
? ? ? ? ? ? ? <div slot="reference" class="name-wrapper">
? ? ? ? ? ? ? ? <el-button type="text">{{ scope.row.userName }}</el-button>
? ? ? ? ? ? ? </div>
? ? ? ? ? ? </el-popover>
? ? ? ? ? </template>
? ? ? ? </el-table-column>
? ? ? ? <el-table-column
? ? ? ? ? label="住址">
? ? ? ? ? <template slot-scope="scope">
? ? ? ? ? ? <span>{{ scope.row.userAddress }}</span>
? ? ? ? ? </template>
? ? ? ? </el-table-column>
? ? ? ? <el-table-column
? ? ? ? ? label="操作"
? ? ? ? ? fixed="right"
? ? ? ? ? width="200">
? ? ? ? ? <template slot-scope="scope">
? ? ? ? ? ? <el-button
? ? ? ? ? ? ? size="mini"
? ? ? ? ? ? ? icon="el-icon-edit"
? ? ? ? ? ? ? @click="handleEdit(scope.$index, scope.row)">編輯
? ? ? ? ? ? </el-button>
? ? ? ? ? ? <el-button
? ? ? ? ? ? ? size="mini"
? ? ? ? ? ? ? type="danger"
? ? ? ? ? ? ? icon="el-icon-delete"
? ? ? ? ? ? ? @click="handleDelete(scope.$index, scope.row)">刪除
? ? ? ? ? ? </el-button>
? ? ? ? ? </template>
? ? ? ? </el-table-column>
? ? ? </el-table>
? ? ? <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="70px" class="demo-ruleForm" size="medium">
? ? ? ? <el-dialog
? ? ? ? ? title="添加"
? ? ? ? ? :append-to-body='true'
? ? ? ? ? :visible.sync="dialogVisible"
? ? ? ? ? width="80%"
? ? ? ? ? :before-close="handleClose">
? ? ? ? ? <el-input type="hidden" v-model="ruleForm.userId"/>
? ? ? ? ? <el-form-item label="時間" prop="userDate">
? ? ? ? ? ? <el-date-picker type="datetime" placeholder="選擇日期" v-model="ruleForm.userDate" style="width: 100%;"></el-date-picker>
? ? ? ? ? </el-form-item>
? ? ? ? ? <el-form-item label="姓名" prop="userName">
? ? ? ? ? ? <el-input v-model="ruleForm.userName"></el-input>
? ? ? ? ? </el-form-item>
? ? ? ? ? <el-form-item label="住址" prop="userAddress">
? ? ? ? ? ? <el-input v-model="ruleForm.userAddress"></el-input>
? ? ? ? ? </el-form-item>
? ? ? ? ? <span slot="footer" class="dialog-footer">
? ? ? ? ? ? <el-button @click="cancel()" size="medium">取 消</el-button>
? ? ? ? ? ? <el-button @click="addUser()" type="primary" size="medium">確 定</el-button>
? ? ? ? ? </span>
? ? ? ? </el-dialog>
? ? ? </el-form>
? ? <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="70px" class="demo-ruleForm" size="medium">
? ? ? <el-dialog
? ? ? ? title="編輯"
? ? ? ? :append-to-body='true'
? ? ? ? :visible.sync="dialogUpdate"
? ? ? ? width="80%"
? ? ? ? :before-close="handleClose">
? ? ? ? <el-input type="hidden" v-model="ruleForm.userId"/>
? ? ? ? <el-form-item label="時間" prop="userDate">
? ? ? ? ? <el-date-picker type="datetime" placeholder="選擇日期" v-model="ruleForm.userDate" style="width: 100%;"></el-date-picker>
? ? ? ? </el-form-item>
? ? ? ? <el-form-item label="姓名" prop="userName">
? ? ? ? ? <el-input v-model="ruleForm.userName"></el-input>
? ? ? ? </el-form-item>
? ? ? ? <el-form-item label="住址" prop="userAddress">
? ? ? ? ? <el-input v-model="ruleForm.userAddress"></el-input>
? ? ? ? </el-form-item>
? ? ? ? <span slot="footer" class="dialog-footer">
? ? ? ? ? ? <el-button @click="cancel()" size="medium">取 消</el-button>
? ? ? ? ? ? <el-button @click="updateUser()" type="primary" size="medium">確 定</el-button>
? ? ? ? ? </span>
? ? ? </el-dialog>
? ? </el-form>
? ? ? <br>
? ? ? <div class="pages">
? ? ? ? <el-pagination
? ? ? ? ? background
? ? ? ? ? :disabled = "disablePage"
? ? ? ? ? :current-page.sync="currentPage"
? ? ? ? ? small
? ? ? ? ? layout="prev, pager, next"
? ? ? ? ? :page-size="pageSize"
? ? ? ? ? :total="total"
? ? ? ? ? @current-change="handleCurrentChange">
? ? ? ? </el-pagination>
? ? ? </div>
? </div>
</template>
<script>
? ? export default {
? ? ? ? data() {
? ? ? ? ? ? return {
? ? ? ? ? ? ? ? ruleForm: {
? ? ? ? ? ? ? ? ? ? userId: '',
? ? ? ? ? ? ? ? ? ? userName: '',
? ? ? ? ? ? ? ? ? ? userDate: '',
? ? ? ? ? ? ? ? ? ? userAddress: ''
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? rules: {
? ? ? ? ? ? ? ? ? ? userName: [
? ? ? ? ? ? ? ? ? ? ? ? { required: true, message: '請輸入姓名', trigger: 'blur' },
? ? ? ? ? ? ? ? ? ? ? ? { min: 2, max: 7, message: '長度在 2 到 7 個字符', trigger: 'blur' }
? ? ? ? ? ? ? ? ? ? ],
? ? ? ? ? ? ? ? ? ? userAddress: [
? ? ? ? ? ? ? ? ? ? ? ? { required: true, message: '請輸入住址', trigger: 'blur' },
? ? ? ? ? ? ? ? ? ? ? ? { min: 5, message: '長度大于 5 個字符', trigger: 'blur' }
? ? ? ? ? ? ? ? ? ? ],
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? tableData: [],
? ? ? ? ? ? ? ? search: '',
? ? ? ? ? ? ? ? dialogVisible: false,
? ? ? ? ? ? ? ? dialogUpdate: false,
? ? ? ? ? ? ? ? pageSize: 5,
? ? ? ? ? ? ? ? currentPage: 1,
? ? ? ? ? ? ? ? total: 0,
? ? ? ? ? ? ? ? disablePage: false
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? methods: {
? ? ? ? ? ? handleEdit(index, row) {
? ? ? ? ? ? ? ? this.dialogUpdate = true;
? ? ? ? ? ? ? ? this.ruleForm = Object.assign({}, row); //這句是關(guān)鍵!1ⅰ停蕉!
? ? ? ? ? ? },
? ? ? ? ? ? handleDelete(index, row) {
? ? ? ? ? ? ? ? console.log(index, row);
? ? ? ? ? ? ? ? this.$confirm('刪除操作, 是否繼續(xù)?', '提示', {
? ? ? ? ? ? ? ? ? ? confirmButtonText: '確定',
? ? ? ? ? ? ? ? ? ? cancelButtonText: '取消',
? ? ? ? ? ? ? ? ? ? type: 'warning'
? ? ? ? ? ? ? ? }).then(() => {
? ? ? ? ? ? ? ? ? ? let postData = this.qs.stringify({
? ? ? ? ? ? ? ? ? ? ? ? userId: row.userId,
? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? this.axios({
? ? ? ? ? ? ? ? ? ? ? ? method: 'post',
? ? ? ? ? ? ? ? ? ? ? ? url:'/delete',
? ? ? ? ? ? ? ? ? ? ? ? data:postData
? ? ? ? ? ? ? ? ? ? }).then(response =>
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? this.getPages();
? ? ? ? ? ? ? ? ? ? ? ? this.currentPage = 1;
? ? ? ? ? ? ? ? ? ? ? ? this.axios.post('/page').then(response =>
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? this.tableData = response.data;
? ? ? ? ? ? ? ? ? ? ? ? }).catch(error =>
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? console.log(error);
? ? ? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? ? ? this.$message({
? ? ? ? ? ? ? ? ? ? ? ? ? ? type: 'success',
? ? ? ? ? ? ? ? ? ? ? ? ? ? message: '刪除成功!'
? ? ? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? ? ? console.log(response);
? ? ? ? ? ? ? ? ? ? }).catch(error =>
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? console.log(error);
? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? }).catch(() => {
? ? ? ? ? ? ? ? ? ? this.$message({
? ? ? ? ? ? ? ? ? ? ? ? type: 'info',
? ? ? ? ? ? ? ? ? ? ? ? message: '已取消刪除'
? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? });
? ? ? ? ? ? },
? ? ? ? ? ? handleClose(done) {
? ? ? ? ? ? ? ? this.$confirm('確認(rèn)關(guān)閉?')
? ? ? ? ? ? ? ? ? ? .then(_ => {
? ? ? ? ? ? ? ? ? ? ? ? done();
? ? ? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ? ? ? .catch(_ => {});
? ? ? ? ? ? },
? ? ? ? ? ? handleCurrentChange() {
? ? ? ? ? ? ? ? console.log(`當(dāng)前頁: ${this.currentPage}`);
? ? ? ? ? ? ? ? let postData = this.qs.stringify({
? ? ? ? ? ? ? ? ? ? page: this.currentPage
? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? this.axios({
? ? ? ? ? ? ? ? ? ? method: 'post',
? ? ? ? ? ? ? ? ? ? url:'/page',
? ? ? ? ? ? ? ? ? ? data:postData
? ? ? ? ? ? ? ? }).then(response =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? this.tableData = response.data;
? ? ? ? ? ? ? ? }).catch(error =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? console.log(error);
? ? ? ? ? ? ? ? });
? ? ? ? ? ? },
? ? ? ? ? ? cancel() {
? ? ? ? ? ? ? ? this.dialogUpdate = false;
? ? ? ? ? ? ? ? this.dialogVisible = false;
? ? ? ? ? ? ? ? this.emptyUserData();
? ? ? ? ? ? },
? ? ? ? ? ? emptyUserData(){
? ? ? ? ? ? ? ? this.ruleForm = {
? ? ? ? ? ? ? ? ? ? userName: '',
? ? ? ? ? ? ? ? ? ? userDate: '',
? ? ? ? ? ? ? ? ? ? userAddress: ''
? ? ? ? ? ? ? ? }
? ? ? ? ? ? },
? ? ? ? ? ? addUser() {
? ? ? ? ? ? ? ? let postData = this.qs.stringify({
? ? ? ? ? ? ? ? ? ? userDate: this.ruleForm.userDate,
? ? ? ? ? ? ? ? ? ? userName: this.ruleForm.userName,
? ? ? ? ? ? ? ? ? ? userAddress: this.ruleForm.userAddress
? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? this.axios({
? ? ? ? ? ? ? ? ? ? method: 'post',
? ? ? ? ? ? ? ? ? ? url:'/insert',
? ? ? ? ? ? ? ? ? ? data:postData
? ? ? ? ? ? ? ? }).then(response =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? this.axios.post('/page').then(response =>
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? this.tableData = response.data;
? ? ? ? ? ? ? ? ? ? ? ? this.currentPage = 1;
? ? ? ? ? ? ? ? ? ? ? ? this.$message({
? ? ? ? ? ? ? ? ? ? ? ? ? ? type: 'success',
? ? ? ? ? ? ? ? ? ? ? ? ? ? message: '已添加!'
? ? ? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? }).catch(error =>
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? console.log(error);
? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? this.getPages();
? ? ? ? ? ? ? ? ? ? this.dialogVisible = false
? ? ? ? ? ? ? ? ? ? console.log(response);
? ? ? ? ? ? ? ? }).catch(error =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? console.log(error);
? ? ? ? ? ? ? ? });
? ? ? ? ? ? },
? ? ? ? ? ? updateUser() {
? ? ? ? ? ? ? ? let postData = this.qs.stringify({
? ? ? ? ? ? ? ? ? ? userId: this.ruleForm.userId,
? ? ? ? ? ? ? ? ? ? userDate: this.ruleForm.userDate,
? ? ? ? ? ? ? ? ? ? userName: this.ruleForm.userName,
? ? ? ? ? ? ? ? ? ? userAddress: this.ruleForm.userAddress
? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? this.axios({
? ? ? ? ? ? ? ? ? ? method: 'post',
? ? ? ? ? ? ? ? ? ? url:'/update',
? ? ? ? ? ? ? ? ? ? data:postData
? ? ? ? ? ? ? ? }).then(response =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? this.handleCurrentChange();
? ? ? ? ? ? ? ? ? ? this.cancel();
? ? ? ? ? ? ? ? ? ? this.$message({
? ? ? ? ? ? ? ? ? ? ? ? type: 'success',
? ? ? ? ? ? ? ? ? ? ? ? message: '更新成功!'
? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? console.log(response);
? ? ? ? ? ? ? ? }).catch(error =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? this.$message({
? ? ? ? ? ? ? ? ? ? ? ? type: 'success',
? ? ? ? ? ? ? ? ? ? ? ? message: '更新失敗!'
? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? console.log(error);
? ? ? ? ? ? ? ? });
? ? ? ? ? ? },
? ? ? ? ? ? onSearch() {
? ? ? ? ? ? ? ? let postData = this.qs.stringify({
? ? ? ? ? ? ? ? ? ? userName: this.search
? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? this.axios({
? ? ? ? ? ? ? ? ? ? method: 'post',
? ? ? ? ? ? ? ? ? ? url: '/ListByName',
? ? ? ? ? ? ? ? ? ? data: postData
? ? ? ? ? ? ? ? }).then(response =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? this.tableData = response.data;
? ? ? ? ? ? ? ? ? ? this.disablePage = true;
? ? ? ? ? ? ? ? }).catch(error =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? console.log(error);
? ? ? ? ? ? ? ? });
? ? ? ? ? ? },
? ? ? ? ? ? getPages() {
? ? ? ? ? ? ? ? this.axios.post('/rows').then(response =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? this.total = response.data;
? ? ? ? ? ? ? ? }).catch(error =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? console.log(error);
? ? ? ? ? ? ? ? });
? ? ? ? ? ? },
? ? ? ? ? ? refreshData() {
? ? ? ? ? ? ? ? location.reload();
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? created() {
? ? ? ? ? ? /*this.axios.get('static/user.json').then(response =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this.tableData = response.data.tableData;
? ? ? ? ? ? ? ? this.total = response.data.tableData.length;
? ? ? ? ? ? ? ? // console.log(JSON.parse(JSON.stringify(response.data))['tableData'])
? ? ? ? ? ? });*/
? ? ? ? ? ? this.axios.post('/page').then(response =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this.tableData = response.data;
? ? ? ? ? ? }).catch(error =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ? console.log(error);
? ? ? ? ? ? });
? ? ? ? ? ? this.axios.post('/rows').then(response =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this.total = response.data;
? ? ? ? ? ? }).catch(error =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ? console.log(error);
? ? ? ? ? ? });
? ? ? ? },
? ? }
</script>
<style scoped>
? .search_name{
? ? width: 200px;
? }
? .pages{
? ? margin: 0px;
? ? padding: 0px;
? ? text-align: right;
? }
</style>
```
## 前后端整合
在vue01\config\index.js文件中配置proxyTable{}钙态,如下:
```
proxyTable: {
? ? ? '/': {
? ? ? ? target:'http://localhost:8081', // 你請求的第三方接口
? ? ? ? changeOrigin:true, // 在本地會創(chuàng)建一個虛擬服務(wù)端慧起,然后發(fā)送請求的數(shù)據(jù),并同時接收請求的數(shù)據(jù)册倒,這樣服務(wù)端和服務(wù)端進(jìn)行數(shù)據(jù)的交互就不會有跨域問題
? ? ? ? pathRewrite:{? // 路徑重寫蚓挤,
? ? ? ? ? '^/': ''? // 替換target中的請求地址
? ? ? ? }
? ? ? }
? ? },
```
## 實(shí)現(xiàn)效果

