一、前言

主要通过一个例子演示三个钩子的作用:

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(基础八)_导航守卫(组件内的守卫)的更多相关文章

  1. vue 组件内的守卫

    1.beforeRouteEnter ()  // 进入该组件之前要去进行的逻辑操作, 2.beforeRouteLeave() // 离开该组件之前要去进行的逻辑操作(可清除定时器等耗用内存的变量, ...

  2. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十║Vue基础终篇:传值+组件+项目说明

    缘起 新的一天又开始啦,大家也应该看到我的标题了,是滴,Vue基础基本就到这里了,咱们回头看看这一路,如果你都看了,并且都会写了,那么现在你就可以自己写一个Demo了,如果再了解一点路由,ajax请求 ...

  3. Vue(基础四)_总结五种父子组件之间的通信方式

    一.前言 这篇文章主要总结了几种通信方式: 1.方式一:使用props: [ ]和$emit()  (适用于单层通信) 2.方式二:$attrs和$listeners(适用于多层) 3.方式三:中央处 ...

  4. Vue路由守卫之组件内路由守卫

    ​        beforeRouteEnter,进入路由前.需要注意这里不能使用this,因为我们使用的是进入路由之前,那会组件还没创建,得不到this这个属性,所有我们只能使用过vm异步语句来让 ...

  5. vue(基础二)_组件,过滤器,具名插槽

    一.前言 主要包括:  1.组件(全局组件和局部组件)                     2.父组件和子组件之间的通信(单层)                     3.插槽和具名插槽     ...

  6. Vue(基础六)_嵌套路由(续)

    一.前言                  1.路由嵌套里面的公共路由                  2.keep-alive路由缓存                  3.导航守卫 二.主要内容 ...

  7. vue基础八

    表单控件绑定 1.基础用法 你可以用 v-model 指令在表单控件元素上创建双向数据绑定.尽管有些神奇,但 v-model 本质上不过是语法糖,它负责监听用户的输入事件以更新数据,并特别处理一些极端 ...

  8. vue基础指令了解补充及组件介绍

    v-once指令 """ v-once:单独使用,限制的标签内容一旦赋值,便不可被动更改(如果是输入框,可以主动修改) """ <di ...

  9. Vue(基础三)_监听器与计算属性

    一.前言 本文主要涉及:     1.watch()监听单个属性 2.computed可以监听多个属性 3.点击li标签切换音乐案例 二.主要内容 1.watch()监听器(监听单一数据) (1)监听 ...

随机推荐

  1. HDFS副本放置策略

    1.第一个副本放置在上传文件的DataNode上,如果是集群外提交,则随机挑选一个磁盘不太满,CPU不太忙的节点. 2.第二个副本放置在与第一个副本不同的机架上. 3.第三个副本放置在与第二个副本同机 ...

  2. MySQL 基础知识梳理学习(三)----InnoDB日志相关的几个要点

    1.InnoDB的特点 :(1)Fully ACID (InnoDB默认的Repeat Read隔离级别支持):(2)Row-level Locking(支持行锁):(3)Multi-version ...

  3. android SDK 无法更新

    android-windows-sdk无法更新解决办法:   1.在host文件新增如下配置 (host文件位置:c:\Windows\System32\drivers\etc文件夹下面,用文本编辑器 ...

  4. Java Api Consumer 连接启用Kerberos认证的Kafka

    java程序连接到一个需要Kerberos认证的kafka集群上,消费生产者生产的信息,kafka版本是2.10-0.10.0.1: Java程序以maven构建,(怎么构建maven工程,可去问下度 ...

  5. websocket 实现单聊群聊 以及 握手原理+加密方式

    WebSocket 开始代码 服务端 群聊 # type:WebSocket 给变量标注类型 # websocket web + socket from geventwebsocket.server ...

  6. SQL分组求每组最大值问题的解决方法收集 (转载)

    例如有一个表student,其结构如下: id      name     sort      score 1        张三      语文      82 2        李四      数 ...

  7. 如何用java发送Http的post请求,并传递参数

    书写方法,请参考以下代码: package utils; import java.io.BufferedReader; import java.io.IOException; import java. ...

  8. 【学习总结】Git学习-参考廖雪峰老师教程-总

    公元2018-10-21 实验室台式机 win7 64位 参考教程: 廖雪峰Git教程 其他资料:Git-book 北大一只总结的笔记,最终整理的时候可以参考:Git笔记 评论区看到的另一个人,总结在 ...

  9. Flask 微信公众号开发

    公众号接口 1. 公众号消息会话 目前公众号内主要有这样几类消息服务的类型,分别用于不同的场景. 群发消息 公众号可以以一定频次(订阅号为每天1次,服务号为每月4次),向用户群发消息,包括文字消息.图 ...

  10. Linux 默认连接数

    Linux 默认连接数 - 国内版 Binghttps://cn.bing.com/search?FORM=U227DF&PC=U227&q=Linux+%E9%BB%98%E8%AE ...