Vue Router路由搭建

用Vue.js + Vue Router 创建单页面应用,是很方便的。使用Vue.js,我们通过组合组件来组成应用程序,当你要把Vue Router 添加进来,我们需要做的是将组件(components)映射到路由(routes),然后告诉Vue Router 在哪里渲染它们。

搭建一个简单路由的例子:

HTML

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- 使用 router-link 组件来导航. -->
    <!-- 通过传入 `to` 属性指定链接. -->
    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    <router-link to="/router1">这是路由一</router-link>
    <router-link to="/router2">这是路由二</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>

JS

// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)

// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const content1 = { template: '<div>内容一</div>' }
const content2 = { template: '<div>内容二</div>' }

// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
  { path: '/router1', component: content1},
  { path: '/router2', component: content2 }
]

// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
  routes // (缩写) 相当于 routes: routes
})

// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
  router
}).$mount('#app')

// 现在,应用已经启动了!

 

嵌套路由

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如:

/user/foo/profile                     /user/foo/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

借助vue-router,使用嵌套路由配置,就可以很简单地表达这种关系。

<div id="app">
  <router-view></router-view>
</div>
const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

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

这里的<router-vue>是最顶层的出口,渲染最高级路由匹配到的组件。同样地,一个被渲染组件同样可以包含自己的嵌套<router-vue>。例如,在User组件的模板添加一个<router-vue>:

const User = {
  template: `
    <div class="user">
      <h2>User {{ $route.params.id }}</h2>
      <router-view></router-view>
    </div>
  `
}

要在嵌套的出口中渲染组件,需要在VueRouter的参数中使用children配置:

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // 当 /user/:id/profile 匹配成功,
          // UserProfile 会被渲染在 User 的 <router-view> 中
          path: 'profile',
          component: UserProfile
        },
        {
          // 当 /user/:id/posts 匹配成功
          // UserPosts 会被渲染在 User 的 <router-view> 中
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})

要注意,以 / 开头的嵌套路径会被当做根路径。这让你专注地使用嵌套组件而无须设置嵌套的路径。

你会发现,children配置就是像routes配置一样的路由配置数组,所以呢,你可以嵌套多层路由。

此时,基于上面的配置,当你访问 /user/foo 时,User的出口是不会渲染任何的东西,这是因为没有匹配到合适的子路由。如果你想要渲染点什么,可以提供一个空的子路由:

const router = new VueRouter({
  routes: [
    {
      path: '/user/:id', component: User,
      children: [
        // 当 /user/:id 匹配成功,
        // UserHome 会被渲染在 User 的 <router-view> 中
        { path: '', component: UserHome },

        // ...其他子路由
      ]
    }
  ]
})

 

编程式导航

除了使用<router-link> 创建a标签来定义导航链接,我们还可以借助router的实例方法,通过编写代码来实现。

router.push(location, onComplete?, onAbort)

 注意:在Vue实例内部,你可以通过$router访问路由实例。因此你可以调用this.$router.push。

想要导航到不同的URL,则使用router.push方法。这个方法会向history栈添加一个新的记录,所以当用户点击浏览器后退按钮时,则回到之前的URL。

当你点击<router-link>时,这个方法会在内部调用,所以说,点击<router-link :to=”....“>  等同调用 router.push(...)。

声明式编程式
<router-link :to="...">router.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 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的name 或者手写完整的带有参数的path:

const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

注意:如果目的地和当前路由相同,只有参数发生了改变(比如从一个用户资料到另一个/user/1 > /usesr/2),你需要使用 beforeRouteUpdate 来响应这个变化(比如抓取用户信息)。

router.replace(location, onComplete?, onAbort?)

跟router.push 很像,唯一的不同就是,它不会向history添加新记录,而是跟它的方法名一样 —— 替换当前的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)

// 前进 3 步记录
router.go(3)

// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)

 

路由懒加载

当打包构建应用时,JavaScript包会变得非常大,影响页面加载。如果我们能把不用路由对应的组件分割成不用的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

结合Vue的异步组件和webpack的代码分割功能,便轻松实现路由组件多的懒加载。

首先,可以将异步组件定义为返回一个Promise的工厂函数(该函数返回的Promise应该resolve组件本身):

const Foo = () => Promise.resolve({ /* 组件定义对象 */ })

第二,在webpack中,我们可以使用动态 import 语法来定义代码分块点(split point):

import('./Foo.vue') // 返回 Promise

结合以上两点,就可以定义一个能够被webpack自动代码分割的异步组件。

const Foo = () => import('./Foo.vue')

在路由配置中什么都不需要改变,只需要像往常一样使用 Foo:

const router = new VueRouter({
  routes: [
    { path: '/foo', component: Foo }
  ]
})

 

把组件按组分块

有时候我们想把某个路由下的所有组件都打包在同个异步块(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')

webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。

 

更多内容可移步Vue Router官方文档

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值