美文网首页
vue-router

vue-router

作者: 卡布i | 来源:发表于2020-03-26 23:49 被阅读0次

    路由详解-基础

    router-link和router-view组件

    router-link: 封装了一个a标签
    router-view: 视图渲染组件

    路由配置

    动态路由

    router/index.js

      {
        path: '/about/:name',
        component: () => import('../views/About.vue')
      }
    

    about.vue

    <template>
      <div class="about">
        <h1>This is an about page</h1>
        传递的参数是: {{ $route.params.name}}
        // $route 当前路由对象
      </div>
    </template>
    
    image.png

    嵌套路由

    router/index.js

      {
        path: '/parent',
        component: () => import('../views/parent.vue'),
        children: [
          {
            path: 'child',
            component: () => import('../views/child.vue')
          }
        ]
      }
    

    parent.vue

    <template>
      <div>
        <p>这是parent.vue页面</p>
        <router-view></router-view>
      </div>
    </template>
    
    

    child.vue

    <template>
      <div>这是children.vue页面</div>
    </template>
    

    效果


    image.png

    命名路由

    router-link标签的to属性, 可以通过传入路径或者传入name值进行跳转
    注意写法: :to="{name:'Home'}"

        <router-link to="/">Home</router-link>     
        <router-link :to="{name:'Home'}">Home</router-link>
    

    router/index.js

    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      }
    }
    

    命名视图

    一个页面内可以使用多个router-view组件, 如果 router-view 没有设置名字,那么默认为 default。
    app.vue

    <template>
      <div id="app">
        <div id="nav">
          <router-link to="/">Home</router-link> |
          <router-link to="/about">About</router-link> |
          <router-link to="/parent">parent</router-link> |
          <router-link to="/child">child</router-link> |
          <router-link :to="{name:'Home'}">Home</router-link>
        </div>
        <router-view/>
        <router-view name="parent"/>
        <router-view name="child"/>
      </div>
    </template>
    

    router/index.js

      {
        path: '/name',
        components: {
          default: () => import('../views/About.vue'),
          parent: () => import('../views/parent.vue'),
          child: () => import('../views/child.vue')
        }
      }
    

    效果


    image.png

    重定向和别名

    重定向

    router/index.js

      {
        path: '/test',
        redirect: '/'
      }
    

    别名

    const router = new VueRouter({
      routes: [
        { path: '/a', component: A, alias: '/b' }
      ]
    })
    

    /a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

    js操作路由

    文档

    路由详解-进阶

    官方文档

    导航守卫

    导航守卫就是路由跳转过程中vue-router的生命周期,路由跳转是一个大的过程,这个大的过程分为跳转前中后等等细小的过程,在每一个过程中都有一函数,这个函数能让你操作一些其他的事儿的时机,这就是导航守卫。

    完整的导航解析流程

    • 导航被触发。
    • 在失活的组件里调用离开守卫。
    • 调用全局的 beforeEach 守卫。
    • 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
    • 在路由配置里调用 beforeEnter。
    • 解析异步路由组件。
    • 在被激活的组件里调用 beforeRouteEnter。
    • 调用全局的 beforeResolve 守卫 (2.5+)。
    • 导航被确认。
    • 调用全局的 afterEach 钩子。
    • 触发 DOM 更新。
    • 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

    全局前置守卫

    beforeEach

    const router = new VueRouter({
      routes
    })
    // 根据常量HAS_LOGINED判断用户是否登录, 如果未登录, 则用户只能跳转到登录页面, 如果用户已经登录, 那么无法进入登录页面
    const HAS_LOGINED = false
    router.beforeEach((to, from, next) => {
      console.log('要去的页面', to.path)
      console.log('离开的页面', from.path)
      if (to.path === '/login') {
        if (HAS_LOGINED) {
          next('/')
        } else {
          console.log('已经进入了login页面')
          next()
        }
      } else {
        if (HAS_LOGINED) next()
        else next('/login')
      }
    })
    

    路由守卫

    你可以在路由配置上直接定义 beforeEnter 守卫:

    const router = new VueRouter({
      routes: [
        {
          path: '/foo',
          component: Foo,
          beforeEnter: (to, from, next) => {
            // ...
          }
        }
      ]
    })
    

    这些守卫与全局前置守卫的方法参数是一样的。

    组件内的守卫

    你可以在路由组件内直接定义以下路由导航守卫:

    beforeRouteEnter
    beforeRouteUpdate (2.2 新增)
    beforeRouteLeave
    
    const Foo = {
      template: `...`,
      beforeRouteEnter (to, from, next) {
        // 在渲染该组件的对应路由被 confirm 前调用
        // 不!能!获取组件实例 `this`
        // 因为当守卫执行前,组件实例还没被创建
      },
      beforeRouteUpdate (to, from, next) {
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 可以访问组件实例 `this`
      },
      beforeRouteLeave (to, from, next) {
        // 导航离开该组件的对应路由时调用
        // 可以访问组件实例 `this`
      }
    }
    

    beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。

    不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

    beforeRouteEnter (to, from, next) {
      next(vm => {
        // 通过 `vm` 访问组件实例
      })
    }
    

    注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。

    beforeRouteUpdate (to, from, next) {
      // just use `this`
      this.name = to.params.name
      next()
    }
    

    这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。

    beforeRouteLeave (to, from, next) {
      const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
      if (answer) {
        next()
      } else {
        next(false)
      }
    }
    

    相关文章

      网友评论

          本文标题:vue-router

          本文链接:https://www.haomeiwen.com/subject/llofuhtx.html