diz*_*tar 8 javascript vue.js server-side-rendering vuex
我正在尝试让服务器端渲染在 VueJS 中工作。
我一直在关注官方文档,并且正在尝试使用 axios 使此示例正常工作。端点是正确的,数据确实显示在mutation.
https://ssr.vuejs.org/guide/data.html
我也找到了这个页面并尝试了其中的大部分示例,其中包括使用 getter、vuex mapState、mapGetter 等:
这是store/index.js:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import { fetchPage } from './api'
export function createStore () {
return new Vuex.Store({
strict: true,
state: () => ({
res: {}
}),
actions: {
actXY ({ commit }, page) {
fetchPage('homepage').then((item) => {
commit('mutXY', { page, item });
}).catch(error => {
throw new Error(`Store ${error}`);
})
}
},
mutations: {
mutXY (state, { page, item }) {
Vue.set(state.res, page, item);
console.log(state.res.homepage.data)
}
},
getters: {
getXY (state) {
return state.res
}
}
})
}
Run Code Online (Sandbox Code Playgroud)
控制台日志显示正确的信息,这意味着 axios 端点正在工作并更新状态对象。最初,我试图调用mutation,但此后我尝试调用getter. 不幸的是,新数据没有在 中更新getter,所以当然,组件中没有显示任何新数据。
这是HomePage.vue:
<template>
<div v-if="htmlData">{{ JSON.stringify(htmlData) }}</div>
<div v-else>loading?</div>
</template>
<script>
export default ({
name: 'homepage',
computed: {
htmlData () {
console.log("computed = " + JSON.stringify(this.$store.state.res));
console.log(this.$store.getters.getXY);
return this.$store.getters
// return this.getQuery()
}
},
serverPrefetch () {
return this.getData()
},
mounted () {
console.log("in mounted")
if (!this.item) {
this.getData()
}
},
methods: {
getData () {
return this.$store.dispatch('actXY', 'homepage')
}
}
})
</script>
Run Code Online (Sandbox Code Playgroud)
如所写,htmlData将显示:
{"getXY":{}}
Run Code Online (Sandbox Code Playgroud)
是的,我确实尝试了许多其他关于如何退回商店商品的变体,getter,但没有任何效果。
除了上面链接中的内容,我还四处寻找配置文件的变化,我尝试添加async到 store/actions、getData() 等。
我也尝试过直接在组件中进行 axios 调用,没有成功。
由于这是一个已经或多或少在 VueJS 中完成的项目,我正在将其转换为 SSR,因此我从 package.json 中删除了所有内容并重新安装了每个包,希望可能是旧的 vue 包之一导致了冲突。
我还尝试了从官方文档中拆分商店代码,并尝试了如何编写路由的变体。什么都不起作用。
我想我应该在运行当前代码时添加打印语句显示的内容:
computed = undefined
computed mm = undefined
getter = {}
computed get = {"getXY":{}}
{
title: 'Home'...}
Run Code Online (Sandbox Code Playgroud)
组件中的计算属性在设置突变之前运行。这会导致在更新突变之前调用 getter。同样,如果我尝试res直接从组件调用更改,则在调用和呈现商店时不会发生任何变化。
这是我试图运行的代码的回购:https : //github.com/dt1/vue-ssr-attempt
(我想出了答案。我已经用对我有用的东西更新了 repo,下面是我的解决方案的解释)
好吧,我终于明白了这一点。
我遇到的主要问题是乱序调用。当我修正顺序时,我遇到了Converting circular structure to JSON错误。接下来尝试了解 VueJS、Vuex 存储和 axios 之间的回调函数是如何运行的。
我想出的最终解决方案是:
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import * as util from 'util'
Vue.use(Vuex)
import { fetchPage } from './api'
export function createStore () {
return new Vuex.Store({
strict: true,
state: () => ({
res: {}
}),
actions: {
actXY ({ commit }, page) {
return fetchPage(page).then(item => {
commit('mutXY', { page , item } );
})
}
},
mutations: {
mutXY (state, {page, item }) {
Vue.set(state.res, page, item);
}
}
})
}
Run Code Online (Sandbox Code Playgroud)
然后,在进行 axios 调用时,我必须确保仅返回而response.data不是整个响应。在此之前,我收到一个unhandled promise错误。
api.js
import Vue from 'vue';
import axios from 'axios';
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios);
Vue.axios.defaults.baseURL = '<url goes here>';
export function fetchPage(page){
return Vue.axios.get(page).then((resp => resp.data))
}
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要的一点是,这是Homepage.vue。
为了触发更新,我必须使 getData() 异步:
<template>
<div v-if="htmlData">
<div>{{ htmlData.title }}</div>
<div>{{ htmlData.description }}</div>
<div>{{ htmlData.html }}</div>
</div>
</template>
<script>
export default ({
name: 'homepage',
computed: {
htmlData () {
return this.$store.state.res.homepage
}
},
serverPrefetch () {
return this.getData()
},
mounted () {
if (!this.item) {
this.getData()
}
},
methods: {
async getData () {
await this.$store.dispatch('actXY', 'homepage')
}
}
})
</script>
Run Code Online (Sandbox Code Playgroud)
希望这对遇到所有这些问题的人有所帮助。
| 归档时间: |
|
| 查看次数: |
1221 次 |
| 最近记录: |