学习笔记Vue(十 九)—— 路由导航守卫&动态路由

一、路由导航守卫

路由导航守卫也就是路由的钩子函数:

1.beforeRouteLeave

比如在某些信息收集网页,用户填写信息后不小心点到了别的地方,此时应该给出一个提示信息,是否离开此页,不然之前填写的信息就都白填了,就可以用beforeRouteLeave这个函数:
有三个参数,to,from,和next,
to: 你要跳转到的路径信息,
from:从哪里跳转走的路径信息,
next:写了路由钩子函数就必须写next(), 不然就不会执行跳转

<template>
    <div>
        <div class="learn">课程学习</div>
        课程名:<input type='text' v-model="name">
        <button @click="handleClick">确定</button>
    </div>
</template>
<script>
    export default {
        //路由离开之前,要改变成其他路径的时候
        beforeRouteLeave (to, from, next){
            //to: 你要去到的路径的信息
            //from:当前路径的信息
            //next: 跳转,如果你写了beforeRouteLeave但是没有让这个next()去执行,就不会跳转了

            //实现功能,如果input里有值,就去询问是否跳转,没有值就next()
            if(this.name){
                const flag = window.confirm('你确定要离开吗');
                if(flag){
                    this.name = '';
                    next();
                }
            }else{
                next();
            }
        },
        data () {
            return {
                name: ''
            }
        },
        methods: {
            handleClick(){
                this.name = '';
            }
        }
    }
</script>

2.beforeRouteEnter

跳转进入这个路由之前。
这个函数里不能使用this,this是undefiend,可以在next里传一个函数,函数的参数是vue实例:

    beforeRouteEnter (to, from, next){
        // 在这个函数里不能使用this,this为undefiend
        next(vm => {
            // console.log(vm);
        });
    },

3.beforeRouteUpdate

路由中的内容更新之前。

二、动态路由

比如你在一个模块里想放几个问题链接,点击某个问题后进入他的详情页,可以使用动态路由,而不是在你的路由模块里加很多子路由。
使用动态路由,通过id的匹配来显示你想要显示的详情页。
首先在router.js里添加你的question路由:

{
      path: '/question/:id', //添加了冒号后就表示后面的id是不定的了,
      name: 'question',
      component: () => import('./views/Question')
 },

这里的path路径里用一个:后面接id,冒号后面的id就不是一个固定的值了,可以在router-link里通过params来匹配路径,也可以不用冒号,用?,这样就用query属性来匹配路径:

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <!-- 动态路由的to里不能写path,不然就不管用了 -->
    <router-link tag="div" :to="{name: 'question', params: {id: item.id}}" class="aboutInfo"
      v-for="item in question" :key="item.id">
      {{item.info}}
      </router-link>
  </div>
</template>

<script>
    export default {
        data (){
          return {
            question: [
              {
                id: 201901,
                info: 'About question1'
              },
                            {
                id:201902,
                info: 'About question2'
              },
                            {
                id:201903,
                info: 'About question3'
              }
            ]
          }
        }
    }
</script>

注意,动态路由的to里不能用path属性,不然就不好使了

通过$route.params.id拿到当前路径的id值,然后就可以根据这个id来去问题列表里找到对应id的title内容渲染到页面上了:
Question.vue:

<template>
    <div class="question">
        <h4>问题{{$route.params.id}}</h4>
        <div>{{questionInfo}}</div>
        <button @click="handleClick" v-show="flag">下一个问题</button>
    </div>
</template>

<script>
export default {
    beforeRouteUpdate (to, from, next){
        this.getData(to.params.id)
        next();
    },
    mounted () {
        this.getData(this.$route.params.id)
    },
    data () {
        return {
            questionInfo: '',
            curId: '',
            flag: true,
            question: [
              {
                id: 201901,
                title: 'Vue的双向数据绑定原理是什么?'
              },
                            {
                id: 201902,
                title: '请详细说下你对vue生命周期的理解?'
              },
                            {
                id: 201903,
                title: '嵌套路由怎么定义?'
              }
            ]
        }
    },
    methods: {
        handleClick() {
            this.$router.push({
                name: 'question',
                params: {
                    id: this.curId + 1
                }
            })
        },
        getData (id){
            const index = this.question.findIndex(item => item.id === id);
            // console.log(index);
            if(index == -1){
                this.flag = false;
            }else{
                this.questionInfo = this.question[index].title;
                this.curId = id;
                this.flag = true;
            }
        }
    }
}
</script>

你可能感兴趣的:(Vue学习)