Стан Vuex при оновленні сторінки


105

У моїй програмі використовується Firebase API для автентифікації користувачів, зберігаючи статус входу як логічне значення у стані Vuex.

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

Але коли сторінку оновлено, стан програми vue втрачається та скидається до типового

Це спричиняє проблему, оскільки навіть коли користувач входить у систему та сторінка оновлюється, статус входу повертається у значення false, а кнопка входу відображається замість кнопки виходу, навіть якщо користувач залишається авторизованим ....

Що я повинен робити, щоб запобігти цій поведінці

Чи повинен я використовувати файли cookie або будь-яке інше краще рішення ...

    -

2
Я використовую будь-яку локальну пам’ять для обробки цього. Це може бути Cookies або щось інше
Hammerbot

@El_Matella, окрім файлів cookie, який ще метод ви використовуєте для локального зберігання даних
boomboxboy

1
Взагалі, я використовую локальний пакет зберігання npm, який може вибрати для мене найкращий спосіб зберігання даних: npmjs.com/package/local-storage "API - це спрощений спосіб взаємодії з усіма речами localStorage. Зверніть увагу, що коли localStorage є не підтримується в поточному браузері, повернення до сховища в пам'яті використовується прозоро. "
Hammerbot

@El_Matella велике спасибі ... Я подивлюсь
boomboxboy

Відповіді:


108

Це відомий варіант використання. Є різні рішення.

Наприклад, можна використовувати 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


Дякую ... Просто подивився сторінку плагіна на github ... Ще раз
дякую

8
Чи потрібно робити щось конкретне для встановлення / отримання даних? При перезавантаженні мої дані скидаються за замовчуванням. Просто налаштування через цей. $ Store.state.user, випробувані об’єкти та прості рядки - не везе.
DogCoffee

6
Оскільки файли cookie передаються між клієнтом та сервером, я б, напевно, переглянув місцеве сховище ...
Джеймс Вестгейт,

як зберегти стан aws-amplify? оскільки це велике вміщення в файлах cookie, а місцеве зберігання не працюватиме в приватному режимі сафарі
переслідували

@hounded Я також стикаюся з такою ж проблемою, знайшов якесь рішення для цього?
Аділ

54

Створюючи свій стан VueX, збережіть його у сховищі сеансів за допомогою плагіна vuex-persistentstate . Таким чином, інформація буде втрачена при закритті браузера. Уникайте використання файлів 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();коли користувач виходить із системи вручну.


13
Я здивований, що рішення для файлів cookie отримує стільки зірок. Я думаю, що це рішення набагато краще, оскільки воно автоматично очищає весь стан, коли вікно браузера закрито. Мені не подобається надсилати свої дані про стан файлів cookie на сервер, і я також не хочу зберігати конфіденційні дані, коли вікно браузера закривається.
Mark Hagers

Ви також можете обмежити до 8 тис. Загалом із вашими заголовками, включаючи файли cookie.
Джеймс Вестгейт,

2
@MarkHagers, і він підтримується з IE8! Не потрібно завантажувати додатковий код.
Фабіан фон Еллерц,

1
Я отримував помилку vuex-persistedstate.es.js?0e44:1 Uncaught (in promise) TypeError: Converting circular structure to JSON
Акін Хван,

1
@Akin - Помилка припускає, що у вас є кругова посилання у вашому стані, об’єкт посилається на інший об’єкт, який з часом посилається на перший об’єкт.
Джеймс Вестгейт,

11

Стан 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()]


10

Я думаю, що використання 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.');
            }
        });
    },
});

найкращий, офіційний та рекомендований підхід проти цієї ситуації
alijunior

8

надіти державу:

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

покласти на мутації:

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

у мене чудово працює!


1

Я вирішив це, скидаючи заголовки кожного разу, коли я перезавантажую також отримую дані користувача, я не знаю, що краще ...

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

})
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.