vue路由

#vue-router

介绍

Vue Router 是 Vue.js 官方的路由管理器。包含的功能有:
  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查询、通配符
  • 基于 Vue.js 过渡系统的视图过渡效果
  • 带有自动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
  • 自定义的滚动条行为

安装

直接下载|SDN/NPM/构建开发版
通过npm安装及在js中的配置:
引入
import Vue from 'vue'
import VueRouter from 'vue-router'
激活
Vue.use(VueRouter)
定义路由组件的基础上-定义路由
const routes = [
  { path: '/resume', component: resume },
  { path: '/position',  component: (resolve) => {
    require(['.src/pages/position/position'], resolve)
    },
  }
]
生成路由实例
const router = new VueRouter({
  routes // (缩写) 相当于 routes: routes
})
或者
const router = new Router({
  routes = [
  { path: '/resume', component: resume },
  { path: '/position',  component: (resolve) => {
    require(['.src/pages/position/position'], resolve)
    },
  }
]
})

挂载
new Vue({
  router,
}).$mount('#app')
上述是在main.js中编写的,但我们通常会把router额外放到一个独立的js文件,方法如上(挂载除外)最后把这个文件默认输出( export default router),然后在把这个文件import 到main.js当中进行挂载就可以了
在页面中使用路由:
<div id="app">
  <p>
    <!-- 通过传入 `to` 属性指定链接. -->
    <!-- router-link 默认会被渲染成一个 `<a>` 标签 -->
    <router-link to="/position">Go to position</router-link>
    <router-link to="/resume">Go to resume</router-link>
  </p>
  <!-- 路由出口-路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>
路由对象是什么

一个路由对象 (route object) 表示当前激活的路由的状态信息,包含了当前 URL 解析得到的信息,还有 URL 匹配到的路由记录 (route records)。
一个路由对象表示当前激活的路由的状态信息,每次成功导航后都会产生一个新的对象
路由对象出现在多个地方:

  • 在组件内,即 this.$route
  • $route观察者回调内
  • 导航守卫的参数
  • scrollBehavior方法的参数:
  • router.match(location)的返回值
    location的值可以有一下几种类型:
    ‘home’
    {path:‘home’}
    { name: ‘user’, params: { userId: 123 }} // 命名路由,变成/user/123
    { path: ‘register’, query: { plan: ‘private’ }} // 带查询参数,变成 /register?plan=private
  • 导航守卫的参数
router.beforeEach((to, from, next) => {
  // `to``from` 都是路由对象
})
  • scrollBehavior方法的参数:
const router = new VueRouter({
  scrollBehavior (to, from, savedPosition) {
    // `to``from` 都是路由对象
  }
})

vue路由对象为this.$route时的一些属性:

  • $route.path
    类型: string
    字符串,对应当前路由的路径,总是解析为绝对路径,如 “/foo/bar”。

  • $route.params
    类型: Object
    一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。

  • $route.query

    类型: Object
    一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 $route.query.user == 1,如果没有查询参数,则是个空对象。

  • $route.hash
    类型: string
    当前路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。

  • $route.fullPath
    类型: string
    完成解析后的 URL,包含查询参数和 hash 的完整路径。

  • $route.matched
    类型: Array
    一个数组,包含当前路由的所有嵌套路径片段的路由记录 。路由记录就是 routes 配置数组中的对象副本 (还有在 children 数组)。

const router = new VueRouter({
  routes: [
    // 下面的对象就是路由记录
    { path: '/foo', component: Foo,
      children: [
        // 这也是个路由记录
        { path: 'bar', component: Bar }
      ]
    }
  ]
})
  • $route.name
    当前路由的名称,如果有的话。

  • $route.redirectedFrom
    如果存在重定向,即为重定向来源的路由的名字。

对象为this.$route的属性
小结(8):path params query hash fullPath matched name redirectedFrom


vue路由传参query和params的区别

params:/router1/:id ,/router1/123,/router1/789 ,这里的id叫做params
query:/router1?id=123 ,/router1?id=456 ,这里的id叫做query。
1、用法

  • query要用path来引入,接收参数都是this.$route.query.name。
  • params要用name来引入,接收参数都是this.$route.params.name。
    2、效果
  • query类似于ajax中get传参,即在浏览器地址栏中显示参数。
  • params则类似于post,即在浏览器地址栏中不显示参数。
    通过注入路由器,我们可以在任何组件内通过this.$router访问路由器,也可以通过 this.$route访问当前路由:
