最近在重构博客系统前端代码,企图更换框架为Nuxtjs
踩了不少坑,有webpack打包的坑,有服务端渲染的坑
今天记录一下久攻不下的store 状态树相关问题
实践
博客系统有全局布局组件,如:Header(页首),Footer(页脚),Player(播放器),ChatRoom(聊天室)等等状态组件
由于Nuxt.js是服务端渲染框架,在碰到下面这种需要动态请求数据控制的组件不太友好:
<template>
<Player v-if="isPlayer" />
</template>
javascript
起初尝试使用asyncData实现服务端数据请求:
//layout/default.vue
<template>
<Player v-if="isPlayer" />
</template>
<script>
export default {
name:"default",
async asyncData({store}) {
let data = await axios.get("https://******/***")
return {
isPlayer: data.data
}
}
}
javascript
其中store/index.js源代码
// store/index.js
import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";
Vue.use(Vuex);
export default ()=>new Vuex.Store({
state: {
isPlayer: {}
},
mutations: {
checkIsPlayer(state, isPlayer) {
state.isPlayer= isPlayer;
}
}
})
javascript
但是还是失败,考虑是异步请求执行顺序的问题,虽然state值成功设置,但是页面渲染仍获取为null值,即跟不上页面渲染
于是考虑更高级别优先级的生命周期函数——nuxtServerInit钩子函数
改写store/index.js,添加nuxtServerInit
// store/index.js
import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";
Vue.use(Vuex);
export default ()=>new Vuex.Store({
state: {
isPlayer: {}
},
mutations: {
checkIsPlayer(state, isPlayer) {
state.isPlayer= isPlayer;
}
},
actions: {
nuxtServerInit(store){
axios.get("https://******/***")
.then(({data})=>{
console.log('nuxtServerInit',data)
store.commit('isPlayer', data.data)
console.log(store.state)
})
}
}
})
javascript
相应地,layout/default.vue更改为:
//layout/default.vue
<template>
<Player v-if="$store.state.isPlayer" />
</template>
javascript
但是依旧失败,虽然state值成功设置,但是页面渲染仍获取为null值,即还是跟不上页面渲染
经过实践
后经过多次尝试,将nuxtServerInit改为异步请求成功解决问题:
// store/index.js
import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";
Vue.use(Vuex);
export default ()=>new Vuex.Store({
state: {
isPlayer: {}
},
mutations: {
checkIsPlayer(state, isPlayer) {
state.isPlayer= isPlayer;
}
},
actions: {
async nuxtServerInit(store){
await axios.get("https://******/***")
.then(({data})=>{
console.log('nuxtServerInit',data)
store.commit('isPlayer', data.data)
console.log(store.state)
})
}
}
})
javascript
页面成功渲染且不报错
完工。





