为了测试VueJS服务器边缘渲染,我试图解决一些问题。我已经使用最新的VueJS Hackernews 2.0作为此项目的样板。
目前我坚持这个:
服务器使用preFetch
预取数据。都好。
当用户路由到此组件时,在beforeRouteEnter
函数内调用相同的函数。一切都好。
但是,当用户第一次加载时,preFetchData
函数会被调用2次。进入preFetch
后进入beforeRouteEnter
。
这是有道理的,因为这就是Vue路由器的工作原理。 preFetch
在服务器上运行,只要Vue在客户端中呈现,beforeRouteEnter
就会被调用。
但是,我不希望Vue在第一次加载时执行此操作2次,因为数据已经从服务器端呈现函数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')
答案 0 :(得分:3)
我已经想出了什么。我将使用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()
}
}
答案 1 :(得分:0)
您也可以查看是否在服务器上。
this.$isServer
或
Vue.prototype.$isServer
如果您是本地人,则只调用您的beforeRouteEnter预取。
beforeRouteEnter(to, from, next) {
// We only want to use this when on the client, not the server
// On the server we have preFetch
if (!this.$isServer) {
console.log('beforeRouterEnter, only on client')
preFetchData(store)
next()
} else {
// We are on the server, just pass it
next()
}
},
答案 2 :(得分:0)
你可以做什么在商店设置一个变量,说明这个页面的数据已经加载了。读取该变量以查看是否应该调用ajax请求。
答案 3 :(得分:0)
我只是检查窗口对象是否在组件的created
方法中定义:
created () {
if (typeof window === 'undefined') {
// we're in server side
} else {
// we're in the client
}
}