vue-router相关基础知识及工作原理(6)

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

首先,我们称呼 routes 配置中的每个路由对象为 路由记录。路由记录可以是嵌套的,因此,当一个路由匹配成功后,他可能匹配多个路由记录

例如,根据上面的路由配置,/foo/bar 这个 URL 将会匹配父路由记录以及子路由记录。

一个路由匹配到的所有路由记录会暴露为 $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()
 }
})

数据获取

我的理解就是在哪里获取数据,可以再组件里面,也可以在组件的守卫里面,也就是组件的生命周期里面。

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

导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示『加载中』之类的指示。

导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航。

从技术角度讲,两种方式都不错 —— 就看你想要的用户体验是哪种。

导航完成后获取数据

当你使用这种方式时,我们会马上导航和渲染组件,然后在组件的 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
    }
   })
  }
 }
}
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/260.html