Vue(基础八)_导航守卫(组件内的守卫)
一、前言
主要通过一个例子演示三个钩子的作用:
1、beforeRouteEnter()
2、beforeRouteUpdate()
3、beforeRouteLeave
二、主要内容
1、举例说明:下面有三个组件,用户1,用户2公用一个公共组件。
2、beforeRouteEnter()
(1)详细说明beforeRouteEnter
//在路由改变之前
beforeRouteEnter (to, from, next){ //在渲染该组件的对应路由被confirm前调用
//不能获取当前组件实例this,因为在守卫执行之前,实例还没有被创建
//但是你可以通过传一个回调函数给next来访问组件实例。在导航被确认的时候进行回调,并且把组件实例作为回调方法的参数 }
/* */
(2)实现beforeRouteEnter的代码以及演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="vue.js"></script>
<script type="text/javascript" src="vue-router.js"></script>
<script type="text/javascript" src="axios.js"></script>
<script type="text/javascript">
Vue.use(VueRouter)
//用户组件
var User = {
data(){
return{
user:'',
error:null,
timer:null,
num:0,
msg:'',//输入框中输入的内容
msg1:'',//页面中展示的数据
confirm:true
}
}, template:`<div>
<div>{{num}}</div>
<input type="text" v-model='msg'/>
<p>{{msg1}}</p>
<button>保存</button>
<div v-if="error" class = 'error'>{{error}}</div>
<div class='user' v-if='user'>
{{user}}
</div> </div>`,
methods:{
setDatas(user){
this.user = user;
},
setError(err){
this.error=err;
}
}, beforeRouteEnter(to,from,next){
//在渲染该组件的对应路由被confirm前调用
//不能获取组件实例this
//因为当守卫执行前,组件还没创建,也就是路由切换之前
//但是你可以通过传一个回调给next来访问组件实例。在导航被确认的时候执行回调,并将组件实例作为回调方法的参数
//全局的axios调用
console.log(to);
axios.get(`http://127.0.0.1:8888/user/${to.params.id}`)
.then(res=>{
next(vm=>vm.setDatas(res.data));
})
.catch(err=>{
next(vm => vm.setError(err))
})
}
}
//测试组件
var Test = {
template:`<div>我是测试组件</div>`
} //路由配置
var router = new VueRouter({
routes:[{
path:'/user/:id',
name:'user',
component:User
},{
path:'/test',
name:'test',
component:Test
}]
}) //入口组件
var App = {
template:`<div>
<router-link :to='{name: "test"}'>测试</router-link>
<router-link :to='{name:"user",params:{id:1}}'>用户1</router-link>
<router-link :to='{name:"user",params:{id:2}}'>用户2</router-link> <router-view></router-view> </div>`
} //创建vue实例
new Vue({
el:'#app',
data:{ },
components:{
App
}, template:'<App/>',
router
})
</script> </body>
</html>
beforeRouteEnter
(3)具体实现
(4)测试:当从“测试”组件进入到用户组件的时候,发现组件中的内容发生改变,但是当从用户1切换到用户2的时候,发现没反应,因为用户1和用户2公用的公共组件user,
“用户1”切换到“用户2”的时候没有组件的创建和销毁
2、beforeRouteUpdate()
(1)在组件内部可以用beforeRouteUpdate来解决上面出现的问题
//路由更新时
beforeRouteUpdate(to, from, next) { //在当前路由改变,但是该组件被复用时调用
//举例来说:对于一个带有动态参数的路径 /foo/:id, 在/foo/1 和 /foo/2 之间跳转的时候,由于会渲染同样的foo组件, 因此组件实例会被重复利用。 此时这个钩子就可以在这个时候调用
//在这里可以获取到当前的this }
(2)beforeRouteUpdate的代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="vue.js"></script>
<script type="text/javascript" src="vue-router.js"></script>
<script type="text/javascript" src="axios.js"></script>
<script type="text/javascript">
Vue.use(VueRouter)
//用户组件
var User = {
data(){
return{
user:'',
error:null,
timer:null,
num:0,
msg:'',//输入框中输入的内容
msg1:'',//页面中展示的数据
confirm:true
}
}, template:`<div>
<div>{{num}}</div>
<input type="text" v-model='msg'/>
<p>{{msg1}}</p>
<button>保存</button>
<div v-if="error" class = 'error'>{{error}}</div>
<div class='user' v-if='user'>
{{user}}
</div> </div>`,
methods:{
setDatas(user){
this.user = user;
},
setError(err){
this.error=err;
}
}, beforeRouteEnter(to,from,next){
//在渲染该组件的对应路由被confirm前调用
//不能获取组件实例this
//因为当守卫执行前,组件还没创建,也就是路由切换之前
//但是你可以通过传一个回调给next来访问组件实例。在导航被确认的时候执行回调,并将组件实例作为回调方法的参数
//全局的axios调用
console.log(to);
axios.get(`http://127.0.0.1:8888/user/${to.params.id}`)
.then(res=>{
next(vm=>vm.setDatas(res.data));
})
.catch(err=>{
next(vm => vm.setError(err))
})
}, beforeRouteUpdate(to, from, next){
this.$axios.get(`http://127.0.0.1:8888/user/${to.params.id}`).
then(res=>{
this.setDatas(res.data); next(); //一定要用next,不然会被卡主
})
.catch(err=>{
this.setError(err);
next();
}) }
}
//测试组件
var Test = {
template:`<div>我是测试组件</div>`
} //路由配置
var router = new VueRouter({
routes:[{
path:'/user/:id',
name:'user',
component:User
},{
path:'/test',
name:'test',
component:Test
}]
}) Vue.prototype.$axios = axios
//入口组件
var App = {
template:`<div>
<router-link :to='{name: "test"}'>测试</router-link>
<router-link :to='{name:"user",params:{id:1}}'>用户1</router-link>
<router-link :to='{name:"user",params:{id:2}}'>用户2</router-link> <router-view></router-view> </div>`
} //创建vue实例
new Vue({
el:'#app',
data:{ },
components:{
App
}, template:'<App/>',
router
})
</script> </body>
</html>
beforeRouteUpdate
(3)测试:发现公共组件部分,可以通过切换路由,渲染出各自的数据了
3、beforeRouteLeave
(1)beforeRouteLeave()
beforeRouteLeave(to, from, next){
//离开当前组件时调用 }
(2)可以利用这个方法当用户离开某个页面的时候,提示用户保存信息
比如在写博客是点击其他页面时,会提示是否保存当前内容
(3)具体代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="vue.js"></script>
<script type="text/javascript" src="vue-router.js"></script>
<script type="text/javascript" src="axios.js"></script>
<script type="text/javascript">
Vue.use(VueRouter)
//用户组件
var User = {
data(){
return{
user:'',
error:null,
timer:null,
num:0,
msg:'',//输入框中输入的内容
msg1:'',//页面中展示的数据
confirm:true
}
}, template:`<div>
<div>{{num}}</div>
<input type="text" v-model='msg'/>
<p>{{msg1}}</p>
<button @click="save">保存</button>
<div v-if="error" class = 'error'>{{error}}</div>
<div class='user' v-if='user'>
{{user}}
</div> </div>`,
methods:{
setDatas(user){
this.user = user;
},
setError(err){
this.error=err;
},
save(){
this.msg1 = this.msg;
this.msg = '';
this.confirm = true;
}
}, beforeRouteEnter(to,from,next){
//在渲染该组件的对应路由被confirm前调用
//不能获取组件实例this
//因为当守卫执行前,组件还没创建,也就是路由切换之前
//但是你可以通过传一个回调给next来访问组件实例。在导航被确认的时候执行回调,并将组件实例作为回调方法的参数
//全局的axios调用
console.log(to);
axios.get(`http://127.0.0.1:8888/user/${to.params.id}`)
.then(res=>{
next(vm=>vm.setDatas(res.data));
})
.catch(err=>{
next(vm => vm.setError(err))
})
}, beforeRouteUpdate(to, from, next){
//当前路由改变,但是组件被复用(也就是公共组件)
this.$axios.get(`http://127.0.0.1:8888/user/${to.params.id}`).
then(res=>{
this.setDatas(res.data); next(); //一定要用next,不然会被卡主
})
.catch(err=>{
this.setError(err);
next();
}) }, beforeRouteLeave(to, from, next){
//导航离开该组件的对应路由时调用 if (this.confirm == true && this.msg) {
//证明用户输入了内容 需要提示用户 保存重要信息
this.confirm= confirm('请保存重要信息'); //用户点击了取消按钮 返回值为false next(false);
}else if(this.confirm == false){
alert('请保存信息后退出');
next(false);
}else{
next();//放行路由
} }
}
//测试组件
var Test = {
template:`<div>我是测试组件</div>`
} //路由配置
var router = new VueRouter({
routes:[{
path:'/user/:id',
name:'user',
component:User
},{
path:'/test',
name:'test',
component:Test
}]
}) Vue.prototype.$axios = axios
//入口组件
var App = {
template:`<div>
<router-link :to='{name: "test"}'>测试</router-link>
<router-link :to='{name:"user",params:{id:1}}'>用户1</router-link>
<router-link :to='{name:"user",params:{id:2}}'>用户2</router-link> <router-view></router-view> </div>`
} //创建vue实例
new Vue({
el:'#app',
data:{ },
components:{
App
}, template:'<App/>',
router
})
</script> </body>
</html>
beforeRouteLeave
三、总结
beforeRouteEnter:用于组件创建之前,公共组件不起作用
beforeRouteUpdate:用于公共组件的情况
参考文章:https://juejin.im/post/5b41bdef6fb9a04fe63765f1#heading-17
Vue(基础八)_导航守卫(组件内的守卫)的更多相关文章
- vue 组件内的守卫
1.beforeRouteEnter () // 进入该组件之前要去进行的逻辑操作, 2.beforeRouteLeave() // 离开该组件之前要去进行的逻辑操作(可清除定时器等耗用内存的变量, ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十║Vue基础终篇:传值+组件+项目说明
缘起 新的一天又开始啦,大家也应该看到我的标题了,是滴,Vue基础基本就到这里了,咱们回头看看这一路,如果你都看了,并且都会写了,那么现在你就可以自己写一个Demo了,如果再了解一点路由,ajax请求 ...
- Vue(基础四)_总结五种父子组件之间的通信方式
一.前言 这篇文章主要总结了几种通信方式: 1.方式一:使用props: [ ]和$emit() (适用于单层通信) 2.方式二:$attrs和$listeners(适用于多层) 3.方式三:中央处 ...
- Vue路由守卫之组件内路由守卫
beforeRouteEnter,进入路由前.需要注意这里不能使用this,因为我们使用的是进入路由之前,那会组件还没创建,得不到this这个属性,所有我们只能使用过vm异步语句来让 ...
- vue(基础二)_组件,过滤器,具名插槽
一.前言 主要包括: 1.组件(全局组件和局部组件) 2.父组件和子组件之间的通信(单层) 3.插槽和具名插槽 ...
- Vue(基础六)_嵌套路由(续)
一.前言 1.路由嵌套里面的公共路由 2.keep-alive路由缓存 3.导航守卫 二.主要内容 ...
- vue基础八
表单控件绑定 1.基础用法 你可以用 v-model 指令在表单控件元素上创建双向数据绑定.尽管有些神奇,但 v-model 本质上不过是语法糖,它负责监听用户的输入事件以更新数据,并特别处理一些极端 ...
- vue基础指令了解补充及组件介绍
v-once指令 """ v-once:单独使用,限制的标签内容一旦赋值,便不可被动更改(如果是输入框,可以主动修改) """ <di ...
- Vue(基础三)_监听器与计算属性
一.前言 本文主要涉及: 1.watch()监听单个属性 2.computed可以监听多个属性 3.点击li标签切换音乐案例 二.主要内容 1.watch()监听器(监听单一数据) (1)监听 ...
随机推荐
- Win32 API翻译
这是从MSDN里面的Win32 SDK API函数.结构.通知.消息等等超过3000个.其中一半是整理自别人翻译. http://files.cnblogs.com/files/sishenzaixi ...
- anaconda常用操作汇总
(1)设置国内(清华)镜像 # 添加Anaconda的TUNA镜像conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/an ...
- Bootstrap -- 文本,背景,其他样式
Bootstrap -- 文本,背景,其他样式 1. 文本样式:展示了不同的文本颜色 使用文本样式: <!DOCTYPE html> <html> <head> & ...
- 爬虫系列二(数据清洗--->正则表达式)
一 正则常识 模式 描述 \w 匹配字母数字及下划线 \W 匹配非字母数字及下划线 \s 匹配任意空白字符,等价于 [\t\n\r\f]. \S 匹配任意非空字符 \d 匹配任意数字,等价于 [0-9 ...
- Nginx健康检查模块
在本小节我们介绍一个用于Nginx对后端UpStream集群节点健康状态检查的第三方模块:nginx_upstream_check_module(https://github.com/yaoweibi ...
- [题解]P1856 [USACO5.5]矩形周长Picture
Loli 考试的题目之一 题目地址 \(N^2\)做法 #include <cstdio> #include <cstring> #define re register #de ...
- firewall centos
firewall-cmd --add-port=8056/tcp --临时增加端口 firewall-cmd --permanent --zone=public --add-port=6069/ ...
- WPF: 自动设置Owner的ShowDialog 适用于MVVM
原文:WPF: 自动设置Owner的ShowDialog 适用于MVVM 原文地址:http://www.mgenware.com/blog/?p=339 WPF中的Windows的ShowDialo ...
- 一个方法教你认识ref(简单易懂)
参数分为值类型和引用类型,当我们将一个值类型的参数进行传递到另一个方法的时候相当于,将这个变量进行复制到该方法进行操作,但是不会对该变量原始的值有影响. 但是有时候我们需要他有“影响”于是ref就出现 ...
- 10-JavaScript之DOM的事件操作
JavaScript之DOM的事件操作 1.介绍 JavaScript基础分为三个部分: ECMAScript:JavaScript的语法标准.包括变量.表达式.运算符.函数.if语句.for语句等 ...