Nuxt 通用应用程序。服务器端的 Vuex 存储在请求之间缓存,与用户的机器无关
Nuxt universal app. Vuex store on server side is cached between requests irrespective of the user's machine
我在 Nuxt Universal Apps 的生产实例中观察到以下行为:
给定“用户A”进行页面请求访问nuxt的服务器端和服务器端方法如asyncData
调度进程中的状态变化
if“用户 B”在另一台机器上通过服务器端方法向服务器请求状态数据“用户 A”较早更改,
然后“用户 B”将能够访问该数据。
ergo nuxt 将 Vuex 视为服务器上的单个存储,不区分不同的调用者。
是否有可配置的方法来防止这种行为并坚持每个用户只能访问与其本地计算机关联的数据?
[编辑]
根据要求,这是商店 index.js
的近似值
import { omit } from 'lodash'
import Vue from 'vue'
// we drafted some methods for automatically generating generic getters and setter-mutators.
// Also, default actions are setup where a list of names are given, that automatically commit to generic setter mutators.
// see comments in the code below...
import {
autoMapGetters,
autoMapMutations,
autoMapActions
} from '~/libs/autoMap'
const _state = {
centre: { id: -1 },
devEmail: 'foo@bar.com',
barApiUrl: process.env.FooUrl + '/foo',
barDownloadImg: process.env.FooUrl + process.env.FooImg,
barDownloadLockImg: process.env.FooUrl + process.env.FoobarDownloadLockImg,
FooLoginUrl: process.env.FooUrl + '/foo/auth',
FooBarUrl: process.env.FooUrl + '/bar',
FooUrl: process.env.FooUrl,
loading: false,
warnings: {}
}
export default {
state: () => (_state),
getters: autoMapGetters(_state, {
foo: (state) => state.foo.someSpecialProperty ? { foo: 'I am different' } : {},
etc: (state) => etc
// For example, autoMapGetters will set:
// centre: (state) => state.centre
}),
mutations: autoMapMutations(_state, {
clearWarning (_state, key) { Vue.delete(_state.warnings, key) },
clearWarnings (_state) { _state.warnings = {} },
setWarning (_state, { key, value }) { _state.warnings[key] = value }
// For example, a autoMapMutations will generate:
// setCentre (state, centre) { state.centre = centre }
}),
actions: autoMapActions(_state, {
// special action, launched server-side ------------------------------------
nuxtServerInit ({ state, commit, getters, dispatch }, { params }) {
dispatch('foo-module/resetAll')
dispatch('foo-module/resetMainInformation')
},
// Normal actions ----------------------------------------------------------
clearCentre ({ commit }) { commit('setCentre', { id: -1 }) },
setCentre ({ commit, dispatch }, centre) {
commit('setCentre', omit(centre, 'user'))
dispatch('bar-module/setUser', centre.user)
},
clearWarning ({ commit }, key) { commit('clearWarning', key) },
clearWarnings ({ commit }) { commit('clearWarnings') },
setWarning ({ commit }, { key, value }) { commit('setWarning', { key, value }) }
// For Example, autoMapActions will generate:
// setLoading ({ commit }, value) { commit('setLoading', value) }
}, [
'loading',
'warnings'
])
}
在我看来,它在文档中不是很清楚**,但您需要将商店导出为函数(使用显式或隐式 return)——而不是对象。导出为函数会在服务器上创建一个新存储,而导出为普通对象将始终 return 相同的对象。
**编辑:似乎 docs 已经更新以突出显示这一点。
这是文档中的示例:
export const state = () => ({
list: []
})
注意到 ()
包裹了对象字面量?
考虑到这一点,尝试调整您的代码(伪代码示例,我相信您会弄清楚将状态传递到您的自动映射方法中!)
import { omit } from 'lodash'
import Vue from 'vue'
import {
autoMapGetters,
autoMapMutations,
autoMapActions
} from '~/libs/autoMap'
export const state = () => ({
centre: { id: -1 },
devEmail: 'foo@bar.com',
barApiUrl: process.env.FooUrl + '/foo',
barDownloadImg: process.env.FooUrl + process.env.FooImg,
barDownloadLockImg: process.env.FooUrl + process.env.FoobarDownloadLockImg,
FooLoginUrl: process.env.FooUrl + '/foo/auth',
FooBarUrl: process.env.FooUrl + '/bar',
FooUrl: process.env.FooUrl,
loading: false,
warnings: {}
})
export const getters = {
// ... your automap method here
}
export const mutations = {
// ... your automap method here
}
export const actions = {
// nuxtServerInit etc ...
}
我在 Nuxt Universal Apps 的生产实例中观察到以下行为:
给定“用户A”进行页面请求访问nuxt的服务器端和服务器端方法如asyncData
调度进程中的状态变化
if“用户 B”在另一台机器上通过服务器端方法向服务器请求状态数据“用户 A”较早更改,
然后“用户 B”将能够访问该数据。
ergo nuxt 将 Vuex 视为服务器上的单个存储,不区分不同的调用者。
是否有可配置的方法来防止这种行为并坚持每个用户只能访问与其本地计算机关联的数据?
[编辑] 根据要求,这是商店 index.js
的近似值import { omit } from 'lodash'
import Vue from 'vue'
// we drafted some methods for automatically generating generic getters and setter-mutators.
// Also, default actions are setup where a list of names are given, that automatically commit to generic setter mutators.
// see comments in the code below...
import {
autoMapGetters,
autoMapMutations,
autoMapActions
} from '~/libs/autoMap'
const _state = {
centre: { id: -1 },
devEmail: 'foo@bar.com',
barApiUrl: process.env.FooUrl + '/foo',
barDownloadImg: process.env.FooUrl + process.env.FooImg,
barDownloadLockImg: process.env.FooUrl + process.env.FoobarDownloadLockImg,
FooLoginUrl: process.env.FooUrl + '/foo/auth',
FooBarUrl: process.env.FooUrl + '/bar',
FooUrl: process.env.FooUrl,
loading: false,
warnings: {}
}
export default {
state: () => (_state),
getters: autoMapGetters(_state, {
foo: (state) => state.foo.someSpecialProperty ? { foo: 'I am different' } : {},
etc: (state) => etc
// For example, autoMapGetters will set:
// centre: (state) => state.centre
}),
mutations: autoMapMutations(_state, {
clearWarning (_state, key) { Vue.delete(_state.warnings, key) },
clearWarnings (_state) { _state.warnings = {} },
setWarning (_state, { key, value }) { _state.warnings[key] = value }
// For example, a autoMapMutations will generate:
// setCentre (state, centre) { state.centre = centre }
}),
actions: autoMapActions(_state, {
// special action, launched server-side ------------------------------------
nuxtServerInit ({ state, commit, getters, dispatch }, { params }) {
dispatch('foo-module/resetAll')
dispatch('foo-module/resetMainInformation')
},
// Normal actions ----------------------------------------------------------
clearCentre ({ commit }) { commit('setCentre', { id: -1 }) },
setCentre ({ commit, dispatch }, centre) {
commit('setCentre', omit(centre, 'user'))
dispatch('bar-module/setUser', centre.user)
},
clearWarning ({ commit }, key) { commit('clearWarning', key) },
clearWarnings ({ commit }) { commit('clearWarnings') },
setWarning ({ commit }, { key, value }) { commit('setWarning', { key, value }) }
// For Example, autoMapActions will generate:
// setLoading ({ commit }, value) { commit('setLoading', value) }
}, [
'loading',
'warnings'
])
}
在我看来,它在文档中不是很清楚**,但您需要将商店导出为函数(使用显式或隐式 return)——而不是对象。导出为函数会在服务器上创建一个新存储,而导出为普通对象将始终 return 相同的对象。
**编辑:似乎 docs 已经更新以突出显示这一点。
这是文档中的示例:
export const state = () => ({
list: []
})
注意到 ()
包裹了对象字面量?
考虑到这一点,尝试调整您的代码(伪代码示例,我相信您会弄清楚将状态传递到您的自动映射方法中!)
import { omit } from 'lodash'
import Vue from 'vue'
import {
autoMapGetters,
autoMapMutations,
autoMapActions
} from '~/libs/autoMap'
export const state = () => ({
centre: { id: -1 },
devEmail: 'foo@bar.com',
barApiUrl: process.env.FooUrl + '/foo',
barDownloadImg: process.env.FooUrl + process.env.FooImg,
barDownloadLockImg: process.env.FooUrl + process.env.FoobarDownloadLockImg,
FooLoginUrl: process.env.FooUrl + '/foo/auth',
FooBarUrl: process.env.FooUrl + '/bar',
FooUrl: process.env.FooUrl,
loading: false,
warnings: {}
})
export const getters = {
// ... your automap method here
}
export const mutations = {
// ... your automap method here
}
export const actions = {
// nuxtServerInit etc ...
}