此文为vue进阶篇,包含vue路由、组件、axios请求以及结合springboot开发实例
入门篇链接地址https://blog.csdn.net/qq_41157588/article/details/115085686
代码完整无水分,供学习参考,更多了解信息请看文末.
总结不易 点赞评论 支持 thank ~
10.Axios基本使用
10.1Axios引言
Axios是一个异步请求技术,核心作用就是用来在页面中发送异步请求,
并获取对应数据在在页面中渲染 页面局部更新技术 Ajax
Axios中文网 http://www.axios-js.com/zh-cn/docs/
10.2Axios安装方式
- 使用 npm
$ npm install axios
- 使用 bower
$ bower install axios
- 使用 cdn(注:需要联网)
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
10.3GET方式请求
Axios使用准备工作=> 在Axios进行 Get和Post请求时,此处请求的地址和数据是结合springboot接口进行模拟的,请按照以下图及代码使用IDEA创建一个springboot项目,用前端vue Axios进行GET和POST请求的使用
User实体代码
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString
public class User {
private Integer id;
private String username;
private String email;
private Integer age;
private String phone;
}
UserController代码
@RestController
@RequestMapping("user")
public class UserController {
//删除数据
@CrossOrigin
@DeleteMapping("delete")//解决跨域的注解
public Map<String,Object> delete(String id){
Map<String, Object> map = new HashMap<>();
System.out.println("id = " + id);
map.put("success",true);
return map;
}
//保存数据
@CrossOrigin//解决跨域的注解
@PostMapping("save")
public Map<String,Object> delete(@RequestBody User user){
Map<String, Object> map = new HashMap<>();
System.out.println("user = " + user);
map.put("success",true);
return map;
}
//展示索引
@CrossOrigin//解决跨域的注解
@GetMapping("findAll")
public List<User> findAll(String id){
System.out.println("id = " + id);
List<User> users = new ArrayList<>();
users.add(new User(1,"axios测试值1","ti66666@vip.qq.com",21,"15155556666"));
users.add(new User(2,"axios测试值2","ti66666@vip.qq.com",22,"15656667777"));
users.add(new User(3,"axios测试值3","ti66666@vip.qq.com",23,"17666663959"));
return users;
}
}
数据准备完成。接下来准备上手axios的get和post请求,测试请求要注意和后端服务端口对应
Axios GET请求Vue代码
<!-- 引入Axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>axios的GET方式请求使用</title>
</head>
<body>
<!-- 引入Axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 发送GET方式的请求 -->
<script>
axios.get("http://localhost:8989/user/findAll?id=1").then(function(response){
console.log(response.data);
}).catch(function(err){
console.log(err);
})
</script>
</body>
</html>
10.4POST方式请求
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>axios的POST方式请求使用</title>
</head>
<body>
<!-- 引入在线Axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
axios.post("http://localhost:8989/user/save",{
id:5,
username:"xiangti",
age:22,
email:"ti66666@vip.qq.com",
phone:13215882222
}).then(function(response){
console.log(response);
}).catch(function(err){
console.log(err);
})
</script>
</body>
</html>
10.5axios并发请求
并发请求:将多个请求在同一时刻发送后到后端服务接口,最后在集中处理每个请求的响应结果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>axios并发请求</title>
</head>
<body>
<!-- 引入在线Axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
// 1.创建一个查询所有的请求
function findAll(){
return axios.get("http://localhost:8989/user/findAll?id=1")
}
// 2.创建一个保存的请求
function save(){
axios.post("http://localhost:8989/user/save",{
id:5,
username:"xiangti",
age:22,
email:"ti66666@vip.qq.com",
phone:13215882222
})
}
// 3.并发执行
// axios.all(findAll(),save());
axios.all([findAll(),save()]).then(
axios.spread(function(res1,res2){
console.log(res1.data);
console.log(res2.data);
})
)//用来发送一组并发请求
</script>
</body>
</html>
此时在IDEA和网页的NetWork看到执行了两条请求
vue结合axios天气查询案例
后端数据模拟api
上图WeatherController代码 (注意:前端请求端口要和后端的端口对应)
@RestController
@RequestMapping("city")
public class WeatherController {
@GetMapping("/find")
@CrossOrigin//跨域注解
//http://localhost:8989/city/find?name=江苏
public Map<String,String> findWeatherByCity(String name){
Map<String, String> map = new HashMap<>();
String weathers = getWeathers(name);
// map.put(name,weathers);
map.put("CityWeatherMsg",weathers);
return map;
}
//返回对应城市的天气情况
public String getWeathers(String name) {
Map<String,String> weathers = new HashMap<>();
weathers.put("河南","晴天 23℃-27℃,天气情况良好");
weathers.put("江苏","多云转阴 20℃-26℃,天气挺好");
weathers.put("北京","大雨 14℃-19℃,天气很不好");
weathers.put("上海","多云 27℃-31℃,天气可以");
return weathers.get(name);
}
}
前端代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue结合axios天气查询案例</title>
</head>
<body>
<div id="app">
<!-- 双向绑定城市信息,点删除键时 隐藏天气信息,回车时,直接搜索 -->
<input type="text" v-model="cityname" @keyup.delete="shows" @keyup.enter="searchCity" placeholder="请输入如下的城市"/>
<input type="button" value="搜索" @click="searchCity"/><br>
<span v-for="city in hotCitys">
<!-- prevent阻止a标签的默认行为 -->
<a href="javascript:;" @click.prevent="searchCitys(city)">{{ city }}</a>
</span>
<span style="color: red;"> <=仅支持提供的城市数据查询</span>
<hr >
<span v-show="isShow">城市: {{cityname}} -> 获取后台的天气数据: {{msg}}</span>
</div>
<!-- 引入在线cdn的vue.js地址-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入在线cdn Axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
const app = new Vue({
el: "#app", //element:用来指定vue作用范围
data: { //data:用来定义vue实例相关数据
hotCitys: ["河南", "江苏", "北京", "上海"],
cityname:"",
msg:"",
isShow:false
},
methods: { //methods:用来定义vue事件处理函数
searchCity(){
// 获取输入的城市信息
console.log("外this作用域信息"+this+"** | **"+"当前输入城市信息:"+this.cityname);
let _this = this;
//发送axios请求
axios.get("http://localhost:8989/city/find?name="+this.cityname).then(function(response){
console.log("内this作用域信息"+this+"** | **"+"后台响应CityWeather信息:"+response.data.CityWeatherMsg);
//把获取到的后台map的CityWeatherMsg键值赋值给页面上的msg
_this.msg = response.data.CityWeatherMsg;
_this.isShow = true;
console.log("------------------------");
}).catch(function(err){
console.log(err);
})
},
searchCitys(name){
//把name传入到a标签中的city值,再调取cityname进行赋值
this.cityname = name;
//函数中再次调函数
this.searchCity();
},
shows(){
this.isShow = false;
}
}
})
</script>
</body>
</html>
11.Vue生命周期
生命周期钩子 => 生命周期函数
12.vue结合前端springboot前后端分离开发综合案例crud
项目结构图
最终效果图
sql
自行添加更多的数据
/*
SQLyog Ultimate v12.3.1 (64 bit)
MySQL - 5.7.20-log : Database - stu_newest
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`stu_newest` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `你的数据库`;
/*Table structure for table `v_user` */
DROP TABLE IF EXISTS `v_user`;
CREATE TABLE `v_user` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(40) DEFAULT NULL COMMENT '名字',
`age` int(3) DEFAULT NULL COMMENT '年龄',
`salary` double(7,2) DEFAULT NULL COMMENT '薪资',
`phoneCode` varchar(11) DEFAULT NULL COMMENT '电话',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
/*Data for the table `v_user` */
insert into `v_user`(`id`,`name`,`age`,`salary`,`phoneCode`) values
(1,'admin',15,50000.00,'15545853564'),
(2,'xiangti',21,99999.00,'15368485275'),
(3,'tizi',20,10000.00,'17666663959'),
(4,'小花',19,17000.00,'18588745952'),
(5,'阿名',23,19000.00,'16859267368'),
(6,'girl',20,20000.00,'16815964211'),
(7,'boy',24,2603.00,'13842156415'),
(8,'华哥',20,15151.00,'16484232515');
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
application.yml 配置
server:
port: 8989 #端口号8989
servlet:
context-path: /user #默认访问路径/user
spring:
application:
name: vue-crud
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/stu_newest?characterEncoding=utf-8
username: root
password: 12345678
mybatis:
mapper-locations: classpath:/mybatis/mapper/*.xml
type-aliases-package: com.lemon.bean
User 实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Accessors(chain = true)//开启链式写法
public class User {
private Integer id;
private String name;
private Integer age;
private Double salary;
private String phoneCode;
}
UserMapper 数据访问接口
@Mapper
public interface UserMapper {
//查询所有信息
List<User> findAll();
//添加用户
void save(User user);
//删除用户
void del(int id);
//根据id查当前信息
User findOne(Integer id);
//根据id修改信息
void update(User user);
//根据姓名或电话模糊搜索
List<User> findNameOrPhoneCode(@Param("name") String name,@Param("phoneCode") String phoneCode);
}
PageMapper 分页数据访问接口
@Mapper
public interface PageMapper<T, K> {
/**
*
* @param start 当前页
* @param rows 页大小
* @return
*/
public List<T> findByPage(@Param("start") Integer start, @Param("rows") Integer rows);
/**
* 总条数
* @return
*/
public Integer findTotals();
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace=绑定一个指定的dao/mapper接口-->
<mapper namespace="com.lemon.mapper.UserMapper">
<!--处理模糊搜索-->
<select id="findNameOrPhoneCode" resultType="user">
select id,name,age,salary,phoneCode from v_user
<where>
<if test="name != ''">
name like concat(#{name},'%')
</if>
<if test="phoneCode != ''">
or phoneCode like concat('%',#{phoneCode},'%')
</if>
</where>
</select>
<!--根据id修改当前信息-->
<update id="update" parameterType="user">
update v_user set name=#{name},age=#{age},salary=#{salary},phoneCode=#{phoneCode} where id = #{id}
</update>
<!--根据id查询当前信息-->
<select id="findOne" resultType="user" >
select id,name,age,salary,phoneCode from v_user where id = #{id}
</select>
<!--根据id删除一条信息-->
<delete id="del" parameterType="Integer">
delete from v_user where id = #{id}
</delete>
<!--开启自增 id,不设置也可以,数据库已经设置自增-->
<!--<insert id="save" parameterType="user" useGeneratedKeys="true" keyProperty="id">-->
<insert id="save" parameterType="user">
insert into v_user values (#{id},#{name},#{age},#{salary},#{phoneCode})
</insert>
<!--查询所有数据-->
<select id="findAll" resultType="user">
select id,name,age,salary,phoneCode from v_user
</select>
</mapper>
PageMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace=绑定一个指定的dao/mapper接口-->
<mapper namespace="com.lemon.mapper.PageMapper">
<!--分页查询所有-->
<select id="findByPage" resultType="user">
select id,
name,
age,
salary,
phoneCode
from v_user
order by id ASC
limit #{start},#{rows}
</select>
<!--查询总条数-->
<select id="findTotals" resultType="integer">
select count(id) from v_user
</select>
</mapper>
UserService
public interface UserService {
//查询所有信息
List<User> findAll();
//添加用户
void save(User user);
//删除用户
void del(int id);
//根据id查当前信息
User findOne(Integer id);
//根据id修改信息
void update(User user);
//根据姓名或电话模糊搜索
List<User> findNameOrPhoneCode(@Param("name") String name, @Param("phoneCode") String phoneCode);
}
UserServiceImpl
@Service
public class UserServiceImpl implements UserService{
@Resource
private UserMapper userMapper;
@Override
public List<User> findAll() {
return userMapper.findAll();
}
@Override
public void save(User user) {
userMapper.save(user);
}
@Override
public void del(int id) {
userMapper.del(id);
}
@Override
public User findOne(Integer id) {
return userMapper.findOne(id);
}
@Override
public void update(User user) {
userMapper.update(user);
}
@Override
public List<User> findNameOrPhoneCode(String name, String phoneCode) {
return userMapper.findNameOrPhoneCode(name,phoneCode);
}
}
PageService
public interface PageService {
/**
* @param page 当前页
* @param rows 每页显示的记录数
* @return
*/
public List<User> findByPage(Integer page,Integer rows);
/**
* 查询总条数
* @return
*/
public Integer findTotals();
}
PageServiceImpl
@Service
public class PageServiceImpl implements PageService {
@Resource
private PageMapper pageMapper;
@Override
public List<User> findByPage(Integer page, Integer rows) {
//页码计算公式 (当前页-1) * 页大小
int start = (page - 1) * rows;
return pageMapper.findByPage(start, rows);
}
@Override
public Integer findTotals() {
return pageMapper.findTotals();
}
}
UserController
@Controller
@RestController
@CrossOrigin//允许跨域处理
public class UserController {
@Resource
private UserService userService;
//模糊搜索
@GetMapping("/findLike")
public List<User> findNameOrPhoneCode(String name,String code){
System.out.println("前端模糊搜索 name值:"+name+" | phone值: " +code);
return userService.findNameOrPhoneCode(name,code);
}
@GetMapping(value = "/findOne")
//根据id查询当前信息
public User findOne(int id){
System.out.println("前端查询当前信息id:" +id);
return userService.findOne(id);
}
@PostMapping(value = "/del")
//删除用户
public Map<String,Object> del(int id){
System.out.println("前端删除id值:"+id);
Map<String, Object> map = new HashMap<>();
try {
//前端传的值为string类型,定义的值为integer,强制string类型转integer
// Integer num = Integer.parseInt(id);
userService.del(id);
map.put("state",true);
} catch (Exception e) {
map.put("state",false);
}
return map;
}
@PostMapping(value = "/save")
//保存用户_修改用户
public Map<String, Object> save(@RequestBody User user) {
System.out.println("前端save信息(有id修改 无id添加): " + user);
Map<String, Object> map = new HashMap<>();
if (!user.equals("") && user!=null) {
//如果没有id执行的是添加操作
if (StringUtils.isEmpty(user.getId())){
userService.save(user);
map.put("state", true);
map.put("msg","添加成功");
}else{
//如果有id执行的是修改操作
userService.update(user);
map.put("state", true);
map.put("msg","修改成功");
}
} else {
map.put("state", false);
map.put("msg", "保存或修改失败");
}
return map;
}
//查询所有信息(已无作用,后期加了分页查询数据)
@GetMapping("/findAll")
public List<User> findAll() {
List<User> userList = userService.findAll();
return userList;
}
}
PageController
@Controller
@CrossOrigin//允许跨域处理
public class PageController {
@Resource
private PageService pageService;
@GetMapping("/findByPage")
@ResponseBody
public Map<String,Object> findByPage(Integer page,Integer rows){
System.out.println("前端页码:"+ page);
//page=null 页面为1
page = page==null?1:page;
//rows=null 每页展示五条数据
rows = rows==null?5:rows;
HashMap<String, Object> map = new HashMap<>();
//分页处理
List<User> userList = pageService.findByPage(page, rows);
//计算总页数
Integer totals = pageService.findTotals();
//总页数 count%rows==0 如果等于0执行 count/rows 否则执行count/rows+1
Integer totalPage = totals%rows==0?totals/rows:totals/rows+1;
if(page>totalPage){
map.put("state",true);
map.put("msg","已经是最后一页了 没有更多的数据啦~");
}
map.put("userList",userList);//放入用户id集合
map.put("totals",totals);//放入总条数的方法
map.put("totalPage",totalPage);//放入总页数
map.put("page",page);//放入当前页
return map;
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User Manager</title>
<!--引入bootstrap中css的样式-->
<link rel="stylesheet" href="../static/css/bootstrap.min.css">
<style type="text/css">
tr th {
text-align: center;
}
td {
text-align: center;
}
</style>
</head>
<body>
<!--导航-->
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a class="navbar-brand" href="#">简易用户管理系统</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">x</a></li>
</ul>
</div>
</div>
</nav>
<div id="app">
<!--中心布局-->
<div class="container-fluid">
<!--搜索框-->
<div class="row">
<div class="col-md-8 col-md-offset-1">
<form class="form-inline">
<div class="form-group">
<label for="exampleInputName2">姓名</label>
<input type="text" placeholder="输入搜索姓名的关键字" v-model="searchName" class="form-control"
id="searchName">
</div>
<div class="form-group">
<label for="exampleInputEmail2">电话</label>
<input type="email" placeholder="输入电话的关建数" v-model="searchPhone" class="form-control"
id="searchEmail">
</div>
<button type="submit" class="btn btn-info" @click.prevent="searchLike">搜索</button>
</form>
</div>
</div>
<div class="row">
<div class="col-md-8" style="margin-top: 50px">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
<th>薪资</th>
<th>电话</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="user,index in users" :key="user.id">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
<td>{{user.salary}}</td>
<td>{{user.phoneCode}}</td>
<td>
<button class="btn btn-danger" @click="delRow(user.id)">删除</button>
<button class="btn btn-primary" @click="findOneUserInfo(user.id)">修改</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-4">
<div class="form-group" style="margin: 0px" align="center">
<span><h3>添加 | 修改 模块</h3></span><br>
<span>表单默认为添加数据不携带id / 点修改自动获取id 携带id进行修改</span>
</div>
<span></span>
<form>
<div class="form-group">
<label for="username">姓名</label>
<input type="text" class="form-control" required id="username" v-model="userparameter.name"
placeholder="请输入姓名">
</div>
<div class="form-group">
<label for="password">年龄</label>
<input type="text" class="form-control" id="password" v-model="userparameter.age"
placeholder="请输入年龄">
</div>
<div class="form-group">
<label for="salary">薪资</label>
<input type="text" class="form-control" id="salary" v-model="userparameter.salary"
placeholder="请输入薪资">
</div>
<div class="form-group">
<label for="phoneCode">电话</label>
<input type="text" class="form-control" id="phoneCode" v-model="userparameter.phoneCode"
placeholder="请输入电话号码">
</div>
<button type="submit" class="btn btn-warning" @click="saveUserInfo">提交</button>
<button type="reset" class="btn btn-info">重置</button>
</form>
</div>
</div>
</div>
<!--分页 未添加样式版-->
<div id="pages" style="margin-left: 270px;">
<!--此处注释掉的代码为控制首页 和 尾页的 上一页和下一页标签隐藏-->
<!--<a href="javascript:;" class="page" v-if="page!=1" disabled @click="pagePart(page-1)"><上一页</a>-->
<a href="javascript:;" class="page" disabled @click="pagePart(page-1)"><上一页</a>
<a href="javascript:;" class="page" v-for="indexpage in totalPage" @click="pagePart(indexpage)"> {{indexpage}} </a>
<!--<a href="javascript:;" class="page" v-if="page<totalPage" @click="pagePart(page+1)">下一页&></a>-->
<a href="javascript:;" class="page" @click="pagePart(page+1)">下一页></a>
</div>
</div>
<!--引入Vue.js-->
<script src="../static/js/vue.js"></script>
<!--引入axios.js-->
<script src="../static/js/axios.min.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
users: [],//数据赋值来源于后端服务接口,在页面加载完成前完成赋值
userparameter: {},//定义添加数据的双向绑定,此处如为[]会报错
searchName: "",//处理搜索名字的数据绑定
searchPhone: "",//处理搜索电话的数据绑定
page: 1,//当前页 默认1
rows: 5,//行数 默认5
totalPage: 0,
totals: 0,
},
methods: {
//查询所有数据 并进行分页
pagePart(indexpage) {//查询所有
if (indexpage) {
this.page = indexpage;
}
axios.get("http://localhost:8989/user/findByPage?page=" + this.page).then((res) => {
// console.log(res.data.userList);
if (res.data.state) {
//当处于最后一页时,再点击下一页响应后台msg信息
alert(res.data.msg);
//刷新页面
location.reload();
}
this.users = res.data.userList;
this.page = res.data.page;
this.totalPage = res.data.totalPage;
this.totals = res.data.totals;
});
},
searchLike() {
//模糊搜索
axios.get("http://localhost:8989/user/findLike?name=" + this.searchName + "&code=" + this.searchPhone).then((res) => {
console.log(res.data);
this.users = res.data;
})
},
//根据id查询当前的信息(修改)
findOneUserInfo(id) {
axios.get("http://localhost:8989/user/findOne?id=" + id).then((res) => {
console.log(res.data);
//根据双向绑定原理,后台直接赋值给userparameter
this.userparameter = res.data;
});
},
//根据id删除信息
delRow(id) {
if (confirm("确认删除id为 " + id + "信息吗")) {
axios.post("http://localhost:8989/user/del?id=" + id).then((res) => {
if (res.data.state) {
alert("删除id " + id + " 信息成功");
location.reload(); //刷新当前页
} else {
alert("删除失败");
}
});
}
},
//添加信息
saveUserInfo() {
axios.post("http://localhost:8989/user/save", this.userparameter).then((res) => {
if (res.data.state) {
alert(res.data.state + " " + res.data.msg);
//添加完成后刷新当前页 location.reload()或调取 this.findAll
location.reload();
//清空文本框的信息
this.userparameter = "";
} else {
alert("后台:" + res.data.state + " " + res.data.msg);
}
}).catch((err) => {
alert("添加失败 错误信息: " + err);
});
},
//查询所有用户信息的函数 (后期已加入分页查数据,当前无用)
// findAll() {
// //已简写为以下的箭头函数
// axios.get("http://localhost:8989/user/findAll").then((res) => {
// // console.log(res.data);
// this.users = res.data;
// }).catch((err) => {
// console.log("查询所有错误信息:" + err);
// })
// },
},
//生命周期相关函数 页面加载直接调用
created() {
//调用查询所有信息函数
// this.findAll();
this.pagePart();
}
})
</script>
</body>
</html>
static静态文件说明
static静态文件为 bootstrap vue.js vue.min.axios 此处没有放入这些文件,可以尝试在inedx.html删除现有的link和script 导入如下cdn
<!--引入bootstrap-->
<link href="https://cdn.bootcdn.net/ajax/libs/twitterbootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!--引入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!--引入axios.js-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
test测试类
@SpringBootTest
class VueTest {
@Autowired
private UserMapper userMapper;
@Autowired
private PageService pageService;
@Test
void findAll() {
userMapper.findAll().forEach(user -> System.out.println("user = " + user));
}
//分页测试
@Test
public void testFindByPage() {
List<User> list = pageService.findByPage(1, 3);
//jdk8的新特性
list.forEach(province -> {
System.out.println(province);
});
}
}
13.Vue组件
13.1组件作用
组件作用:用来减少vue实例对象中代码量,之后在使用vue开发的过程中,可根据不用业务功能划分不同的多个组件,然后由多个组件去完成整个页面的布局,便于以后使用vue开发时页面管理,方便开发人员维护
13.2组件使用
13.2.1全局组件的注册
全局组件注册给vue实例,以后可以在任何vue实例范围内使用该组件
开发全局组件
<!--使用全局组件-->
<login></login>
//全局组件注册 (参数1:组件名称 参数2:组件配置对象 template:用来书写组件html代码 注意在template中必须存在一个容器 )
Vue.component('login', {
template: '<div><h1>用户登录</h1></div>'
})
# 注意:
1. Vue.component用来开发全局组件 参数1:组件的名称 参数2:组件配置{} template:‘ ’ 用来书写组件的html代码 template中必须只有有 且只有一个root元素
2.使用时需要在Vue的作用范围内根据组件名使用 Vue 全局组件
3.如在注册组件时使用驼峰式命名时,注意在调用时用 - 来衔接,全部小写,如下示例
<user-login></user-login>
Vue.component('userLogin', {
template: '<div><h1>用户登录</h1></div>'
})
13.2. 局部组件的注册
通过将组件注册给对应Vue实例中一个components属性来完成组件注册,这种方式不会对Vue实例造成累加
局部组件注册推荐使用第二种
第一种开发方式
<div id="app">
<login></login>
</div>
<!-- 引入在线cdn的vue.js地址-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//局部组件登录模板 1 x
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: { //用来注册局部组件
login: {//局部组件名称
template: '<div><h2>用户管理</h2></div>'
}
}
})
</script>
-----------------------------------------------------------------------
<script>
//局部组件登录模板 2 *
let login = {//具体局部组件名称
template: '<div><h2>用户管理</h2></div>' }
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: { //用来注册局部组件
login:login //注册局部组件
}
})
</script>
第二种开发方式
<div id="app">
<!--4.局部组件使用 在vue实例范围内-->
<login></login>
<login></login>
</div>
<!-- 1.引入在线cdn的vue.js地址-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!--2.生命局部变量模板 template 标签,注意:在vue实例作用外声明-->
<template id="loginTemplate"><h2>用户登录</h2></template>
<!--3.注册组件-->
<script>
let login = {//具体局部组件名称
template:'#loginTemplate'
}
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: { //用来注册局部组件
//login: login //注册局部组件
login //:后内容可直接去掉调用
}
})
</script>
13.3 Prop的使用
prop用来给组件传递相应静态数据或动态数据
13.3.1通过在组件上声明静态数据传递给组件内部
//1.声明组件模板对象
let login = {
template: "<div><h1>欢迎:{{userName}} age:{{age}}</h1></div>",
props:['userName','age'] //props 用来接收使用组件时通过组件中标签传递的数据
}
//2.注册组件
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: {
login //组件注册
}
})
//3.通过组件完成数据传递
<login user-name="柠檬" age="21"></login>
# 总结
1.使用组件时可以再组件上定义多个属性以及对应数据
2.在组件内部可以使用props数组声明多个定义在组件上的属性名,之后可以在组件中通过{{属性名}}方式获取组件中属性值
13.3.2通过组件声明动态数据传递给组件内部
//1.声明组件模板对象
let comp = {
template: '<div><h2>欢迎:{{name}}</h2> 年龄:{{age}}</div>',
props:['name','age']
}
//2.注册局部组件
const app = new Vue({
el: "#app",
data: {
username:"提先森",
age:21
},
methods: {},
components: {
login:comp, //注册组件
}
})
//3.使用组件
<login :name="username" :age="age"></login>
使用v-bind形式将数据绑定在vue实例中data属性,之后data属性发生变化,组件内部数据跟着变化
13.3.3单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个 单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行
所有 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。 ------摘自官网
13.4组件中定义数据和事件
1.组件中定义属于组件的数据
<div id="app">
<!--组件的使用-->
<login></login>
</div>
//组件声明的配置对象
let comp = {
template: '<div>' +
'<h2>平淡安好</h2>' +
'<span>{{msg}}</span>' +
'<ul><li v-for="list,index in lists">{{index+1}} {{list}}</li></ul>'+
'</div>',
data() { //组件中自己的数据 使用data函数定义组件的属性 在template代码中通过插值表达式获取值
return {
msg: "template data",
lists:["java","php","python"]
}
}
}
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: {
login: comp //注册组件
}
})
2.组件中事件定义
<div id="app">
<login></login>
</div>
<!-- 引入在线cdn的vue.js地址-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let comp = {
template: '<div><input type="button" value="点击" @click="change""></div>',
data() {
return {
name:"提先森"
}
},
methods: {
change() {
alert(this.name);
}
}
}
const app = new Vue({
el: "#app",
components: {
login: comp
}
})
# 总结
1.组件中定义事件和直接在vue中定义事件基本一致,直接在组件内部对应的html代码加入@事件=函数名方式即可
2.在组件内部使用methods属性用来定义对应的事件函数即可,事件函数中this指向的是当前组件的实例
13.5向vue子组件中传递事件并在子组件中调用该事件
在子组件中调用传递过来的相关事件必须使用this.$emit(“函数名”) 方式调用
//1.声明组件
const login = {
template:'<div><h2>平淡安好</h2><input type="button" @click="change" value="点击"><br>{{uname}}</div>',
data(){
return{
uname:this.name,
}
},
methods:{
change(){
//调用vue实例中的函数
this.$emit("vc");//调用组件传递来的其他函数时使用 this.$emit('函数名调用')
}
},props:['name'],
}
//2.注册组件
const app = new Vue({
el: "#app",
data: {
username:"提先森",
},
methods: {
vueComp(){ //一个事件函数,将这个vue函数传递给子组件
alert("vue 实例函数执行");
}
},
components:{
login //注册组件
}
})
//3.使用组件(自己定义名字,绑定父组件事件)
<div id="app">
<login :name="username" @vc="vueComp"></login> //在组件内部使用 this.$emit("vc")调用
</div>
14.vue中路由(VueRouter)
14.1路由简介
路由:根据请求的路径按照一定的路由规则进行请求的转发 从而帮助我们实现统一请求的管理
14.2路由做用
用来在vue中实现组件之间的动态切换
vue router官网(包含使用安装_使用路由) https://router.vuejs.org/zh/guide/
14.3使用路由*
1.引入路由
vue.js cdn
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
vue路由的cdn 在 Vue 后面加载 vue-router,会自动安装的
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
2.创建组件对象
const login = {
template: '<div><h1>登录</h1></div>'
}
const register = {
template: '<div><h1>注册</h1></div>'
}
3.定义路由对象规则
//创建路由对象
const router = new VueRouter({
routes: [
//path:路由的路径 component:路径对应的组件
{path: '/login', component: login},
{path: '/register', component: register}
]
})
4.将路由对象注册到vue实例
const app = new Vue({
el: "#app",
data: {},
methods: {},
router: router //设置路由对象
})
5.在页面中显示路由组件 根据链接切换路由(注意路径前加 #)
<div id="app">
<a href="#/login">登录</a>
<br>
<a href="#/register">注册</a>
<!--显示路由的组件-->
<router-view></router-view>
</div>
完整代码
<div id="app">
<!--<a href="#/login">点击登录</a>-->
<!--<a href="#/register">点击注册</a>-->
<!--router-link好处:书写路由路径不需要 #, to用来写路由路径-->
<router-link to="/login" tag="button">点击登录</router-link>
<router-link to="/register" tag="button">点击注册</router-link>
<!--显示路由的组件-->
<router-view></router-view>
</div>
<!-- 引入在线cdn的vue.js地址-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!--引入router.js-->
<script src="./js/vue-router.js"></script>
<script>
//声明组件模板
const login = {
template: '<div><h1>登录</h1></div>'
}
const register = {
template: '<div><h1>注册</h1></div>'
}
//创建路由对象
const router = new VueRouter({
routes: [
{path: '/login', component: login},
{path: '/register', component: register},
]
})
const app = new Vue({
el: "#app",
data: {},
methods: {},
router: router //注册路由对象
})
</script>
14.4 router-link使用
作用:用来替换在切换路由时使用 a 标签切换路由
好处:可以自动给路由路径加入 # ,不需要手动加入
<!--<a href="#/login">点击登录</a>-->
<!--<a href="#/register">点击注册</a>-->
<!--router-link好处:书写路由路径不需要 #, to用来写路由路径 tag渲染指定标签元素-->
<router-link to="/login" tag="button">点击登录</router-link>
<router-link to="/register" tag="span">点击注册</router-link>
# 总结
1.router-link 用来替换使用a标签实现路由切换,好处是不需要书写 # 号,直接写路由路径
2.router-link to 属性用来书写路由路径 tag属性:用来将router-link渲染成指定的标签
14.5默认路由
作用:用来在第一次进入界面时显示一个默认的组件
const router = new VueRouter({
routes: [
// {path: '/', component: login},
//默认路由使用的两种形式
//redirect:当访问的是默认路由 "/" 时,跳转到指定的路由展示 推荐使用此方式
{path: '/', redirect:'login'},
{path: '/login', component: login},
{path: '/register', component: register},
]
})
14.6路由中的参数传递
方式一参数传递 传统方式
1.1、通过 ? 号的形式拼接参数
<router-link to="/login?id=21&name=tizi" tag="button">登录</router-link>
1.2.组件中获取参数
//声明组件模板
const login = {
template:'<div><h2>登录</h2></div>',
data(){return{}},
methods: {},
created(){
console.log("id: " + this.$route.query.id+" name: "+this.$route.query.name);
}
}
方式二参数传递 restful
2.1通过使用路径方式传递
<router-link to="/register/12/tizi" tag="button">注册</router-link>
//创建路由对象
var router = new VueRouter({
routes:[
{path:'/register/:id/:name',component:register}, //定义路径获取参数
]
});
2.2组件中获取参数
const register = {
template:'<div><h2>注册</h2> {{this.$route.params.name}}</div>',
created() {
console.log("注册组件id:" +this.$route.params.id+" 注册组件name: "+this.$route.params.id);
}
}
14.7嵌套路由
1.声明最外层和内层路由
2.创建路由对象含有嵌套路由 children子路由
3.注册路由对象
4.测试路由
嵌套路由全部代码
<div id="app">
<router-link to="/product"><span>商品管理</span></router-link>
<!--显示路由的组件-->
<router-view></router-view>
</div>
<template id="product">
<div>
<h1>商品管理</h1>
<router-link to="/product/add">商品添加</router-link>
<router-link to="/product/edit">商品编辑</router-link>
<!--显示路由的组件-->
<router-view></router-view>
</div>
</template>
<!-- 引入在线cdn的vue.js地址-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!--引入router.js-->
<script src="./js/vue-router.js"></script>
<script>
//声明组件模板
const product = {
template: "#product"
}
const add = {
template: '<div><h1>商品添加</h1></div>'
}
const edit = {
template: '<div><h1>商品编辑</h1></div>'
}
//定义路由对象
var router = new VueRouter({
routes: [
{path: "/product", component: product,
children:[
{path: "add", component: add},
{path: "edit", component: edit},
]
},
]
})
const app = new Vue({
el: "#app",
data: {},
methods: {},
router//注册路由对象
})
</script>
15. Vue CLI脚手架
15.1什么是CLI
命令行界面(英语:command-line interface,缩写:CLI)是在图形用户界面得到普及之前使用最为广泛的用户界面,它通常不支持鼠标,用户通过键盘输入指令,计算机接收到指令后,予以执行。
15.2什么是Vue CLI
Vue CLI 是一个基于vue.js进行快速开发的完整系统。使用Vue脚手架之后开发页面将是一个完整系统(项目)
15.3Vue CLI优势
-
通过
@vue/cli
实现的交互式的项目脚手架。 -
通过
@vue/cli
+@vue/cli-service-global
实现的零配置原型开发。vue页面 vue.js vue-axios vue-router(一条命令) 都包含
-
一个运行时依赖 (
@vue/cli-service
)- 可升级; 一条命令
- 基于 webpack 构建,并带有合理的默认配置;webpack项目打包方式 编译好的项目源码=>部署直接可用
- 可以通过项目内的配置文件进行配置; 默认配置文件,通过改默认配置文件达到想要的项目环境
- 可以通过插件进行扩展。 vue v-charts elementui
- 一个丰富的官方插件集合,集成了前端生态中最好的工具。Node.js(类似tomcat) Vue VueRouter webpack yarn
-
一套完全图形化的创建和管理 Vue.js 项目的用户界面。
15.4Vue CLI安装
1.环境准备
npm类似于maven node.js类似于tomcat
vue cli3安装以以下为准 也可参考链接:https://blog.csdn.net/xuwei1215225/article/details/89519600
node.js对应npm版本:https://nodejs.org/zh-cn/download/releases/
# 1.npm介绍
node package manager //简称npm。 node.js包管理工具 前端主流技术 npm进行统一管理
maven管理java后端依赖 远程仓库(中心仓库) 阿里云镜像
npm 管理前端系统依赖 远程仓库(中心仓库) 配置淘宝镜像
npm 是 Node.js 官方提供的包管理工具,用于 Node.js 包的发布、传播、依赖控制。npm 提供了命令行工具,使你可以方便地下载、安装、升级、删除包,也可以让你作为开发者发布并维护包。
# 2.下载node.js
Vue CLI 需要 Node.js 8.9 或更高版本 (推荐 8.11.0),此处在网上下载的node.15.0.1版
node.js中文网 http://nodejs.cn/download/
windows系统: .msi(安装包 exe)安装指定位置 .zip(压缩包) 解压缩至指定目录
mac os 系统: .pkg 安装包格式自动配置环境变量 .tar.gz(压缩包) 解压缩至指定目录
# 3.配置node.js环境变量 (安装一般会自动配置)
桌面 计算机=>右键属性=>高级属性=>环境变量 添加如下配置
系统变量=>选择Path 编辑 新建 直接输入node.js目录即可
# 4.cmd命令验证是否安装成功
node -v 输出node版本安装成功,如失败参考网上资料安装配置
npm -v 查看npm版本
# 5.配置淘宝镜像*
百度搜索 npm淘宝镜像,通过命令配置安装
配置命令:npm config set registry https://registry.npm.taobao.org
验证镜像是否成功:npm config get registry
# 6.配置npm下载依赖的位置
npm config ls 执行后看到默认下载cache和prefix是C盘
1.npm config set cache "D:\node.js\cli_path\npm-cache" (更改为创建文件的路径)
2.npm config set prefix "D:\node.js\cli_path\npm-global"
配置之后,在执行第一条命令,可看到默认下载路径已更改
npm config ls 再次验证node.js默认依赖位置
;userconfig C:\Users\user\.npmrc
cache = "D:\\node.js\\cli_path\\npm-cache"
prefix = "D:\\node.js\\cli_path\\npm-global"
registry = "https://registry.npm.taobao.org1/"
sass-binary_site = "https:npm.taobao.org/mirrors/node-sass"
sass_binary_site = "https://npm.taobao.org/mirrors/node-sass"
输出以上内容 成功
2.安装脚手架
# 安装Vue-CLI
npm install @vue/cli -g (cli3的版本) 此处安装是3版本
npm install vue-cli -g (cli2的版本)
# 卸载脚手架
npm uninstall -g @vue/cli //卸载3.x版本脚手架
npm uninstall -g vue/cli //卸载2.x版本脚手架
3.第一个vue脚手架项目
# 1.创建vue脚手架第一个项目
在要创建项目路径的通过如下命令创建
vue init webpack 项目名 回车执行
# 2.项目结构
v_project --->项目名
-build ---> 使用webpack打包使用build依赖
-config ---> 整个项目配置目录
-src ---> 编写vue的源代码[重点]
- assets ---> 存放静态资源[重点]
- components ---> 写Vue组件[重点]
- router ---> 配置项目中的路由[重点]
- App.vue ---> 项目中根组件[重点]
- main.js ---> 项目的主路口[重点]
-static ---> 其它静态
-.babelrc ---> 将ES6语法转为ES5运行
-.editorconfig --->项目编辑配置
-.gitignore --->git版本控制忽略文件
-.postcssrc.js --->源码相关js
-index.html --->项目主页
-package.json --->类似pom.xml 依赖管理 不建议手动更改
-package-lock.json --->对package.json枷锁
-README.md --->项目说明文件
# 3.运行脚手架项目(进入当前项目文件)
npm start
npm run dev
两种命令都可以
运行之后 根据提供的路径端口访问 默认 http://localhost:8080
# 4. 查看可以基于哪些模板创建vue应用程序,通常选择 webpack
vue list //作用意义不大
# 5.Vue Cli中项目开发方式
一切皆组件 一个组件中 js代码 html代码 css样式
1.VueCli开发方式是在项目中开发一个一个组件对应一个业务功能模块,之后可将多个组件组合在一起构成前端系统
2.在使用Vue Cli开发时,不在书写html,编写的是一个组件(.vue结尾的文件),打包时vue cli会将组件编译成运行的html文件
15.5如何开发vue脚手架
Vue cli中一切皆组件
15.6在脚手架中使用axios
安装axios
npm install axios --save-dev
**配置axios 在项目main.js引入axios **
import axios from 'axios';
使用axios
在需要发送异步请求的位置:
this.$http.get("url").then((res)=>{})
this.$http.post("url").then((res)=>{})
16.vue cli crud案例
前端实例
前后端分离,结合springboot开发
项目结构
运行效果
创建脚手架项目
在需要创建项目的文件夹使用 idea命令行终端 或在文件夹 输入以下命令构建项目
vue init webpack 项目名
创建完成后删除 components组件的内容,删除之后创建我们自己的5个组件
此项目中只用到了如下代码内容,简易增删改查开发,其余文件均未修改
Home.vue
<template>
<div>
<h1>欢迎进入</h1>
</div>
</template>
<script>
export default {
name: "Home"
}
</script>
<style scoped>
</style>
Student.vue
<template>
<div>
<h1>学生管理</h1>
</div>
</template>
<script>
export default {
name: "Student"
}
</script>
<style scoped>
</style>
User.vue
<template>
<div>
<h1>用户列表</h1>
<table border="1">
<tr>
<td>编号</td>
<td>姓名</td>
<td>年龄</td>
<td>生日</td>
<td>操作</td>
</tr>
<tr v-for="user in users">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
<td>{{user.bir}}</td>
<td><a href="javascript:;" @click="delRow(user.id)">删除</a> <a :href="'#/user/edit?id='+user.id">修改</a></td>
</tr>
</table>
<a href="#/user/add">添加</a>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "User",
data() {
return {
users:[]
}
},
methods: {
findAll(){//查询所有
this.$http.get("http://localhost:8989/vue/user/findAll?page=1&row=4").then((res)=>{
console.log(res.data)
this.users = res.data.result;
})
},
delRow(id){//删除
console.log(id);
this.$http.get("http://localhost:8989/vue/user/delete?id="+id).then((res)=>{
if (confirm("确认删除"+id+"吗?")){
if(res.data.state){
alert("删除"+id+"成功");
this.findAll();
}
}
})
}
},
created() {
this.findAll();
},
watch:{ //用来监听路由变化
$route:{
handler:function (val,oldVal) {
console.log(val);
if(val.path=='/user'){
this.findAll();
}
},
//深度观察监听
deep:true
}
}
}
</script>
<style scoped>
</style>
UserAdd.vue
<template>
<div>
<h2>用户信息添加</h2>
<form>
用户名:<input type="text" v-model="user.name"><br>
年龄:<input type="text" v-model="user.age"><br>
生日:<input type="text" v-model="user.bir"><br>
<input type="button" value="添加" @click="saveUserInfo()">
</form>
</div>
</template>
<script>
export default {
name: "UserAdd",
data() {
return {
user: {},
}
},
methods: {
saveUserInfo() {
//发送axios请求 添加数据
console.log(this.user);
this.$http.post("http://localhost:8989/vue/user/add", this.user).then((res) => {
if (res.data.state) {
this.$router.push("/user");//数据添加至用户页的路由
}
})
}
}
}
</script>
<style scoped>
</style>
UserEdit.vue
<template>
<div>
<h2>编辑信息</h2>
<form action="">
用户名:<input v-model="user.name" type="text">
年龄:<input v-model="user.age" type="text">
生日:<input v-model="user.bir" type="text"><br>
<input type="button" @click="editUserInfo()" value="提交">
</form>
</div>
</template>
<script>
export default {
name: "UserEdit",
data() {
return {
user: {
id: "",
}
}
},
methods: {
findOne() {//查询一个内容
this.$http.get("http://localhost:8989/vue/user/findOne?id=" + this.user.id).then((res) => {
this.user = res.data;
});
},
editUserInfo() {
this.$http.post("http://localhost:8989/vue/user/update", this.user).then((res) => {
console.log(res);
if (res.data.state) {
this.$router.push("/user");//切换路由
}
});
}
},
created() {
console.log("修改组件id:" + this.$route.query.id);
this.user.id = this.$route.query.id;
this.findOne();
}
}
</script>
<style scoped>
</style>
router/index.js路由配置
import Vue from 'vue'
import Router from 'vue-router'
import Home from "../components/Home";
import User from "../components/User";
import Student from "../components/Student";
import UserAdd from "../components/UserAdd";
import UserEdit from "../components/UserEdit";
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
redirect:'Home'
},
{
path: '/home',
component: Home
},
{
path: '/user',
component: User,
children:[
{
path:'add',
component:UserAdd //嵌套路由 用户添加
},
{
path: 'edit',
component: UserEdit
}
]
},
{
path: '/student',
component: Student
},
]
})
App.vue
<template>
<div id="app">
<router-link to="/home">主页</router-link>
<router-link to="/user">用户管理</router-link>
<router-link to="/student">学生管理</router-link>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
</style>
后端实例
后端给前端提供数据,前端请求后端给予响应
项目结构
准备sql
/*
SQLyog Ultimate v12.3.1 (64 bit)
MySQL - 5.7.20-log : Database - stu_newest
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`stu_newest` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `stu_newest`;
/*Table structure for table `v_pro` */
DROP TABLE IF EXISTS `v_pro`;
CREATE TABLE `v_pro` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`name` varchar(40) DEFAULT NULL,
`age` int(4) DEFAULT NULL,
`bir` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
/*Data for the table `v_pro` */
insert into `v_pro`(`id`,`name`,`age`,`bir`) values
(1,'admin',15,'2021-03-28 13:33:20'),
(8,'tizi',21,'1999-07-06 08:00:00'),
(9,'idea test',0,'1999-03-05 08:00:00');
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
User实体
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Accessors(chain = true)
public class User {
private Integer id;
private String name;
private Integer age;
@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GTM+8")
private Date bir;
}
UserMapper
@Mapper
public interface UserMapper {
//添加
void save(User user);
//查出一个值
User findById(Integer id);
//修改
void update(User user);
//删除
void delete(Integer id);
//查询所有值
public List<User> findAll();
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace=绑定一个指定的dao/mapper接口-->
<mapper namespace="com.lemon.dao.UserMapper">
<!--查询所有的值-->
<select id="findAll" resultType="user">
select id,name,age,bir from v_pro
</select>
<select id="findById" resultType="user">
SELECT id,NAME,age, bir FROM v_pro WHERE id = #{id}
</select>
<update id="update" parameterType="user">
update v_pro
set name=#{name},age=#{age},bir=#{bir}
where id = #{id}
</update>
<delete id="delete" parameterType="integer">
delete from v_pro where id = #{id}
</delete>
<insert id="save" parameterType="user" useGeneratedKeys="true" keyProperty="id">
insert into v_pro values (#{id},#{name},#{age},#{bir})
</insert>
</mapper>
UserService
public interface UserService {
//添加
void save(User user);
//查出一个值
User findById(Integer id);
//修改
void update(User user);
//删除
void delete(Integer id);
//查询所有值
public List<User> findAll();
}
UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
@Override
public void save(User user) {
userMapper.save(user);
}
@Override
public User findById(Integer id) {
return userMapper.findById(id);
}
@Override
public void update(User user) {
userMapper.update(user);
}
@Override
public void delete(Integer id) {
userMapper.delete(id);
}
@Override
public List<User> findAll() {
return userMapper.findAll();
}
}
application.properties
spring.application.name=vue
server.port=8989
server.servlet.context-path=/vue
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/stu_newest?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=12345678
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.type-aliases-package=com.lemon.entity
logging.level.root=info
logging.level.com.lemon.dao=debug
UserController控制器
@RestController
@CrossOrigin
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
/**
* 更新值
*/
@PostMapping("/update")
public Map<String, Object> update(@RequestBody User user) {
Map<String, Object> map = new HashMap<>();
try {
userService.update(user);
map.put("state", true);
map.put("msg", "修改成功");
} catch (Exception e) {
map.put("state", false);
map.put("msg", "修改失败: " + e.getMessage());
}
return map;
}
/**
* 查询一个
*/
@GetMapping("/findOne")
public User findOne(Integer id) {
return userService.findById(id);
}
/**
* 删除用户
*/
@GetMapping("/delete")
public Map<String, Object> delete(Integer id) {
System.out.println("删除id:" + id);
Map<String, Object> map = new HashMap<>();
try {
userService.delete(id);
map.put("state", true);
map.put("msg", "删除成功");
} catch (Exception e) {
e.printStackTrace();
map.put("state", false);
map.put("msg", "删除失败: " + e.getMessage());
}
return map;
}
/**
* 添加用户
*/
@PostMapping("/add")
public Map<String, Object> add(@RequestBody User user) {
System.out.println("front user: " + user);
Map<String, Object> map = new HashMap<>();
try {
userService.save(user);
map.put("state", true);
map.put("msg", "添加成功");
} catch (Exception e) {
e.printStackTrace();
map.put("state", false);
map.put("msg", "添加失败: " + e.getMessage());
}
return map;
}
/**
* 查询所有
*
* @return
*/
@GetMapping("/findAll")
public Map<String, Object> findAll(Integer page, Integer rows) {
Map<String, Object> map = new HashMap<>();
List<User> result = userService.findAll();
map.put("total", 10);
map.put("totalPage", 1);
map.put("page", 1);
map.put("result", result);
return map;
}
}
17.vue cli脚手架项目打包和部署
# 1.在前端项目的根目录中 执行如下命令即可打包
npm run build
注意vue脚手架打包的项目必须在服务器上运行,不能直接双击运行
# 2.打包之后项目中变化
在打包之后项目中出现dist目录,此目录就是vue脚手架项目的生产目录 或者 说是直接部署目录
打包成功之后当前项目会多出一个dist目录,将dist目录复制到idea static文件目录,修改index.html页面配置,直接也可运行
运行完成,此文章总结完毕,感谢您的参考和观看 thank~
该文章是vue进阶篇
入门篇链接地址 https://blog.csdn.net/qq_41157588/article/details/115085686 ,代码很全 供学习参考,更直观了解vue+springboot结合开发
需要全套源码及pdf文件 请 评论留言 或 发送邮箱至 ti66666@vip.qq.com
vue进阶篇总结到此结束,一字字总结不易,点个赞收藏评论支持下,你的支持是我创造的动力,thank~