페이지 새로 고침시 Vuex 상태


106

내 앱은 사용자 인증에 Firebase API를 사용하여 로그인 상태를 Vuex 상태에 부울 값으로 저장합니다.

사용자가 로그인 하면 로그인 상태를 설정하고 그에 따라 로그인 / 로그 아웃 버튼을 조건부로 표시합니다.

그러나 페이지를 새로 고치면 vue 앱의 상태가 손실되고 기본값으로 재설정됩니다.

사용자가 로그인하고 페이지를 새로 고쳐도 로그인 상태 가 다시 거짓으로 설정 되고 사용자가 로그인 상태를 유지하더라도 로그 아웃 버튼 대신 로그인 버튼이 표시되므로 문제가 발생합니다 ....

이 동작을 방지하려면 어떻게해야합니까?

쿠키를 사용할까요 아니면 다른 더 나은 솔루션을 사용할 수 있습니까?

    -

2
나는 그것을 처리하기 위해 모든 종류의 로컬 저장소를 사용합니다. 즉 쿠키 또는 뭔가 다른 일 수있다
Hammerbot

떨어져 로컬 데이터를 저장하는 데 사용합니까 다른 어떤 방법 쿠키 @El_Matella
boomboxboy

1
일반적으로 데이터를 저장하는 가장 좋은 방법을 선택할 수있는 로컬 스토리지 npm 패키지를 사용합니다. npmjs.com/package/local-storage "API는 모든 localStorage와 상호 작용하는 간단한 방법입니다. localStorage가 현재 브라우저에서 지원되지 않는 경우 인 메모리 저장소로의 대체가 투명하게 사용됩니다. "
Hammerbot 2017 년

@El_Matella은 대단히 감사합니다 ... 내가 좀해야합니다
boomboxboy

답변:


109

이것은 알려진 사용 사례입니다. 다른 해결책이 있습니다.

예를 들어 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의 페이지에서보기를 가졌다 감사
boomboxboy을

8
데이터를 설정 / 얻기 위해 특정 작업을 수행해야합니까? 다시로드하면 내 데이터가 기본값으로 재설정됩니다. this. $ store.state.user, 시도 된 객체 및 간단한 문자열을 통해 설정하기 만하면됩니다.
DogCoffee

6
쿠키는 클라이언트와 서버간에 전송되기 때문에 아마 ... 대신 로컬 스토리지에 보일 것이다
제임스 웨스트 게이트

aws-amplify의 상태를 저장하려면 어떻게해야합니까? 이 큰에 그대로 쿠키에 맞게하고 로컬 스토리지 것이다 사파리 전용 모드에없는 작업
hounded

@hounded 나도 같은 문제에 직면하고 있는데 이것에 대한 해결책을 찾았습니까?
Adil

54

VueX 상태를 만들 때 vuex-persistedstate 플러그인을 사용하여 세션 저장소에 저장하십시오 . 이런 식으로 브라우저를 닫으면 정보가 손실됩니다. 이러한 값은 클라이언트와 서버간에 이동하므로 쿠키 사용을 피하십시오.

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
쿠키 솔루션에 별이 너무 많아서 놀랐습니다. 브라우저 창을 닫을 때 모든 상태를 자동으로 지우므로이 솔루션이 훨씬 낫다고 생각합니다. 상태 데이터를 쿠키로 서버에 보내는 것을 좋아하지 않으며 브라우저 창이 닫힐 때 중요한 데이터를 유지하고 싶지도 않습니다.
Mark Hagers

또한 쿠키를 포함한 헤더의 총 개수는 8K로 제한됩니다.
James Westgate

2
@MarkHagers이며 IE8부터 기본적으로 지원됩니다! 추가 코드를로드 할 필요가 없습니다.
Fabian von Ellerts

1
오류가 발생했습니다 vuex-persistedstate.es.js?0e44:1 Uncaught (in promise) TypeError: Converting circular structure to JSON
Akin Hwan

1
@Akin-이 오류는 상태에 순환 참조가 있음을 나타내며 객체는 결국 첫 번째 객체를 다시 참조하는 다른 객체를 참조합니다.
James Westgate

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

쿠키 / localStorage를 사용하여 로그인 상태를 저장하면 상황에 따라 오류가 발생할 수 있다고 생각합니다.
Firebase는 이미 우리를 위해 localStorage에 로그인 정보를 기록하여 만료 시간 및 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()
                            })
                    }
                }
            }
        })

})
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.