页面刷新时的 Vuex 状态
Vuex state on page refresh
我的应用使用 Firebase API 进行用户身份验证,将登录状态保存为 Vuex 状态中的布尔值。
当用户登录时,我设置 登录状态 并相应地有条件地显示 Login/Logout 按钮。
但是当页面刷新时,vue app的状态丢失并重置为默认值
这会导致问题,因为即使用户已登录并刷新页面,登录状态 也会设置回 false即使用户保持登录状态,也会显示登录按钮而不是注销按钮....
我应该怎么做才能防止这种行为
我可以使用 cookies
或者还有其他更好的解决方案...
-
这是一个已知用例。有不同的解决方案。
例如,可以使用vuex-persistedstate
。这是 vuex
用于处理和存储页面刷新之间的状态的插件。
示例代码:
import { Store } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'
const store = new Store({
// ...
plugins: [
createPersistedState({
getState: (key) => Cookies.getJSON(key),
setState: (key, state) => Cookies.set(key, state, { expires: 3, secure: true })
})
]
})
我们这里做的很简单:
- 您需要安装
js-cookie
- 在
getState
我们尝试从 Cookies
加载保存的状态
- 在
setState
我们将我们的状态保存到 Cookies
我已经通过每次 re-load 也获取用户数据时重置我的 headers 来解决这个问题,我不知道什么更好...
new Vue({
el: 'vue',
render: h => h(VueBox),
router,
store,
computed: {
tokenJWT () {
return this.$store.getters.tokenCheck
},
},
created() {
this.setAuth()
},
methods:
Object.assign({}, mapActions(['setUser']), {
setAuth(){
if (this.tokenJWT) {
if (this.tokenJWT === 'expired') {
this.$store.dispatch('destroyAuth')
this.$store.dispatch('openModal')
this.$store.dispatch('setElModal', 'form-login')
} else {
window.axios.defaults.headers.common = {
'Accept': 'application/json',
'Authorization': 'Bearer ' + this.tokenJWT
}
axios.get( api.domain + api.authApi )
.then(res => {
if (res.status == 200) {
this.setUser( res.data.user )
}
})
.catch( errors => {
console.log(errors)
this.destroyAuth()
})
}
}
}
})
})
我认为使用cookies/localStorage保存登录状态在某些情况下可能会导致一些错误。
Firebase 已经在 localStorage 为我们记录了登录信息,包括 expirationTime 和 refreshToken。
因此,我将使用 Vue 创建的钩子和 Firebase api 来检查登录状态。
如果令牌已过期,api 将为我们刷新令牌。
所以我们可以确保我们的应用程序中显示的登录状态等于 Firebase。
new Vue({
el: '#app',
created() {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
log('User is logined');
// update data or vuex state
} else {
log('User is not logged in.');
}
});
},
});
穿上状态:
producer: JSON.parse(localStorage.getItem('producer') || "{}")
进行突变:
localStorage.setItem("producer",JSON.stringify(state.producer)) // OR
localStorage.removeItem("producers");
对我来说很好用!
创建 VueX 状态时,使用 vuex-persistedstate 插件将其保存到会话存储中。这样,当浏览器关闭时,信息就会丢失。避免使用 cookie,因为这些值将在客户端和服务器之间传输。
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex);
export default new Vuex.Store({
plugins: [createPersistedState({
storage: window.sessionStorage,
})],
state: {
//....
}
});
用户手动注销时使用sessionStorage.clear();
。
编辑:请注意,如果您的商店具有本质上不是字符串类型的值(例如日期),您的应用程序可能会失败或行为可能会改变,因为 serialisation/deserialisation 过程会将这些值转换为字符串。
Vuex 状态保存在内存中。页面加载将清除当前状态。这就是状态不会在重新加载时持续存在的原因。
但是 vuex-persistedstate
插件解决了这个问题
npm install --save vuex-persistedstate
现在将其导入商店。
import Vue from 'vue'
import Vuex from 'vuex'
import account from './modules/account'
import createPersistedState from "vuex-persistedstate";
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
account,
},
plugins: [createPersistedState()]
});
只需一行代码即可完美运行:plugins: [createPersistedState()]
在这种情况下,最简单的方法是安装
npm install --save vuex-persistedstate
然后,将其导入到您的 vuex 文件中
从“vuex-persistedstate”导入 createPersistedState;然后,只需将其放入您的 createStore 中即可:
plugins: [createPersistedState()],
state(){
return{
isActive: false,
}
}
以下是如何使用合成 api。
npm install --save vuex-persistedstate
import createPersistedState from "vuex-persistedstate";
import { createStore } from "vuex";
export default createStore({
state: {
project_id: 1,
},
mutations: {
setProjectId(state, payload) {
state.project_id = payload;
},
},
getters: {},
actions: {},
plugins: [createPersistedState()],
});
我的应用使用 Firebase API 进行用户身份验证,将登录状态保存为 Vuex 状态中的布尔值。
当用户登录时,我设置 登录状态 并相应地有条件地显示 Login/Logout 按钮。
但是当页面刷新时,vue app的状态丢失并重置为默认值
这会导致问题,因为即使用户已登录并刷新页面,登录状态 也会设置回 false即使用户保持登录状态,也会显示登录按钮而不是注销按钮....
我应该怎么做才能防止这种行为
我可以使用 cookies 或者还有其他更好的解决方案...
-
-
这是一个已知用例。有不同的解决方案。
例如,可以使用vuex-persistedstate
。这是 vuex
用于处理和存储页面刷新之间的状态的插件。
示例代码:
import { Store } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'
const store = new Store({
// ...
plugins: [
createPersistedState({
getState: (key) => Cookies.getJSON(key),
setState: (key, state) => Cookies.set(key, state, { expires: 3, secure: true })
})
]
})
我们这里做的很简单:
- 您需要安装
js-cookie
- 在
getState
我们尝试从Cookies
加载保存的状态
- 在
setState
我们将我们的状态保存到Cookies
我已经通过每次 re-load 也获取用户数据时重置我的 headers 来解决这个问题,我不知道什么更好...
new Vue({
el: 'vue',
render: h => h(VueBox),
router,
store,
computed: {
tokenJWT () {
return this.$store.getters.tokenCheck
},
},
created() {
this.setAuth()
},
methods:
Object.assign({}, mapActions(['setUser']), {
setAuth(){
if (this.tokenJWT) {
if (this.tokenJWT === 'expired') {
this.$store.dispatch('destroyAuth')
this.$store.dispatch('openModal')
this.$store.dispatch('setElModal', 'form-login')
} else {
window.axios.defaults.headers.common = {
'Accept': 'application/json',
'Authorization': 'Bearer ' + this.tokenJWT
}
axios.get( api.domain + api.authApi )
.then(res => {
if (res.status == 200) {
this.setUser( res.data.user )
}
})
.catch( errors => {
console.log(errors)
this.destroyAuth()
})
}
}
}
})
})
我认为使用cookies/localStorage保存登录状态在某些情况下可能会导致一些错误。
Firebase 已经在 localStorage 为我们记录了登录信息,包括 expirationTime 和 refreshToken。
因此,我将使用 Vue 创建的钩子和 Firebase api 来检查登录状态。
如果令牌已过期,api 将为我们刷新令牌。
所以我们可以确保我们的应用程序中显示的登录状态等于 Firebase。
new Vue({
el: '#app',
created() {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
log('User is logined');
// update data or vuex state
} else {
log('User is not logged in.');
}
});
},
});
穿上状态:
producer: JSON.parse(localStorage.getItem('producer') || "{}")
进行突变:
localStorage.setItem("producer",JSON.stringify(state.producer)) // OR
localStorage.removeItem("producers");
对我来说很好用!
创建 VueX 状态时,使用 vuex-persistedstate 插件将其保存到会话存储中。这样,当浏览器关闭时,信息就会丢失。避免使用 cookie,因为这些值将在客户端和服务器之间传输。
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex);
export default new Vuex.Store({
plugins: [createPersistedState({
storage: window.sessionStorage,
})],
state: {
//....
}
});
用户手动注销时使用sessionStorage.clear();
。
编辑:请注意,如果您的商店具有本质上不是字符串类型的值(例如日期),您的应用程序可能会失败或行为可能会改变,因为 serialisation/deserialisation 过程会将这些值转换为字符串。
Vuex 状态保存在内存中。页面加载将清除当前状态。这就是状态不会在重新加载时持续存在的原因。
但是 vuex-persistedstate
插件解决了这个问题
npm install --save vuex-persistedstate
现在将其导入商店。
import Vue from 'vue'
import Vuex from 'vuex'
import account from './modules/account'
import createPersistedState from "vuex-persistedstate";
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
account,
},
plugins: [createPersistedState()]
});
只需一行代码即可完美运行:plugins: [createPersistedState()]
在这种情况下,最简单的方法是安装
npm install --save vuex-persistedstate
然后,将其导入到您的 vuex 文件中
从“vuex-persistedstate”导入 createPersistedState;然后,只需将其放入您的 createStore 中即可:
plugins: [createPersistedState()],
state(){
return{
isActive: false,
}
}
以下是如何使用合成 api。
npm install --save vuex-persistedstate
import createPersistedState from "vuex-persistedstate";
import { createStore } from "vuex";
export default createStore({
state: {
project_id: 1,
},
mutations: {
setProjectId(state, payload) {
state.project_id = payload;
},
},
getters: {},
actions: {},
plugins: [createPersistedState()],
});