Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vue ssr疑问点 #33

Open
Jmingzi opened this issue May 7, 2018 · 0 comments
Open

vue ssr疑问点 #33

Jmingzi opened this issue May 7, 2018 · 0 comments

Comments

@Jmingzi
Copy link
Owner

Jmingzi commented May 7, 2018

1. 关于getMatchedComponents

entry-server中,根据当前路由匹配出的组件,只包含路由组件么?而不包含路由组件中引用的子组件。
例如:

// route Component A
// 引入了 BottomTab 组件,在BottomTab组件中需要预取数据
<route-a>
  <bottom-tab />
</route-a>

而此时组件BottomTab,并没有被getMatchedComponents匹配到。

2.关于在客户端预取数据

起初看到官方文档数据的预取与渲染这里时,对客户端数据的预取很不理解,客户端为何要预取数据?

官方有2种实现:

// 1. 在entry-client.js中实现
router.onReady(() => {
  // 在路由初始化完成后,注册钩子函数去处理路由变化时,对组件的一些操作,比如数据预取。
  router.beforeResolve((to, from, next) => {
    // 在这里会根据to, from,来getMatchedComponents
    // 从而匹配出相应的路由组件
    // 筛选出to和from不一致的情况下,也就是跳转的路由与当前不一致时,才去预取数据
    // 为什么会这么做?我猜是在这种情况下,例如获取文章详情,或分类列表
    // 它们的路由看起来是这样的:`/detail/1`,`/list/1`,当路由变化时,组件并没有改变
    // 所以不需要去预取数据的,所以也就避免了二次预取(double-fetch)已有的数据
    const matched = router.getMatchedComponents(to)
    const prevMatched = router.getMatchedComponents(from)
    let diffed = false
    const activated = matched.filter((c, i) => {
      return diffed || (diffed = (prevMatched[i] !== c))
    })
    if (!activated.length) {
      return next()
    }
  })
})

我们再来看第二种实现来论证这个观点:

// 2. 通过全局的mixin,来注册生命周期钩子函数
Vue.mixin({
 // beforeMount只会在组件初始化时调用
 // 在`/detail/1`,`/list/1`这种路由发生变化时,是不会调用的
 // 也就论证了上面的说法成立
 beforeMount () {
   const { asyncData } = this.$options
   if (asyncData) {
     // 将获取数据操作分配给 promise
     // 以便在组件中,我们可以在数据准备就绪后
     // 通过运行 `this.dataPromise.then(...)` 来执行其他任务
     this.dataPromise = asyncData({
       store: this.$store,
       route: this.$route
     })
   }
 }
})

在实际的项目中,规避double-fetch的做法有很多,客户端数据预取的实现也有很多,通常我们是在created钩子中去做这个事情,例如:

{
  created() {
    if (this.list === null) {
      // 当list为null时,才去取数据
      this.fetchData()
    }
  }
}

我想,这跟官方的数据的预取是一个道理吧

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant