美文网首页
vue-router学习

vue-router学习

作者: 回不去的那些时光 | 来源:发表于2020-01-02 21:59 被阅读0次

    helloworld

    <div>
        <div>
            <router-link to="/">Home</router-link> |
            <router-link to="/about">About</router-link>
        </div>
        <router-view />
    </div>
    
    export default new Router({
      mode: 'history',
      routes: [
        {
          path: '/',
          name: 'home',
          component: Home,
        },
        {
          path: '/about',
          name: 'about',
          component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
        }
      ]
    })
    

    嵌套路由中需要注意的事项

    能匹配到 /about/a 和 /about/b

    {
        path: '/about',
        name: 'about',
        component: () => import('./views/About.vue'),
        redirect: '/about/a',
        children: [
            {
                path: 'a',
                name: 'a',
                component: () => import('./components/A.vue')
            },
            {
                path: 'b',
                name: 'b',
                component: () => import('./components/B.vue')
            }
        ]
    }
    

    能匹配到 /a 和 /b

    {
        path: '/about',
        name: 'about',
        component: () => import('./views/About.vue'),
        redirect: '/a',
        children: [
            {
                path: '/a',
                name: 'a',
                component: () => import('./components/A.vue')
            },
            {
                path: '/b',
                name: 'b',
                component: () => import('./components/B.vue')
            }
        ]
    }
    
    • 要注意,以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。

    编程式导航

    • router.push()

    在vue内部可以使用this.$router.push来代替,这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

    点击<router-link :to="...">等同于调用router.push(...)

    // 字符串
    router.push('home')
    
    // 对象
    router.push({ path: 'home' })
    
    // 命名的路由   /user/123
    router.push({ name: 'user', params: { userId: '123' }})
    
    // 带查询参数,变成 /register?plan=private
    router.push({ path: 'register', query: { plan: 'private' }})
    
    const userId = '123'
    router.push({ name: 'user', params: { userId }}) // -> /user/123
    router.push({ path: `/user/${userId}` }) // -> /user/123
    // 这里的 params 不生效, 如果提供了 path,params 会被忽略
    router.push({ path: '/user', params: { userId }}) // -> /user
    
    • router.replace()

    这个方法不会向history添加记录

    点击<router-link :to="..." replace>等同于调用router.replace(...)

    • router.go(n)

    这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。

    // 在浏览器记录中前进一步,等同于 history.forward()
    router.go(1)
    
    // 后退一步记录,等同于 history.back()
    router.go(-1)
    

    命名路由(带有名称的路由)

    在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称

    命名视图

    有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。

    <router-view class="view one"></router-view>
    <router-view class="view two" name="a"></router-view>
    <router-view class="view three" name="b"></router-view>
    
    const router = new VueRouter({
      routes: [
        {
          path: '/',
          components: {
            default: Foo,
            a: Bar,
            b: Baz
          }
        }
      ]
    })
    

    重定向(redirect)

    { path: '/a', redirect: '/b' }
    

    别名

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

    { path: '/a', component: A, alias: '/b' }
    

    “别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。

    路由组件传参

    在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。
    可以使用 props 将组件和路由解耦

    const User = {
      props: ['id'],
      template: '<div>User {{ id }}</div>'
    }
    
    const router = new VueRouter({
        routes: [
            // 当设置 props 为 true 时,路由上的数据就会给分配到 props 中了
            { path: '/user/:id', component: User, props: true }, 
            // 对于包含命名视图的路由,你必须分别为每个命名视图添加 props 选项:
        {
          path: '/user/:id',
          components: { default: User, sidebar: Sidebar },
          props: { default: true, sidebar: false }
        }
        ]
    })
    

    导航守卫

    全局前置守卫
    beforeEach

    router.beforeEach((to, from, next) => {
      // ...
    })
    

    全局解析守卫
    beforeResolve
    在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

    全局后置守卫
    afterEach

    router.afterEach((to, from) => {
      // ...
    })
    

    路由独享的守卫
    beforeEnter

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

    组件内的守卫
    beforeRouteEnter
    beforeRouteUpdate
    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`
      }
    }
    

    完整的导航解析流程
    1、导航被触发。
    2、在失活的组件里调用离开守卫。
    3、调用全局的 beforeEach 守卫。
    4、在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
    5、在路由配置里调用 beforeEnter。
    6、解析异步路由组件。
    7、在被激活的组件里调用 beforeRouteEnter。
    8、调用全局的 beforeResolve 守卫 (2.5+)。
    9、导航被确认。
    10、调用全局的 afterEach 钩子。
    11、触发 DOM 更新。
    12、用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

    路由元信息

    meta

    滚动行为

    使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。

    注意: 这个功能只在支持 history.pushState 的浏览器中可用。

    // savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用
    scrollBehavior (to, from, savedPosition) {
      if (savedPosition) {
        return savedPosition
      } else {
        return { x: 0, y: 0 }
      }
    }
    

    路由懒加载

    把组件按组分块
    有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。

    const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
    const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
    const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
    

    相关文章

      网友评论

          本文标题:vue-router学习

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