Vue Router_4、两个生命周期钩子、路由守卫、浏览器的两种工作模式

1.两个新的生命周期钩子

作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。

具体名字:

  1. activated路由组件被激活时触发。
  2. deactivated路由组件失活时触发。

如,在一个路由里的某个数据,在切换到另一个路由对应的组件后,里面的数据还保留,也就是不销毁原来的组件,但是需要关闭里面的定时器,所以用组件的beforeDestroy钩子无法实现关闭掉定时器,因为原组件通过<keep-alive>标签所包含着的。这时候就可以用deactivated钩子来关闭定时器。注意:组件失活不等于组被销毁。

src\pages\News.vue

<template>
    <ul>
        <li :style="{opacity}">欢迎学习vue</li>
        <li>news001 <input type="text"></li>
        <li>news002 <input type="text"></li>
        <li>news003 <input type="text"></li>
    </ul>  
</template>

<script>
export default {
    name:"News",
    data(){
        return{
            opacity:1
        }
    },
    activated(){
        console.log("News组件激活了");
        this.timer=setInterval(() => {
            console.log("定时器在工作 ");
            this.opacity-=0.01;
            if(this.opacity<=0){
                 this.opacity=1;;
            }
        }, 16);
    },
    deactivated(){
        console.log("News组件失活了");
        
         //关闭定时器
        clearInterval(this.timer);
    }
}
</script>


2.路由守卫

作用:对路由进行权限控制

分类:全局守卫、独享守卫、组件内守卫

meta配置项:路由提供的的meta配置项:路由的元信息,可以在该项里存放程序员自己的属性。
读取:
在守卫里可以:to.meta.属性名读取。
在组件里:this.$route.meta.属性名读取。

全局守卫:

//全局前置守卫:初始化时执行、每次路由切换前执行
router.beforeEach((to,from,next)=>{
	console.log('beforeEach',to,from)
	if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
		if(localStorage.getItem('school') === 'atguigu'){ //权限控制的具体规则
			next() //放行
		}else{
			alert('暂无权限查看')
			// next({name:'guanyu'})
		}
	}else{
		next() //放行
	}
})

//全局后置守卫:初始化时执行、每次路由切换后执行
router.afterEach((to,from)=>{
	console.log('afterEach',to,from)
	if(to.meta.title){ 
		document.title = to.meta.title //修改网页的title
	}else{
		document.title = 'vue_test'
	}
})

案例:

//创建并暴露一个路由器
const router= new VueRouter({
    routes:[
        {
            name:"guanyu",
            path:"/About",
            component:About,
            meta:{title:"关于"}
            
        },
        {
            name:"zhuye",
            path:"/home",
            component:Home,
            meta:{title:"主页"},
            children:[
                {
                    name:"xiaoxi",
                    path:"message",
                    component:Message,
                    meta:{isAuth:true,title:"消息"},
                    children:[
                        {
                            name:"xiangqing",
                            //path:"detail/:id/:title",//params传参专用
                            path:"detail",
                            component:Detail,                            

                            //props的第二种写法,值为函数。
                            props($route){
                                return {
                                    id:$route.query.id,
                                    title:$route.query.title
                                }
                            },
                            meta:{
                                isAuth:true,
                                title:"详情"
                            }
                        }
                    ]
                },
                {
                    name:"xinwen",
                    path:"news",
                    component:News,
                    meta:{isAuth:true,title:"新闻"}
                }
            ]
        }
        
    ]
});


//全局前置路由守卫 ---初始化的时候被调用、每次路由切换之前被调用。
router.beforeEach((to,from,next)=>{

    console.log("前置路由守卫执行");

    
    
    // if(to.name==='xinwen'||to.path==='/home/message'){
    //     if(localStorage.getItem('school')==='nanchong'){
    //         next();//放行,让其进入
    //     }else{
    //         alert("学校名不对,无权限查看。");
    //     };
    // }else{
    //     next();//放行,让其进入
    // }

    //判断是否需要鉴权
    if(to.meta.isAuth){
        if(localStorage.getItem('school')==='nanchong'){
           
            next();//放行,让其进入
        }else{
            alert("学校名不对,无权限查看。");
        };
    }else{
        next();//放行,让其进入
    }

});


//全局后置路由守卫 ---初始化的时候被调用、每次路由切换之后被调用。
router.afterEach((to,from)=>{
    //console.log("后置路由守卫执行",to,from);

    document.title=to.meta.title||"系统";//修改网页标题

});


export default router;

独享守卫:

在组件的配置项里写beforeEnter配置项即可
独享路由守卫只属于某个路由所拥有,在该组件被读取前执行。

//创建并暴露一个路由器
const router= new VueRouter({
    routes:[
        {
            name:"guanyu",
            path:"/About",
            component:About
            
        },
        {
            name:"zhuye",
            path:"/home",
            component:Home,
            children:[
                {
                    name:"xiaoxi",
                    path:"message",
                    component:Message,
                    children:[
                        {
                            name:"xiangqing",
                            //path:"detail/:id/:title",//params传参专用
                            path:"detail",
                            component:Detail,                            

                            //props的第二种写法,值为函数。
                            props($route){
                                return {
                                    id:$route.query.id,
                                    title:$route.query.title
                                }
                            }
                        }
                    ]
                },
                {
                    name:"xinwen",
                    path:"news",
                    component:News,
                    meta:{isAuth:true,title:"新闻"},
                    beforeEnter:(to,from,next)=>{
                        //判断是否需要鉴权
                        if(to.meta.isAuth){
                            if(localStorage.getItem('school')==='nanchong2'){
                            
                                next();//放行,让其进入
                            }else{
                                alert("学校名不对,无权限查看。");
                            };
                        }else{
                            next();//放行,让其进入
                        }
                    }
                }
            ]
        }
        
    ]
});

组件内守卫:

//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {
},
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) {
}

必须是通过路由进入该组件才会触发守卫,如果是引用该组件直接通过组件标签在页面显示是不会触发守卫的。

<template>
    <h2>我是About的内容</h2>
</template>

<script>
export default {
    name:"About",
    //通过路由规则,进入该组件时被调用。如果是在别的组件里直接引入该组件挂载后在页面通过该组件的标签显示该组件,
    //不属于通过路由进入该组件,则不会触发该方法。
    beforeRouteEnter(to, from, next){
        
        //判断是否需要鉴权
        if(to.meta.isAuth){
            if(localStorage.getItem('school')==='nanchong'){            
                next();//放行,让其进入
            }else{
                alert("学校名不对,无权限查看。");
            };
        }else{
            next();//放行,让其进入
        }
    },
    //通过路由规则,离开该组件时被调用
    beforeRouteLeave (to, from, next) {
        // 放行,否则无法去下一个路由了。
        next();
    }

}
</script>

浏览器的两种工作模式

  1. 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。

  2. hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。

  3. hash模式:

    1. 地址中永远带着#号,不美观 。
    2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
    3. 兼容性较好。
  4. history模式:

    1. 地址干净,美观 。
    2. 兼容性和hash模式相比略差。
    3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。

在路由器里可以指定工作模式:

//创建并暴露一个路由器
const router= new VueRouter({
    mode:'history',//指定工作模式
    routes:[...],
});

export default router;
posted @ 2022-04-14 20:45  青仙  阅读(435)  评论(0编辑  收藏  举报