ChatGPT解决这个技术问题 Extra ChatGPT

页面刷新时的 Vuex 状态

我的应用程序使用 Firebase API 进行用户身份验证,将登录状态保存为 Vuex 状态中的布尔值。

当用户登录时,我设置登录状态并相应地有条件地显示登录/注销按钮。

但是当页面刷新时,vue app的状态丢失并重置为默认

这会导致问题,因为即使用户登录并刷新页面,登录状态也会设置回 false 并且即使用户保持登录状态,也会显示登录按钮而不是注销按钮......

我该怎么做才能防止这种行为

我应该使用 cookie 还是可以使用任何其他更好的解决方案...

我使用任何类型的本地存储来处理它。这可以是 Cookie 或其他东西
@El_Matella 除了 cookie,您还使用什么方法在本地存储数据
一般来说,我使用本地存储 npm 包,它可以为我选择存储数据的最佳方法:npmjs.com/package/local-storage“API 是与所有 localStorage 交互的简化方式。请注意,当当前浏览器不支持 localStorage 时,回退到内存存储是透明的。”
@El_Matella 非常感谢你......我会看看

s
sobolevn

这是一个已知的用例。有不同的解决方案。

例如,可以使用 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 })
    })
  ]
})

我们在这里做的很简单:

您需要在 getState 上安装 js-cookie 我们尝试在 setState 上从 Cookies 加载保存的状态 我们将状态保存到 Cookies

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


谢谢...刚刚查看了插件的github页面...再次感谢您
您需要做任何特定的事情来设置/获取数据吗?重新加载时,我的数据被重置为默认值。只是通过 this.$store.state.user 设置,尝试过对象和简单的字符串 - 没有运气。
因为 cookie 在客户端和服务器之间传输,所以我可能会查看本地存储...
如何保存 aws-amplify 的状态?因为它太大了,无法放入 cookie 中,并且 localstorage 无法在 safari 私有模式下运行
@hounded 我也面临同样的问题,找到解决方案了吗?
J
James Westgate

创建 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();

编辑:请注意,如果您的商店具有本质上不是字符串类型的值(例如日期),您的应用程序可能会失败或行为可能会改变,因为序列化/反序列化过程会将这些值转换为字符串。


我很惊讶 cookie 解决方案获得了如此多的星星。我认为这个解决方案要好得多,因为它会在浏览器窗口关闭时自动清除所有状态。我不喜欢将我的状态数据作为 cookie 发送到服务器,我也不想在浏览器窗口关闭时保留敏感数据。
您的标头(包括 cookie)总共也被限制为 8k。
@MarkHagers,它自 IE8 起就受到原生支持!无需加载额外的代码。
我收到错误 vuex-persistedstate.es.js?0e44:1 Uncaught (in promise) TypeError: Converting circular structure to JSON
@Akin - 该错误表明您的状态中有一个循环引用,一个对象引用另一个对象,该对象最终引用回第一个对象。
R
Rijo

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()]


使用 vuex 创建存储: const store = createStore({ /*...*/ plugins: [createPersistedState()], });
这是最简单的方法,无需添加其他包。有用!
效果很好!默认情况下,状态保存到 vuex 键下的 localStorage
非常容易集成。
L
Leonardo Filipe

装上状态:

producer: JSON.parse(localStorage.getItem('producer') || "{}")

进行突变:

localStorage.setItem("producer",JSON.stringify(state.producer)) // OR
localStorage.removeItem("producers");

对我来说很好!


很好的答案认为它不需要额外的库并且不再支持持久状态
不错,但我认为 localStorage.removeItem("producer"); 应该在 localStorage.setItem("producer",JSON.stringify(state.producer)) 之前
A
Andrew - oahehc

我认为在某些情况下使用 cookies/localStorage 保存登录状态可能会导致一些错误。 Firebase 已经为我们在 localStorage 记录了登录信息,包括 expireTime 和 refreshToken。因此,我将使用 Vue 创建的钩子和 Firebase api 来检查登录状态。如果token过期了,api会为我们刷新token。所以我们可以确保我们的应用程序中的登录状态显示等于 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.');
            }
        });
    },
});

针对这种情况的最佳、官方和推荐方法
A
Alenn G'Kar

我已经通过每次重新加载时重置我的标题来解决这个问题,还获取用户数据,我不知道什么更好......

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()
                            })
                    }
                }
            }
        })

})

S
Spudneck Dan

以下是使用组合 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()],
});

U
Ulugbek Mannopov

在这种情况下,最简单的方法是安装 npm install --save vuex-persistedstate 然后,将其导入您的 vuex 文件 import createPersistedState from "vuex-persistedstate";然后,只需将其放入您的 createStore 中,如下所示:

plugins: [createPersistedState()],
    state(){
        return{
            isActive: false,
        }
    }