this.$routerthis.$route的区别
  1. this.$router:
    表示全局路由器对象,项目中通过router路由参数注入路由之后,在任何一个页面都可以通过此方法获取到路由器对象,并调用其push(), go()等方法;
  2. this.$route:
    表示当前正在用于跳转的路由器对象,可以调用其name、path、query、
    params等方法;

命名路由

给路由起名字 配合在$route中属性使用

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

动态路由匹配

如根据不同的id值访问同一个组件
这时就可以在路由路径中使用“动态路径参数”来达到我们要的效果

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User }
  ]
})

一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,所有的参数值会被设置到this.$route.params当中,并且参数可以设置多个,可以在每个组件内使用。所以也可以通过this.$route.params.id来获取参数

     模式                             匹配路径                     $route.params
/user/:username                     /user/evan                 { username: 'evan' }
/user/:username/post/:post_id    /user/evan/post/123  
                                              { username: 'evan', post_id: 123 }
响应路由参数的变化

当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象:

const User = {
  template: '...',
  watch: {
    '$route' (to, from) {
      // 对路由变化作出响应...
    }
  }
}
//组件内的守卫
const User = {
  template: '...',
  //在当前路由改变,但是该组件被复用时调用
  //根据参数的不同访问同一个组件时
  beforeRouteUpdate (to, from, next) {
  }
}

小结:动态路由匹配以及响应路由参数的变化


router-link

router-link通过to属性指定目标地址,默认渲染成带有正确链接的 a 标签,配置 tag 属性生成别的标签.

<router-link to="/position" tag="div">Go to position</router-link>
router-link VS a 标签
  • 让浏览器不再重新加载页面。。。。。
  • 当目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名。有时候我们要让激活 class 应用在外层元素,而不是 a标签本身,那么可以用 router-link 渲染外层元素,包裹着内层的原生 a 标签:
<router-link tag="li" to="/foo">
  <a>/foo</a>
</router-link>

######<router-link>的一些属性:
1、 to
类型: string | Location
表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。

<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

2、replace
类型: boolean
默认值: false
设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),于是导航后不会留下 history 记录。

<router-link :to="{ path: '/abc'}" replace></router-link>

3、append
类型: boolean
默认值: false
设置 append 属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b

<router-link :to="{ path: 'relative/path'}" append></router-link>

4、tag
类型: string
默认值: “a”
router-link默认是a标签,如果想把它设置成别的标签那么就使用tag标签

<router-link to="/foo" tag="li">foo</router-link>

5、active-class
类型: string
默认值: “router-link-active”
设置 链接激活时使用的 CSS 类名。默认值可以通过路由的构造选项 linkActiveClass 来全局配置。

<router-link :to="/home" active-class="u-link--Active">Home</router-link>

6、exact-active-class
类型: string
默认值: “router-link-exact-active”
配置当链接被精确匹配的时候应该激活的 class。注意默认值也是可以通过路由构造函数选项 linkExactActiveClass 进行全局配置的。

7、exact [ɪɡ’zækt]
类型: boolean
默认值: false
每个路由被激活的时候都会设置class类名,但是使用exact这个属性就意味着只有在特定的路由地址才会激活链接类名

<!-- 这个链接只会在地址为 / 的时候被激活 -->
 <li><router-link to="/">全局匹配</router-link></li>
 <li><router-link to="/" exact>严格匹配</router-link></li>

简单点说,第一个的话,如果地址是/aa,或/aa/bb,……都会匹配成功,
但加上exact,只有当地址是/时被匹配,其他都不会匹配成功
8、event
类型: string | Array<string>
默认值: ‘click’
声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。

<router-link to="/document" event="mouseover">document</router-link>

如果我们不加event,那么默认情况下是当我们点击document的时候,跳转到相应的页面,但当我们加上event的时候,就可以改变触发导航的事件,比如鼠标移入事件

<router-link>属性小结(8个属性):
to replace append tag active-class exact event exact-active-class


命名视图

一个组件内同时展示多个视图

html
<div>
   <div class="container">
     <router-view/>
   </div>
   <div>
    <router-view name="orderInguide"></router-view>
   </div>
    <div>
    <router-view name="delivery"></router-view>
   </div>
    <div>
    <router-view name="history"></router-view>
   </div>
</div>
js
 {
      path: '/',
      name: 'home',
      components: {
        //默认输出hemo
        default:Home,
        //视图名:视图对应组件
        "orderInguide":OrderInguide,
        "delivery":Delivery,
        "history":History
      }
  },
