一、前言

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

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. ext遍历表单中所有输入项,并全部设置为只读

    baseInfoForm.getForm().getFields().each(function (field) { // 设置只读 field.setReadOnly(true); })

  2. MySQL 基础知识梳理学习(五)----详解MySQL两次写的设计及实现

    一 . 两次写提出的背景或要解决的问题 两次写(InnoDB Double Write)是Innodb中很独特的一个功能点.因为Innodb中的日志是逻辑的,所谓逻辑就是比如插入一条记录时,它可能会在 ...

  3. Python字典、集合之高山流水

    字典dict字典是由大括号{键:值}组成.字典是无序的.字典的键必须是不可变数据类型.不能使用列表作为键,但可以使用元祖作为字典的键.例如: dict_ = {"test":&qu ...

  4. MongoDB的导入与导出

    一.导入与导出可以操作本地的mongodb也可以是远程的mongodb,通用选项: -h host 主机 --port port 端口 -u username 用户名 -p password 密码 如 ...

  5. SQLServer之创建Transact-SQL DDL触发器

    DDL触发器原理 DDL 触发器用于响应各种数据定义语言 (DDL) 事件. 这些事件主要与以关键字 CREATE.ALTER.DROP.GRANT.DENY.REVOKE 或 UPDATE STAT ...

  6. sizeof和strlen()区别及用法

    //sizeof是以字节为单位计算变量或类型所占内存大小,它是属于C语言运算符系列:而strlen()是一个函数,是计算字符串长度(也是以字节为单位,但略有区别):比如: char array[] = ...

  7. 浏览器各个版本和系统(chrome/safari/edge/qq/360)

    浏览器对象: let userAgent = navigator.userAgent.toLowerCase()console.log(userAgent) Edge: mozilla/5.0 (wi ...

  8. Python距离放弃拉近的day03

    新的一天,依旧是内容补充,补充了数学没有的运算符,in和not in,就是判断in前面的东西是不是在后面的数据中,然后新课讲了平常最常用的字符串的方法,引号的里面全部都是字符串,在其中就会又如何判断这 ...

  9. php 表单提交大量数据发生丢失的解决方法

    最近在项目中,出现一个奇怪的现象,有一个大form里面有上千个input,提交的时候,老是发现post过来的数据不完整,一开始还怀疑是html 表单名称有冲突,排除掉了.然后,网上找了一堆,php.i ...

  10. MD5加密加盐

    Java实现MD5的随机加盐加密,这样以来就很难解密了,必须使用原密码才能正常的登录系统了,以下为Java实现的MD5随机加盐加密,以及使用Apache的Hex类实现Hex(16进制字符串和)和字节数 ...