一、前言

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

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. lnmp环境里安装mssql及mssql的php扩展

    小活中用到mssql,于是在自己lnmp环境中安装各mssql数据库 步骤如下: 源码编译安装 (1)下载freetds-stable-0.91源码:http://download.csdn.net/ ...

  2. c/c++ linux 进程 fork wait函数

    linux 进程 fork wait函数 fork:创建子进程 wait:父进程等待子进程结束,并销毁子进程,如果父进程不调用wait函数,子进程就会一直留在linux内核中,变成了僵尸进程. for ...

  3. nginx内置变量总结

    nginx内置变量 2019-02-28 变量名称 变量用途 $atg_PARAMETER      客户端GET请求中   PARAMETER字段的值                        ...

  4. kaptcha验证码的使用

    使用kaptcha可以方便的配置: 验证码的字体 验证码字体的大小 验证码字体的字体颜色 验证码内容的范围(数字,字母,中文汉字!) 验证码图片的大小,边框,边框粗细,边框颜色 验证码的干扰线(可以自 ...

  5. 【English】20190328

    Emotions情绪 [ɪ'moʊʃənz]  Run Your Life for Teens影响你的青少年生活[ti:nz] Don't Let Your Emotions Run Your Lif ...

  6. sbt安裝與配置

    官方下載地址:https://www.scala-sbt.org/download.html?spm=a2c4e.11153940.blogcont238365.9.42d147e0iF8dhv 解压 ...

  7. vue SSR : 原理(一)

    前言: 由于vue 单页面对seo搜索引擎不支持,vue官网给了一个解决方案是ssr服务端渲染来解决seo这个问题,最近看了很多关于ssr的文章, 决定总结下: 参考博客:从0开始,搭建Vue2.0的 ...

  8. lsof -i

    https://www.cnblogs.com/sparkbj/p/7161669.html 主要命令

  9. golang 解析XML

    用adb操控android手机时,可以解析页面控件信息(xml) 代码如下: package main import ( "encoding/xml" "fmt" ...

  10. poj 3090 Visible Lattice Points(离线打表)

    这是好久之前做过的题,算是在考察欧拉函数的定义吧. 先把欧拉函数讲好:其实欧拉函数还是有很多解读的.emmm,最基础同时最重要的算是,¢(n)表示范围(1, n-1)中与n互质的数的个数 好了,我把规 ...