为了测试VueJS服务器端渲染,我正在尝试弄清楚一些事情。我已使用最新的VueJS Hackernews 2.0作为该项目的样板。

目前,我一直坚持:

服务器使用preFetch预取数据。都好。
当用户路由到此组件时,在beforeRouteEnter函数内部将调用同一函数。都好。

但是,当用户第一次加载它时,preFetchData函数被调用两次。一次在preFetch中,一次在beforeRouteEnter中。

这是有道理的,因为这就是Vue Router的工作方式。 preFetch在服务器上运行,一旦Vue在客户端中渲染,就立即调用beforeRouteEnter

但是,我不希望Vue在第一次加载时执行两次此操作,因为数据已经在服务器端呈现功能preFetch的存储中。

我无法检查数据是否已经在存储中,因为我希望该组件始终对beforeRouteEnter进行API调用。只是第一次从服务器渲染时不是这样。

在这种情况下如何只获取一次数据?

  <template>
    <div class="test">
        <h1>Test</h1>
      <div v-for="item in items">
        {{ item.title }}
      </div>
    </div>
  </template>

  <script>
  import store from '../store'

  function preFetchData (store) {
    return store.dispatch('GET_ITEMS')
  }

  export default {
    beforeRouteEnter (to, from, next) {
      // We only want to use this when on the client, not the server
      // On the server we have preFetch
      if (process.env.VUE_ENV === 'client') {
        console.log('beforeRouterEnter, only on client')
        preFetchData(store)
        next()
      } else {
        // We are on the server, just pass it
        next()
      }
    },
    name: 'test',
    computed: {
      items () {
        return this.$store.state.items
      }
    },
    preFetch: preFetchData // Only on server
  }
  </script>

  <style lang="scss">
  .test {
    background: #ccc;
    padding: 40px;

    div {
      border-bottom: 1px red solid;
    }
  }
  </style>

在上面的代码中:API调用在store.dispatch('GET_ITEMS')中完成

最佳答案

我已经弄明白了。我将使用from.name检查用户来自何处。如果这是null,则意味着用户第一次加载页面,因为我命名了所有路线。这样我们就知道我们正在提供服务器呈现的HTML:

beforeRouteEnter (to, from, next) {
    if (from.name && process.env.VUE_ENV === 'client') {
      preFetchData(store).then(data => {
        next(vm => {
          // do something
        })
      })
    } else {
      next()
    }
  }

关于javascript - VueJS 2.0服务器端渲染:如何使用preFetch和beforeRouteEnter仅获取一次数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41586718/

10-11 23:24
查看更多