嵌套命名视图
html
<!-- UserSettings.vue -->
<div>
  <h1>User Settings</h1>
  <NavBar/>
  <router-view/>
  <router-view name="helper"/>
</div>
js
{
  path: '/settings',
  // 你也可以在顶级路由就配置命名视图
  component: UserSettings,
  children: [{
    path: 'emails',
    component: UserEmailsSubscriptions
  }, {
    path: 'profile',
    components: {
      default: UserProfile,
      helper: UserProfilePreview
    }
  }]
}


嵌套路由

即在 VueRouter 的参数中使用 children 配置

routes: [
 {
      path: '/',
      name: 'about',
      component: About,
      redirect:'/about/context',
      children:[
        {
          path: '/about/context',
          name: 'context',
          component: Context,
          redirect:'/phone',
          children:[
            {
              path:'/phone',
              name:'phone',
              component:Phone
            },
            {
              path:'/personName',
              name:'personName',
              component:PersonName
            }
          ]
        }
      ]
    }
]

要注意,以 / 开头的嵌套路径会被当作根路径,children可以多层嵌套
redirect:’/phone’ 默认路由地址


编程式的导航

<router-link>创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
注意: $router访问的是路由器 r o u t e 访 问 的 是 当 前 的 路 由 ( 比 如 q u e r y − p a r a m s . . . ) 1 、 route访问的是当前的路由(比如query-params...) 1、 route访queryparams...1router.push()

      申明式                  编程式
<router-link :to="...">	   router.push/repalce(...)

to和push的参数类型可以是以下几种类型:

// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

注意:如果提供了 path,params 会被忽略,
也可以写成这样

const userId = 123
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123

2、$router.replace() 跟 router.push 很像区别:

  • router.push(); //直接添加一个路由,表现切换路由,本质往历史记录里面添加一个
  • router.replace() //替换路由,不会往历史记录里面添加
    3、$router.go(n)
    这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。
/ 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)

小结:$router.push/replace/go()


重定向和别名

“重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b,
重定向
重定向的三种方式

const router = new VueRouter({
  routes: [
    //1
    // { path: '/a', redirect: '/b' }
    //2
     { path: '/a', redirect: { name: 'foo' }}
  ]
})
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
    }}
  ]
})

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

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

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


路由组件传参

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

使用 props 将组件和路由解耦:

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User }
  ]
})
//props
const User = {
  props: ['id'],
  template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true },

    // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
    {
      path: '/user/:id',
      components: { default: User, sidebar: Sidebar },
      props: { default: true, sidebar: false }
    }
  ]
})

props的三种模式
1、布尔模式
如果 props 被设置为 true,route.params 将会被设置为组件属性。
2、对象模式
如果 props 是一个对象,它会被按原样设置为组件属性。

const router = new VueRouter({
  routes: [
    { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
  ]
})

3、函数模式
你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。

const router = new VueRouter({
  routes: [
    { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
  ]
})

[vue-router通过url传递参数给组件的props]
(https://blog.csdn.net/huipo22/article/details/80167136)
URL /search?q=vue 会将 {query: ‘vue’} 作为属性传递给 SearchUser 组件。
小结:路由组件传参 props代替动态路由参数 及props的三种类型(布尔、对象、函数)


路由元信息

和 HTML 中 header 部分的 meta 页面原信息类似,例如 description 有助于 seo 等,一般和路由没什么关系的配置可以写在这。

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      children: [
        {
          path: 'bar',
          component: Bar,
          // a meta field
          meta: { 
            title: 'this is app',
            description: 'xxx',
            requiresAuth: true 
          }
        }
      ]
    }
  ]
})

怎么访问到它呢?
一个路由匹配到的所有路由记录会暴露为 $route 对象 (还有在导航守卫中的路由对象) 的 $route.matched 数组。因此,我们需要遍历 $route.matched 来检查路由记录中的 meta 字段。

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!auth.loggedIn()) {
      next({
        path: '/login',
        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    next() // 确保一定要调用 next()
  }
})

meta扩展

导航守卫

router.beforeEach 全局前置守卫

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

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
每个守卫方法接收三个参数:

  • to: Route: 即将要进入的目标 路由对象

  • from: Route: 当前导航正要离开的路由

  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

  • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

  • next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

  • next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

  • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

导航守卫怎么实现错误回调

因为项目里用了懒加载,每次重新build之后有修改过的文件哈希码会改变,导致路由跳转到有修改过的页面会报页面文件404。所以想要在导航守卫执行next()的时候,如果发生错误就回调回来,重新刷新一次页面,让哈希码更新到最新就能够解决问题。

router.beforeEach((to, from, next) => {
  next(error);
})
router.onError(error => {...});

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

全局后置钩子 不会接受 next 函数也不会改变导航本身

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

beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

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

路由独享的守卫
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 的回调函数。
vue的其他一些的实例化方法:
router.back():回退一步
router.forward():前进一步
router.go(n):指定前进/回退的步数
router.push():导航到不同的 url,向 history 栈添加一个新的记录
router.replace():导航到不同 url,替换 history 栈中当前记录

小结:
有三种方式可以植入路由导航过程中:

全局的
前置守卫:router.beforeEach router.beforeResolve 后置钩子:router.afterEach
单个路由独享的: beforeEnter(写在路由配置中)

组件级的:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave


数据获取

有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。我们可以通过两种方式来实现:

  • 导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。
  • 导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航。

导航完成后获取数据
当你使用这种方式时,我们会马上导航和渲染组件,然后在组件的 created 钩子中获取数据。这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。
假设我们有一个 Post 组件,需要基于 $route.params.id 获取文章数据:

<template>
  <div class="post">
    <div class="loading" v-if="loading">
      Loading...
    </div>

    <div v-if="error" class="error">
      {{ error }}
    </div>

    <div v-if="post" class="content">
      <h2>{{ post.title }}</h2>
      <p>{{ post.body }}</p>
    </div>
  </div>
</template>
export default {
  data () {
    return {
      loading: false,
      post: null,
      error: null
    }
  },
  created () {
    // 组件创建完后获取数据,
    // 此时 data 已经被 observed 了
    this.fetchData()
  },
  watch: {
    // 如果路由有变化,会再次执行该方法
    '$route': 'fetchData'
  },
  methods: {
    fetchData () {
      this.error = this.post = null
      this.loading = true
      // replace getPost with your data fetching util / API wrapper
      getPost(this.$route.params.id, (err, post) => {
        this.loading = false
        if (err) {
          this.error = err.toString()
        } else {
          this.post = post
        }
      })
    }
  }
}

在导航完成前获取数据
通过这种方式,我们在导航转入新的路由前获取数据。我们可以在接下来的组件的 beforeRouteEnter 守卫中获取数据,当数据获取成功后只调用 next 方法。

export default {
  data () {
    return {
      post: null,
      error: null
    }
  },
  beforeRouteEnter (to, from, next) {
    getPost(to.params.id, (err, post) => {
      next(vm => vm.setData(err, post))
    })
  },
  // 路由改变前,组件就已经渲染完了
  // 逻辑稍稍不同
  beforeRouteUpdate (to, from, next) {
    this.post = null
    getPost(to.params.id, (err, post) => {
      this.setData(err, post)
      next()
    })
  },
  methods: {
    setData (err, post) {
      if (err) {
        this.error = err.toString()
      } else {
        this.post = post
      }
    }
  }
}

小结:导航完成之后获取路由数据 (通过组件当中的created()获取)
导航完成之前获取路由数据 (通过路由的生命周期获取 )


路由的滚动行为
const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return 期望滚动到哪个的位置

    return { x: 0, y: 0 }
  }
})

scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。

这个方法返回滚动位置的对象信息,长这样:

{ x: number, y: number }
{ selector: string, offset? : { x: number, y: number }} (offset 只在 2.6.0+ 支持)

如果返回一个 falsy (译者注:falsy 不是 false)的值,或者是一个空对象,那么不会发生滚动。
通过Falsy Bouncer(算法)得出Falsy值,当进行逻辑判断时均为false(如!!false==false)。六个Falsy值:false、undefined、null、正负0、NaN、""。

savedPosition在按下 后退/前进 按钮时,就会像浏览器的原生表现那样:

scrollBehavior (to, from, savedPosition) {
  if (savedPosition) {
    return savedPosition
  } else {
    return { x: 0, y: 0 }
  }
}

滚动到锚点

scrollBehavior (to, from, savedPosition) {
 return {selector:'className'}
}

异步滚动

scrollBehavior (to, from, savedPosition) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ x: 0, y: 0 })
    }, 500)
  })
}

小结:滚动行为:
1、自定义位置
2、滚动到与元素所对应的位置
3、异步滚动 延迟…


路由懒加载懒加载

懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。
结合 Vue 的异步组件和 Webpack 的代码分割功能

<router-view>

<router-view>组件是一个 functional(功能) 组件,渲染路径匹配到的视图组件。<router-view>渲染的组件还可以内嵌自己的 <router-view>,根据嵌套路径,渲染嵌套组件。
其他属性 (非 router-view 使用的属性) 都直接传给渲染的组件, 很多时候,每个路由的数据都是包含在路由参数中。
因为它也是个组件,所以可以配合 <transition><keep-alive>使用。如果两个结合一起用,要确保在内层使用 <keep-alive>

<router-view>name属性

类型: string
默认值: “default”
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 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>

一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):

const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})

Router 构建选项

1、routes
类型: Array
RouteConfig(路由配置) 的类型定义:

declare type RouteConfig = {
  path: string;
  component?: Component;
  name?: string; // 命名路由
  components?: { [name: string]: Component }; // 命名视图组件
  redirect?: string | Location | Function;
  props?: boolean | Object | Function;
  alias?: string | Array<string>;
  children?: Array<RouteConfig>; // 嵌套路由
  beforeEnter?: (to: Route, from: Route, next: Function) => void;
  meta?: any;

  // 2.6.0+
  caseSensitive?: boolean; // 匹配规则是否大小写敏感?(默认值:false)
  pathToRegexpOptions?: Object; // 编译正则的选项
}

2、mode
类型: string
默认值: “hash” (浏览器环境) | “abstract” (Node.js 环境)
可选值: “hash” | “history” | “abstract”
配置路由模式:

  • hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器。
  • history: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。
  • abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。

3、base
类型: string
默认值: “/”
应用的基路径。例如,如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 “/app/”。

4、linkActiveClass
类型: string
默认值: “router-link-active”
全局配置 的默认“激活 class 类名”。

5、linkExactActiveClass
类型: string
默认值: “router-link-exact-active”
全局配置 精确激活的默认的 class。可同时翻阅 router-link。
linkActiveClass 和 linkExactActiveClass
6、scrollBehavior
类型: Function

type PositionDescriptor =
  { x: number, y: number } |
  { selector: string } |
  ?{}

type scrollBehaviorHandler = (
  to: Route,
  from: Route,
  savedPosition?: { x: number, y: number }
) => PositionDescriptor | Promise<PositionDescriptor>

7、parseQuery / stringifyQuery
类型: Function
提供自定义查询字符串的解析/反解析函数。覆盖默认行为。
定制 query 信息
vue 会默认处理,如果有特定需求,可以借助这两个配置项。

/ router.js
export default () => {
  return new Router({
    parseQuery (query) {},
    stringifyQuery (obj) {}
  })
}

8、fallback
类型: boolean
不是所有浏览器都支持前端路由的方式,如果不支持,设置 fallback: true,vue 会自动 fallback 到 hash 模式。默认值为 true。
在 IE9 中,设置为 false 会使得每个 router-link 导航都触发整页刷新。它可用于工作在 IE9 下的服务端渲染应用,因为一个 hash 模式的 URL 并不支持服务端渲染。
Vue-router之配置
小结:Router 构建选项(8):routes mode base linkActiveClass linkExactActiveClass scrollBehavior parseQuery / stringifyQuery fallback


Router 实例属性

1、router.app
类型: Vue instance(实例)
配置了 router 的 Vue 根实例。
2、router.mode
类型: string
路由使用的模式。
3、router.currentRoute
类型: Route
当前路由对应的路由信息对象。
小结:Router 实例属性(3)router.app router.mode router.currentRoute


Router 实例方法

router.beforeEach
router.beforeResolve
router.afterEach

router.beforeEach((to, from, next) => {
  /* must call `next` */
})

router.beforeResolve((to, from, next) => {
  /* must call `next` */
})

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

router.push
router.replace
router.go
router.back
router.forward

编程式导航
router.push(location, onComplete?, onAbort?)
router.replace(location, onComplete?, onAbort?)
router.go(n)
router.back()
router.forward()

router.getMatchedComponents
router.resolve
router.addRoutes
router.onReady
router.onError
注册一个回调,该回调会在路由导航过程中出错时被调用。注意被调用的错误必须是下列情形中的一种:

  • 错误在一个路由守卫函数中被同步抛出;
  • 错误在一个路由守卫函数中通过调用 next(err) 的方式异步捕获并处理;
  • 渲染一个路由的过程中,需要尝试解析一个异步组件时发生错误。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值