文章目录
Vue.js学习系列(一):1~4章
Vue.js学习系列(二):5~8章
Vue.js学习系列(三):9~12章
Vue.js学习系列(四)
十三、Vue-router路由
13.1 安装路由模块
方式一:
在创建项目时安装路由模块
1. 创建项目命令 : vue init 框架名 项目名 (如:
vue init webpack my-vue-demo1
) 2.Install vue-router,该处选择 “y”
方式二:
项目创建后手动安装路由模块
1.进项项目工程目录
2.输入命令:
npm install vue-router --save
安装成功项目目录结果:
13.2 设计路由界面
修改
index.html
,引入bootstrap的样式、js
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
修改
App.vue
,根据bootstrap官方文档编写标签
<template>
<div id="app">
<ul class="nav nav-tabs">
<li role="presentation" class="active">首页</li>
<li role="presentation">商品列表</li>
</ul>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
效果:
13.3 修改静态路由表
13.4 引入路由模块并使用
在main.js中引入路由模块并使用
import Vue from 'vue'
import App from './App'
import VueRouter from 'vue-router' //1.引入路由模块
import {routes} from './routes' //2.引入静态路由表(即src的routes文件里的index.js)
Vue.use(VueRouter); //3.使用路由模块
//4.创建一个VueRouter模块的实例
const router = new VueRouter({
routes:routes
})
/* eslint-disable no-new */
new Vue({
el: '#app',
router, //5.把router实例放入到vue实例中
components: { App },
template: '<App/>'
})
13.5 路由的实现
13.5.1 链接路由的实现
通过标签实现链接路由,而页面将会显示在里面
局限性:
- 每次路由都需要
创建Head.vue
<template>
<ul class="nav nav-tabs">
<li role="presentation" class="active"><router-link to="/Home">首页</router-link></li>
<li role="presentation"><router-link to="/Product/1314520">商品列表</router-link></li>
</ul>
</template>
修改App.vue
<template>
<div id="app">
<Home></Home>
<router-view/>
</div>
</template>
<script>
import Home from '@/components/Head.vue'
export default {
name: 'App'
components: {'Home':Home}
}
</script>
13.5.2 程序式路由的实现
通过 JS 实现程序式路由
13.6 参数的传递
参数的传递:设参、传参、接参
-
设参——在路由表(router/index.js)里设置参数
-
传参——主组件,路由链接处进行传参
(1)方式一:链接式路由实现传参跳转
(2)方式二:程序式路由实现传参跳转
-
接参——子组件中进行接参
this.$route.params.id:意思即为获取当前组件路由表里参数为id属性的值
$route.params:当前组件的route对象的params属性(里面含有大量参数)
【注意: r o u t e 和 route和 route和router的区别】
- $route:某一个路由对象
- $router:代表路由器
十四、使用Axios发送请求
14.1 什么是Axios(第三方组件)
Axios 是一个开源的可以用在浏览器端和Node.js的
异步通信框架
,她的主要作用就是实现AJAX
异步通信,其功能特点如下:
- 从浏览器中创建
XMLHttpRequests
- 从
node.js
创建http
请求- 支持
Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换
JSON
数据- 客户端支持防御
XSRF
(跨站请求伪造)GitHub:https://github.com/axios/axios
14.2 为什么要使用Axios
由于Vue.js是一个视图层框架并且作者(尤雨溪)严格准守
Soc
(关注度分离原则),所以Vue.js并不包含Ajax的通信功能,为了解决通信问题,作者单独开发了一个名为vue-resource
的插件,不过在进入2.0版本以后停止了对该插件的维护并推荐了Axios框架
14.3 Axios的使用
14.3.1 安装vue axios
#在项目工程文件根目录下输入命令
npm install --save axios vue-axios
14.3.2 在main.js中引入
在项目中使用axios模块
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios) //使用VueAxios和axios模块
14.3.3 使用Axios发送ajax请求
服务端请求路径和代码:
地址:localhost:8090/regist
//注册控制器
@RequestMapping(Value="registByGet", method= RequestMethod.GET)
public String regist(String mail, String password) {
System.out.println(mail);
System.out.println(password);
return "regist success!";
}
前端发布地址和主组件(App.vue)使用
Axios发送ajax请求
代码:发布地址:http://localhost:8080
<template>
<div id="app">
<div style="width: 50%" class="container">
<div>
<h3>注册</h3>
<h5>邮箱</h5>
<input type="text" class="form-control" v-model="mail" /><br />
{{mail}}
<h5>密码</h5>
<input type="password" class="form-control" v-model="password" /><br />
{{password}}
<h5>性别</h5>
<input type="radio" name="gender" v-model="gender" value="male" />男
<input type="radio" name="gender" v-model="gender" value="female" />女
<br /><br />
<h5>爱好</h5>
<input type="checkbox" name="hobby" v-model="hobby" value="music" />音乐
<input type="checkbox" name="hobby" v-model="hobby" value="music" />电影
<input type="checkbox" name="hobby" v-model="hobby" value="music" />编程
<br />
<button type="button" class="btn btn-success" @click="registfn">注册</button>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
mail: "",
password: "",
gender: "",
hobby: ""
}
},
methods: {
registfn() {
//使用axios发送ajax请求
this.axios({
method: "get", //请求方式
url: "http://localhost:8090/regist?mail="+this.mail+"&password="+this.password //请求路径
}).then(function(response) {
console.log(response);
})
}
}
}
</script>
【注意】此时因为服务端发布地址与前端发布地址涉及到了
跨域问题
(即服务端是:8090,而前端是:8080),服务端需要解决跨域问题(解决方法请看14.3.4节
)。
14.3.4 服务端解决跨域问题
在spring-mvc.xml配置文件中加入下面代码。其中,
allowed-origins
指的是允许的访问源的域名,“ * ” 表示任何人都可以访问,也可以指明具体的域名
<!-- 使用Cors解决跨域问题 需要springMvc4.2版本以上-->
<mvc:cors>
<mvc:mapping path="/**"
allowed-origins="*"
allowed-methods="POST, GET, OPTIONS, DELETE, PUT, PATCH"
allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
allow-credentials="true" />
</mvc:cors>
14.3.5 解决axios无法传递data中的参数问题
原因:
默认情况下发送axios时请求头中的内容类型为:(且后端没有使用
@RequestBody
注解,若后端有 @RequestBody注解,则不需要进行内容类型转换)Content-Type:application/json;charset=UTF-8
而实际服务端需要的是:
Content-Type:application/x-www-form-urlencoded
因此使用axios的qs内置库中的方法进行内容类型的转换
<template>
<div id="app">
<div style="width: 50%" class="container">
<div>
<h3>注册</h3>
<h5>邮箱</h5>
<input type="text" class="form-control" v-model="mail" /><br />
{{mail}}
<h5>密码</h5>
<input type="password" class="form-control" v-model="password" /><br />
{{password}}
<h5>性别</h5>
<input type="radio" name="gender" v-model="gender" value="male" />男
<input type="radio" name="gender" v-model="gender" value="female" />女
<br /><br />
<h5>爱好</h5>
<input type="checkbox" name="hobby" v-model="hobby" value="music" />音乐
<input type="checkbox" name="hobby" v-model="hobby" value="music" />电影
<input type="checkbox" name="hobby" v-model="hobby" value="music" />编程
<br />
<button type="button" class="btn btn-success" @click="registfn">注册</button>
</div>
</div>
</div>
</template>
<script>
import Qs from 'qs'
export default {
name: 'App',
data() {
return {
mail: "",
password: "",
gender: "",
hobby: ""
}
},
methods: {
registfn() {
//使用axios发送ajax请求
this.axios({
method: "post", //请求方式
url: "http://localhost:8080/registByPost", //请求路径
transformRequest: [function(data) {
return Qs.stringify(data) //使用QS对data进行类型转换
}],
data: {
email: this.email,
password: this.password
}
}).then(function(response) {
alert(response.data.message)
})
}
}
}
</script>
//服务端——请求路径控制器
@RequestMapping(Value="registByPost", method= RequestMethod.POST)
public String registByPost(String mail, String password) {
System.out.println(mail);
System.out.println(password);
return "regist success!";
}
十五、Vue实战项目:Webpack登录验证后路由至列表页(使用 Element_UI)
15.1 安装使用Element UI 框架步骤
- 在项目工程目录下,输入安装Element UI命令:
npm i element-ui -S
- 安装Element 所需的依赖
npm install
根据Element UI官方文档进行环境设置
官方地址:https://element.eleme.cn/#/zh-CN
参考官方文档的快速上手引入Element
在main.js中写入以下内容:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
15.2 后端服务器实体类与接口
后端项目的发布地址: http://localhost:8080
后端服务器接口:
接受参数的类型使用
@RequestBody
注解,会把参数类型转为json格式,所以前端传过来的数据不需要进行转换
@RequestMapping(value="login", method = RequestMethod.POST)
@ResponseBody
public String login(@RequestBody User user) {
String username = user.getUsername();
String password = user.getPassword();
if("xiaohei".equals(username) && "1314520".equals(password)) {
return "success";
}
return "error";
}
15.3 前端页面项目创建
前端项目的发布地址: http://localhost:8090
登录页面效果图显示 |
---|
![]() |
-
创建前端vue项目
需要安装路由、安装所需依赖
vue install webpack my-vue-demo3
-
项目创建完成后,在src目录下新建views文件夹
-
在views文件夹下新建两个组件(Login.vue 和 Home.vue)
-
修改路由列表,添加Login、Home组件
【注意】
@:代表全局路径
@/views/Login 等同于 …/views/Login
-
安装Element UI
在项目工程目录下输入命令:
npm i element-ui -S
-
引入Element UI组件
在main.js引入Element UI模块
import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);
-
编写Login.vue组件页面
使用Element UI 框架进行页面搭建
具体用法参考Element UI 官方文档:https://element.eleme.cn/#/zh-CN/component/form
<template> <div class="login-box"> <el-form ref="form" :model="form" :rules="rules" label-width="80px"> <h3>欢迎登录</h3> <el-form-item label="用户名" prop="username"> <el-input v-model="form.username"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" v-model="form.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit('form')">登录</el-button> <el-button>取消</el-button> </el-form-item> </el-form> </div> </template> <script> export default { name: "Login", data() { return { form: { username: '', password: '', }, rules: { username: [ { required: true, message: '请输入用户名', trigger: 'blur' }, { min: 5, max: 10, message: '长度在 5 到 10 个字符', trigger: 'blur' } ], password: [ { required: true, message: '请输入密码', trigger: 'blur' }, { min: 5, max: 10, message: '长度在 5 到 10 个字符', trigger: 'blur' } ], } } }, methods: { onSubmit(formData) { this.$refs[formData].validate((valid) => { var vm = this; //获取当前vue对象 if (valid) { alert('登录成功!'); } else { this.$message.error('存在选项不符合要求!!'); return false; } }); } } } </script> <style scoped> .login-box { width: 500px; border: 1px solid #DCDFE6; border-radius: 20px; margin: 0 auto; padding: 10px 40px 10px 20px; box-shadow: 0px 0px 20px #DCDFE6; } </style>
rules:Element UI框架的Form 组件的表单验证功能,只需要通过
rules
属性传入约定的验证规则,并将 Form-Item 的prop
属性设置为需校验的字段名。 -
使用Axios发送请求到后端服务器进行校验(后端接口)
使用到Axios,需要安装vue axios,步骤如下:
-
项目工程根目录下输入命令:
#在项目工程文件根目录下输入命令 npm install --save axios vue-axios
-
在main.js中引入axios模块
import Vue from 'vue' import axios from 'axios' import VueAxios from 'vue-axios' Vue.use(VueAxios, axios) //使用VueAxios和axios模块
onSubmit函数使用Axios传值进行用户验证,若登录成功实现跳转到首页,代码如下:
<template> <div class="login-box"> <el-form ref="form" :model="form" :rules="rules" label-width="80px"> <h3>欢迎登录</h3> <el-form-item label="用户名" prop="username"> <el-input v-model="form.username"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" v-model="form.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit('form')">登录</el-button> <el-button>取消</el-button> </el-form-item> </el-form> </div> </template> <script> export default { name: "Login", data() { return { form: { username: '', password: '', }, rules: { username: [ { required: true, message: '请输入用户名', trigger: 'blur' }, { min: 5, max: 10, message: '长度在 5 到 10 个字符', trigger: 'blur' } ], password: [ { required: true, message: '请输入密码', trigger: 'blur' }, { min: 5, max: 10, message: '长度在 5 到 10 个字符', trigger: 'blur' } ], } } }, methods: { onSubmit(formData) { this.$refs[formData].validate((valid) => { var vm = this; //获取当前vue对象 if (valid) { //发送axios请求 this.axios({ method: 'post', url: 'http://localhost:8080/login', data: { username: vm.form.username, //此处不可以用 this.form.username,因为这里用this指的是axios对象 password: vm.form.password }.then(function(response){ if(response.data == "success") { //Element的消息提示弹框 vm.$message({ message: '登录成功', type: 'success' }); //定时器实现跳转到首页(2秒后跳转首页) setTimeout(function (){ vm.$router.push("/Home") },2000); } else { vm.$message.error('用户名或密码错误!!'); } }) }) } else { this.$message.error('存在不符合要求的选项!!'); return false; } }); } } } </script> <style scoped> .login-box { width: 500px; border: 1px solid #DCDFE6; border-radius: 20px; margin: 0 auto; padding: 10px 40px 10px 20px; box-shadow: 0px 0px 20px #DCDFE6; } </style>
-
十六、Vuex的应用
结合
十五节
的实战项目讲解使用Vuex:主要实现功能:登录成功后跳转到首页,需要显示登录人信息
【思路:】登录页面(即Login.vue)校验成功跳转到首页(Home.vue)时,需要向首页传递
user
对象,而该user对象的存储就存在Vuex里。(即:登录成功,要向Vuex中存放user对象)
16.1 什么是Vuex
Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
16.2 安装
在项目根目录执行如下命令来安装Vuex
若失败,可使用cnpm进行安装
npm install vuex --save
修改
main.js
文件,导入Vuex,关键代码如下:
import Vuex from 'vuex'
Vue.use(Vuex)
16.3 配置Vuex
16.3.1 创建Vuex配置文件
在
src
目录下创建一个名为store
的目录并新建一个名为index.js
文件用来配置Vuex,代码如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
// 全局 state 对象,用于保存所有组件的公共数据
const state = {
// 定义一个 user 对象
// 在组件中是通过 this.$store.state.user 来获取
user: {
username: ''
}
};
// 实时监听 state 值的最新状态,注意这里的 getters 可以理解为计算属性
const getters = {
// 在组件中是通过 this.$store.getters.getUser 来获取
getUser(state) {
return state.user;
}
};
// 定义改变 state 初始值的方法,这里是唯一可以改变 state 的地方,缺点是只能同步执行
const mutations = {
// 在组件中是通过 this.¥store.commit('updateUser', user); 方法来调用 mutations
updateUser(state, user) {
state.user = user;
}
};
// 定义触发 mutations 里函数的方法,可以异步执行 mutations 里的函数
const actions = {
// 在组件中是通过 this.$store.dispatch('asyncUpdateUser', user); 来调用 actions
asyncUpdateUser(context, user) {
context.commit('updateUser', user);
}
};
// 暴露Vuex.Store,便于使用里面的state、getters...
export default new Vuex.Store({
state,
getters,
mutations,
actions
});
修改
main.js
增加刚才配置的store/index.js
,关键代码如下:
import Vue from 'vue'
import Vuex from 'vuex'
import store from './store'
Vue.use(Vuex);
new Vue({
el: '#app',
store
})
修改后端服务器控制器代码:
- 添加实体类——ResultBean
public class ResultBean implements Serializable{
private static final long serialVersionUID = 1L;
//结果的状态码:1表示返回的是错误信息,0表示返回的是正确(正常)的信息
private int errno;
//结果的数据
private Object data;
//具体的信息
private String message;
/**
* 返回成功的结果
* @return
*/
public static ResultBean success() {
ResultBean resultBean = new ResultBean();
resultBean.setErrno(0);
resultBean.setData(null);
resultBean.setMessage("success");
return resultBean;
}
/**
* 返回成功的结果
* @param data 具体的数据
* @return
*/
public static ResultBean success(Object data) {
ResultBean resultBean = new ResultBean();
resultBean.setErrno(0);
resultBean.setData(data);
resultBean.setMessage("success");
return resultBean;
}
/**
* 返回成功的结果
* @param message 具体的信息
* @return
*/
public static ResultBean success(String message) {
ResultBean resultBean = new ResultBean();
resultBean.setErrno(0);
resultBean.setData(null);
resultBean.setMessage(message);
return resultBean;
}
/**
* 返回成功的结果
* @param data 具体的数据
* @param message 具体的信息
* @return
*/
public static ResultBean success(Object data, String message) {
ResultBean resultBean = new ResultBean();
resultBean.setErrno(0);
resultBean.setData(data);
resultBean.setMessage(message);
return resultBean;
}
/**
* 返回错误的结果
* @return
*/
public static ResultBean error() {
ResultBean resultBean = new ResultBean();
resultBean.setErrno(1);
resultBean.setData(null);
resultBean.setMessage("error");
return resultBean;
}
/**
* 返回错误的结果
* @param message 具体的错误信息
* @return
*/
public static ResultBean error(String message) {
ResultBean resultBean = new ResultBean();
resultBean.setErrno(1);
resultBean.setData(null);
resultBean.setMessage(message);
return resultBean;
}
//getter 和 setter...
}
- 修改控制器(接口)代码(控制器使用注解:
@RestController
,该 注解等同于 @Controller 与 @ResponseBody 结合)
@RequestMapping(value="login", method = RequestMethod.POST)
@ResponseBody
public ResultBean login(@RequestBody User user) {
String username = user.getUsername();
String password = user.getPassword();
if("xiaohei".equals(username) && "1314520".equals(password)) {
return ResultBean.success(user);
}
return ResultBean.error("用户名或密码错误");
}
修改
Login.vue
的onSubmit方法,登录成功,向Vuex中存放user对象
methods: {
onSubmit(formData) {
this.$refs[formData].validate((valid) => {
var vm = this; //获取当前vue对象
if (valid) {
alert('登录成功!');
//发送axios请求
this.axios({
method: 'post',
url: 'http://localhost:8080/login',
data: {
username: vm.form.username, //此处不可以用 this.form.username,因为这里用this指的是axios对象
password: vm.form.password
}.then(function(response){
if(response.data == "success") {
//登录成功,向Vuex中存放user对象
var user = response.data.data;
vm.$store.dispatch('asyncUpdateUser', user)
//Element的消息提示弹框
vm.$message({
message: '登录成功',
type: 'success'
});
//定时器实现跳转到首页(2秒后跳转首页)
setTimeout(function (){
vm.$router.push("/Home")
},2000);
} else {
vm.$message.error('用户名或密码错误!!');
}
})
})
} else {
this.$message.error('存在选项不符合要求!!');
return false;
}
});
}
}
修改
Home.vue
,获取store的user值,代码如下
<template>
<div>
主页面
<hr>
欢迎您! {{user.name}}
</div>
</template>
<script>
export default {
name: "Home",
data() {
return {
//获取 store里的user的值
user: this.$store.getters.getUser
}
}
}
</script>
<style scoped>
</style>
16.3.2 解决浏览器刷新后Vuex数据消失问题
- 问题描述
Vuex的状态存储是响应式的,当Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会相应地得到高效更新。但是有一个问题就是:vuex的存储的数据只是在页面中,相当于我们定义的全局变量,刷新之后,里边的数据就会恢复到初始化状态。但是这个情况有时候并不是我们所希望的。
- 解决方案
监听页面是否刷新,如果页面刷新了,将state对象存入到sessionStorage中。页面打开之后,判断sessionStorage中是否存在state对象,如果存在,则说明页面是被刷新过的,将sessionStorage中存的数据取出来给vuex中的state赋值。如果不存在,说明是第一次打开,则取vuex中定义的state初始值。
sessionStorage
:前端页面提供的一块存储的空间
- 修改代码
在
App.vue
中增加监听刷新事件
export default {
name: 'App',
//mounted 绑定
mounted() {
// 监听刷新(unload)事件,若发生unload事件,调用saveState方法
window.addEventListener('unload', this.saveState);
},
methods: {
saveState() {
// setItem() 存的是键值对
sessionStorage.setItem('state', JSON.stringify(this.$store.state));
}
}
}
修改
store/index.js
中的state
//全局 state 对象,用于保存所有组件的公共数据
//解释:从sessionStorage中获取键为“state”的值,若存在,则从sessionStorage中获取,若不存在,新建一个
const state = sessionStorage.getItem('state') ? JSON.parse(sessionStorage.getItem('state')) : {
user: {
username: ''
}
}
全系列【完】
觉得写得不错或者对你有帮助的小伙伴,请给小弟点个赞,你的支持是我学习与分享的动力。如果有什么建议或者编写有错的地方,请各位大佬们指出纠正。