页面刷新时的 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 })
    })
  ]
})

我们这里做的很简单:

  1. 您需要安装js-cookie
  2. getState 我们尝试从 Cookies
  3. 加载保存的状态
  4. setState 我们将我们的状态保存到 Cookies

文档和安装说明:https://www.npmjs.com/package/vuex-persistedstate

我已经通过每次 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()],
});