Состояние Vuex на странице обновления

Мое приложение использует API Firebase для аутентификации пользователей, сохраняя статус входа в качестве логического значения в состоянии Vuex.

Когда пользователь входит в систему, я устанавливаю статус входа и условно отображаю кнопку входа/выхода из системы.

Но когда страница обновляется, состояние приложения vue теряется и восстанавливается по умолчанию.

Это вызывает проблему, так как даже когда пользователь вошел в систему и страница обновилась, статус входа возвращается к false, и кнопка входа в систему отображается вместо кнопки выхода из системы, даже если пользователь остается вошедшим в систему....

Что мне делать, чтобы предотвратить это поведение?

Должен ли я использовать файлы cookie или любое другое лучшее решение доступно...

  • -

Ответ 1

Это известная практика. Существуют разные решения.

Например, можно использовать 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. на setState мы сохраняем наше состояние в Cookies

Документы и инструкции по установке: https://www.npmjs.com/package/vuex-persistedstate

Ответ 2

Я думаю, что использование cookie/localStorage для сохранения статуса входа может привести к некоторой ошибке в некоторой ситуации.
Firebase уже записывает информацию для входа в localStorage для нас, включая expirationTime и refreshToken.
Поэтому я буду использовать созданный вами Vue hook и 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.');
            }
        });
    },
});

Ответ 3

Я решил это, сбросив свои заголовки каждый раз, когда я снова загружаю и извлекаю пользовательские данные, я не знаю, что лучше...

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

})

Ответ 4

состояние: производитель: JSON.parse(localStorage.getItem('производитель') || "{}")

мутации: localStorage.setItem("производитель", JSON.stringify(state.producer))

отлично работает для меня!