此文为vue进阶篇,包含vue路由、组件、axios请求以及结合springboot开发实例
入门篇链接地址https://blog.csdn.net/qq_41157588/article/details/115085686
代码完整无水分,供学习参考,更多了解信息请看文末.
总结不易 点赞评论 支持 thank ~
Axios是一个异步请求技术,核心作用就是用来在页面中发送异步请求,
并获取对应数据在在页面中渲染 页面局部更新技术 Ajax
Axios中文网 http://www.axios-js.com/zh-cn/docs/
$ npm install axios
$ bower install axios
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 delete(String id){
Map map = new HashMap<>();
System.out.println("id = " + id);
map.put("success",true);
return map;
}
//保存数据
@CrossOrigin//解决跨域的注解
@PostMapping("save")
public Map delete(@RequestBody User user){
Map map = new HashMap<>();
System.out.println("user = " + user);
map.put("success",true);
return map;
}
//展示索引
@CrossOrigin//解决跨域的注解
@GetMapping("findAll")
public List findAll(String id){
System.out.println("id = " + id);
List users = new ArrayList<>();
users.add(new User(1,"axios测试值1","[email protected]",21,"15155556666"));
users.add(new User(2,"axios测试值2","[email protected]",22,"15656667777"));
users.add(new User(3,"axios测试值3","[email protected]",23,"17666663959"));
return users;
}
}
数据准备完成。接下来准备上手axios的get和post请求,测试请求要注意和后端服务端口对应
Axios GET请求Vue代码
axios的GET方式请求使用
axios的POST方式请求使用
并发请求:将多个请求在同一时刻发送后到后端服务接口,最后在集中处理每个请求的响应结果
axios并发请求
此时在IDEA和网页的NetWork看到执行了两条请求
上图WeatherController代码 (注意:前端请求端口要和后端的端口对应)
@RestController
@RequestMapping("city")
public class WeatherController {
@GetMapping("/find")
@CrossOrigin//跨域注解
//http://localhost:8989/city/find?name=江苏
public Map findWeatherByCity(String name){
Map map = new HashMap<>();
String weathers = getWeathers(name);
// map.put(name,weathers);
map.put("CityWeatherMsg",weathers);
return map;
}
//返回对应城市的天气情况
public String getWeathers(String name) {
Map weathers = new HashMap<>();
weathers.put("河南","晴天 23℃-27℃,天气情况良好");
weathers.put("江苏","多云转阴 20℃-26℃,天气挺好");
weathers.put("北京","大雨 14℃-19℃,天气很不好");
weathers.put("上海","多云 27℃-31℃,天气可以");
return weathers.get(name);
}
}
vue结合axios天气查询案例
生命周期钩子 => 生命周期函数
最终效果图
自行添加更多的数据
/*
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 */;
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
@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;
}
@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);
}
@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();
}
<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>
<update id="update" parameterType="user">
update v_user set name=#{name},age=#{age},salary=#{salary},phoneCode=#{phoneCode} where id = #{id}
update>
<select id="findOne" resultType="user" >
select id,name,age,salary,phoneCode from v_user where id = #{id}
select>
<delete id="del" parameterType="Integer">
delete from v_user where id = #{id}
delete>
<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>
<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>
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);
}
@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);
}
}
public interface PageService {
/**
* @param page 当前页
* @param rows 每页显示的记录数
* @return
*/
public List<User> findByPage(Integer page,Integer rows);
/**
* 查询总条数
* @return
*/
public Integer findTotals();
}
@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();
}
}
@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;
}
}
@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;
}
}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User Managertitle>
<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">
<div class="navbar-header">
<a class="navbar-brand" href="#">简易用户管理系统a>
div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">xa>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>IDth>
<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" 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" @click="pagePart(page+1)">下一页>a>
div>
div>
<script src="../static/js/vue.js">script>
<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静态文件为 bootstrap vue.js vue.min.axios 此处没有放入这些文件,可以尝试在inedx.html删除现有的link和script 导入如下cdn
@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);
});
}
}
组件作用:用来减少vue实例对象中代码量,之后在使用vue开发的过程中,可根据不用业务功能划分不同的多个组件,然后由多个组件去完成整个页面的布局,便于以后使用vue开发时页面管理,方便开发人员维护
全局组件注册给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.如在注册组件时使用驼峰式命名时,注意在调用时用 - 来衔接,全部小写,如下示例
Vue.component('userLogin', {
template: '用户登录
'
})
通过将组件注册给对应Vue实例中一个components属性来完成组件注册,这种方式不会对Vue实例造成累加
局部组件注册推荐使用第二种
第一种开发方式
-----------------------------------------------------------------------
第二种开发方式
用户登录
官网示例
prop用来给组件传递相应静态数据或动态数据
//1.声明组件模板对象
let login = {
template: "欢迎:{{userName}} age:{{age}}
",
props:['userName','age'] //props 用来接收使用组件时通过组件中标签传递的数据
}
//2.注册组件
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: {
login //组件注册
}
})
//3.通过组件完成数据传递
# 总结
1.使用组件时可以再组件上定义多个属性以及对应数据
2.在组件内部可以使用props数组声明多个定义在组件上的属性名,之后可以在组件中通过{{属性名}}方式获取组件中属性值
//1.声明组件模板对象
let comp = {
template: '欢迎:{{name}}
年龄:{{age}}',
props:['name','age']
}
//2.注册局部组件
const app = new Vue({
el: "#app",
data: {
username:"提先森",
age:21
},
methods: {},
components: {
login:comp, //注册组件
}
})
//3.使用组件
使用v-bind形式将数据绑定在vue实例中data属性,之后data属性发生变化,组件内部数据跟着变化
所有的 prop 都使得其父子 prop 之间形成了一个 单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行
所有 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。 ------摘自官网
1.组件中定义属于组件的数据
//组件声明的配置对象
let comp = {
template: '' +
'平淡安好
' +
'{{msg}}' +
'- {{index+1}} {{list}}
'+
'',
data() { //组件中自己的数据 使用data函数定义组件的属性 在template代码中通过插值表达式获取值
return {
msg: "template data",
lists:["java","php","python"]
}
}
}
const app = new Vue({
el: "#app",
data: {},
methods: {},
components: {
login: comp //注册组件
}
})
2.组件中事件定义
vue路由的cdn 在 Vue 后面加载 vue-router,会自动安装的
2.创建组件对象
const login = {
template: '登录
'
}
const register = {
template: '注册
'
}
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.在页面中显示路由组件 根据链接切换路由(注意路径前加 #)
完整代码
点击登录
点击注册
作用:用来替换在切换路由时使用 a 标签切换路由
好处:可以自动给路由路径加入 # ,不需要手动加入
点击登录
点击注册
# 总结
1.router-link 用来替换使用a标签实现路由切换,好处是不需要书写 # 号,直接写路由路径
2.router-link to 属性用来书写路由路径 tag属性:用来将router-link渲染成指定的标签
作用:用来在第一次进入界面时显示一个默认的组件
const router = new VueRouter({
routes: [
// {path: '/', component: login},
//默认路由使用的两种形式
//redirect:当访问的是默认路由 "/" 时,跳转到指定的路由展示 推荐使用此方式
{path: '/', redirect:'login'},
{path: '/login', component: login},
{path: '/register', component: register},
]
})
方式一参数传递 传统方式
1.1、通过 ? 号的形式拼接参数
登录
1.2.组件中获取参数
//声明组件模板
const login = {
template:'登录
',
data(){return{}},
methods: {},
created(){
console.log("id: " + this.$route.query.id+" name: "+this.$route.query.name);
}
}
方式二参数传递 restful
2.1通过使用路径方式传递
注册
//创建路由对象
var router = new VueRouter({
routes:[
{path:'/register/:id/:name',component:register}, //定义路径获取参数
]
});
2.2组件中获取参数
const register = {
template:'注册
{{this.$route.params.name}}',
created() {
console.log("注册组件id:" +this.$route.params.id+" 注册组件name: "+this.$route.params.id);
}
}
1.声明最外层和内层路由
2.创建路由对象含有嵌套路由 children子路由
3.注册路由对象
4.测试路由
嵌套路由全部代码
商品管理
商品管理
商品添加
商品编辑
Vue-CLI官网
命令行界面(英语:command-line interface,缩写:CLI)是在图形用户界面得到普及之前使用最为广泛的用户界面,它通常不支持鼠标,用户通过键盘输入指令,计算机接收到指令后,予以执行。
Vue CLI 是一个基于vue.js进行快速开发的完整系统。使用Vue脚手架之后开发页面将是一个完整系统(项目)
通过 @vue/cli
实现的交互式的项目脚手架。
通过 @vue/cli
+ @vue/cli-service-global
实现的零配置原型开发。
vue页面 vue.js vue-axios vue-router(一条命令) 都包含
一个运行时依赖 (@vue/cli-service
)
一套完全图形化的创建和管理 Vue.js 项目的用户界面。
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文件
Vue cli中一切皆组件
安装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)=>{})
前后端分离,结合springboot开发
在需要创建项目的文件夹使用 idea命令行终端 或在文件夹 输入以下命令构建项目
vue init webpack 项目名
创建完成后删除 components组件的内容,删除之后创建我们自己的5个组件
此项目中只用到了如下代码内容,简易增删改查开发,其余文件均未修改
欢迎进入
学生管理
用户信息添加
编辑信息
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
},
]
})
主页
用户管理
学生管理
后端给前端提供数据,前端请求后端给予响应
/*
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 */;
@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;
}
@Mapper
public interface UserMapper {
//添加
void save(User user);
//查出一个值
User findById(Integer id);
//修改
void update(User user);
//删除
void delete(Integer id);
//查询所有值
public List findAll();
}
update v_pro
set name=#{name},age=#{age},bir=#{bir}
where id = #{id}
delete from v_pro where id = #{id}
insert into v_pro values (#{id},#{name},#{age},#{bir})
public interface UserService {
//添加
void save(User user);
//查出一个值
User findById(Integer id);
//修改
void update(User user);
//删除
void delete(Integer id);
//查询所有值
public List findAll();
}
@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 findAll() {
return userMapper.findAll();
}
}
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
@RestController
@CrossOrigin
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
/**
* 更新值
*/
@PostMapping("/update")
public Map update(@RequestBody User user) {
Map 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 delete(Integer id) {
System.out.println("删除id:" + id);
Map 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 add(@RequestBody User user) {
System.out.println("front user: " + user);
Map 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 findAll(Integer page, Integer rows) {
Map map = new HashMap<>();
List result = userService.findAll();
map.put("total", 10);
map.put("totalPage", 1);
map.put("page", 1);
map.put("result", result);
return map;
}
}
# 1.在前端项目的根目录中 执行如下命令即可打包
npm run build
注意vue脚手架打包的项目必须在服务器上运行,不能直接双击运行
# 2.打包之后项目中变化
在打包之后项目中出现dist目录,此目录就是vue脚手架项目的生产目录 或者 说是直接部署目录
打包成功之后当前项目会多出一个dist目录,将dist目录复制到idea static文件目录,修改index.html页面配置,直接也可运行
该文章是vue进阶篇
入门篇链接地址 https://blog.csdn.net/qq_41157588/article/details/115085686 ,代码很全 供学习参考,更直观了解vue+springboot结合开发
需要全套源码及pdf文件 请 评论留言 或 发送邮箱至 [email protected]
vue进阶篇总结到此结束,一字字总结不易,点个赞收藏评论支持下,你的支持是我创造的动力,thank~