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)监听 ...
随机推荐
- VS根据数据库生成实体类
一.在类库项目上添加新项 二. 三.依次填入数据库连接 选择数据库 就可以生成数据库实体
- Web应用安全测试
偷偷挪用人家的分享: https://blog.csdn.net/aojie80/article/details/43836521 写的很棒 Burp Suite 介绍 https://blog.cs ...
- SSRS----关于图表参考线(平均线)的添加
在开发报表的时候,遇到了一个问题,客户需要在气泡图上添加水平和竖直两条平均线(结果参考如下图). 个人知识背景 一般添加参考线本身是有一个相关的设置的,但一般都是相对于Y值,即平行于X轴的.用类似的方 ...
- PHP跨域jsonp方式
<?php header('Access-Control-Allow-Origin:*');//注意!跨域要加这个头 上面那个没有 $arr = array ('a'=>1,'b'=> ...
- 《JAVA程序设计》_第四周学习总结
一.本周学习内容 1.子类与父类--5.1知识 在类的声明中用关键字extends来定义一个类的子类,格式如下: class 子类名 extends 父类名 { ... } 2.子类的继承性--5.2 ...
- Linux-基础学习(五)-mariadb主从复制以及redis学习
开始今日份整理 1.mariadb的主从复制 主从复制大致图示: 1.1 mysql基本命令复习 linux下的操作 .启动mysql systemctl start mariadb .linux客户 ...
- CSAPP:第八章 异常控制流2
CSAPP:第八章 异常控制流2 关键点:进程控制.信号 8.4 进程控制8.5 信号 8.4 进程控制 Unix提供了大量从C程序中操作进程的系统调用.8.4.1 获取进程ID 每个进程都有一 ...
- hotspot目录结构
Hotspot的目录结构 ├─agent Serviceability Agent的客户端实现 ├─make 用来build出HotSpot的各种配置文件 ├─src HotSpot VM的源代码 │ ...
- easyui-tab标签
一. 加载方式 //class 加载方式<div id="box" class="easyui-tabs" style="width:500px ...
- ondaHTTPError: HTTP 000 CONNECTION FAILED for url
可能是网络问题,换网络. 可能是获取库的IP无法链接到,换库的IP,如添加清华镜像IP等.