Trạng thái Vuex khi làm mới trang


106

Ứng dụng của tôi sử dụng API Firebase để Xác thực người dùng, lưu trạng thái Đăng nhập dưới dạng giá trị boolean trong Trạng thái Vuex.

Khi người dùng đăng nhập, tôi đặt trạng thái đăng nhập và có điều kiện hiển thị nút Đăng nhập / Đăng xuất tương ứng.

Nhưng khi trang được làm mới, trạng thái của ứng dụng vue sẽ bị mất và được đặt lại về mặc định

Điều này gây ra sự cố vì ngay cả khi người dùng đã đăng nhập và trang được làm mới, trạng thái đăng nhập được đặt lại thành false và nút đăng nhập được hiển thị thay vì nút đăng xuất mặc dù người dùng vẫn đăng nhập ....

Tôi phải làm gì để ngăn chặn hành vi này

Tôi sẽ sử dụng cookie Hoặc bất kỳ giải pháp nào khác tốt hơn có sẵn ...

    -

2
Tôi sử dụng bất kỳ loại lưu trữ cục bộ nào để xử lý điều đó. Đó có thể là Cookies hay cái gì khác
Hammerbot

@El_Matella ngoài cookie gì phương pháp khác để bạn sử dụng để lưu trữ dữ liệu tại địa phương
boomboxboy

1
Nói chung, tôi sử dụng gói npm lưu trữ cục bộ có thể chọn phương pháp tốt nhất để lưu trữ dữ liệu cho tôi: npmjs.com/package/local-storage "API là một cách đơn giản để tương tác với tất cả mọi thứ localStorage. Lưu ý rằng khi localStorage thì không được hỗ trợ trong trình duyệt hiện tại, dự phòng cho kho lưu trữ trong bộ nhớ được sử dụng một cách minh bạch. "
Hammerbot

@El_Matella thank you very much ... Tôi sẽ có một cái nhìn
boomboxboy

Câu trả lời:


109

Đây là một trường hợp sử dụng đã biết. Có nhiều giải pháp khác nhau.

Ví dụ, người ta có thể sử dụng vuex-persistedstate. Đây là một plugin vuexđể xử lý và lưu trữ trạng thái giữa các lần làm mới trang.

Mã mẫu:

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

Những gì chúng tôi làm ở đây rất đơn giản:

  1. bạn cần cài đặt js-cookie
  2. trên getStatechúng tôi cố gắng tải trạng thái đã lưu từCookies
  3. trên setStatechúng tôi lưu trạng thái của chúng tôi đểCookies

Tài liệu và hướng dẫn cài đặt: https://www.npmjs.com/package/vuex-persistedstate


Cảm ơn bạn ... Được chỉ có nhìn vào trang github của plugin ... Cảm ơn bạn một lần nữa
boomboxboy

8
Bạn có cần làm bất cứ điều gì cụ thể để thiết lập / lấy dữ liệu không? Khi tải lại, dữ liệu của tôi được đặt lại về mặc định. Chỉ cần thiết lập thông qua. $ Store.state.user, đã thử các đối tượng và chuỗi đơn giản - không may mắn.
DogCoffee

6
Bởi vì các tập tin cookie được truyền giữa máy khách và máy chủ tôi có lẽ sẽ nhìn vào lưu trữ địa phương thay vì ...
James Westgate

làm cách nào để lưu trạng thái aws-ampli? vì nó khá lớn để vừa với cookie và lưu trữ cục bộ sẽ không hoạt động ở chế độ riêng tư safari
hounded

@hounded Tôi cũng đang phải đối mặt với vấn đề tương tự, tìm thấy bất kỳ giải pháp nào cho điều này?
Adil

54

Khi tạo trạng thái VueX của bạn, hãy lưu nó vào bộ nhớ phiên bằng cách sử dụng plugin vuex-persistedstate . Bằng cách này, thông tin sẽ bị mất khi đóng trình duyệt. Tránh sử dụng cookie vì những giá trị này sẽ di chuyển giữa máy khách và máy chủ.

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: {
        //....
    }
});

Sử dụng sessionStorage.clear();khi người dùng đăng xuất theo cách thủ công.


13
Tôi ngạc nhiên rằng giải pháp cookie lại được nhiều sao như vậy. Tôi nghĩ giải pháp này tốt hơn nhiều vì nó tự động xóa tất cả trạng thái khi cửa sổ trình duyệt đóng. Tôi không thích gửi dữ liệu trạng thái của mình dưới dạng cookie đến máy chủ và tôi cũng không muốn lưu giữ dữ liệu nhạy cảm khi cửa sổ trình duyệt đóng lại.
Mark Hager

Bạn cũng bị giới hạn tổng cộng 8k với các tiêu đề của bạn bao gồm cookie.
James Westgate

2
@MarkHagers và nó được hỗ trợ từ IE8! Không cần phải tải thêm mã.
Fabian von Ellerts

1
Tôi gặp lỗi vuex-persistedstate.es.js?0e44:1 Uncaught (in promise) TypeError: Converting circular structure to JSON
Akin Hwan

1
@Akin - Lỗi cho thấy bạn có một tham chiếu vòng tròn trong trạng thái của mình, một đối tượng tham chiếu đến một đối tượng khác mà cuối cùng tham chiếu trở lại đối tượng đầu tiên.
James Westgate

11

Trạng thái Vuex được giữ trong bộ nhớ. Tải trang sẽ xóa trạng thái hiện tại này. Đây là lý do tại sao trạng thái không tiếp tục tải lại.

Nhưng vuex-persistedstateplugin giải quyết vấn đề này

npm install --save vuex-persistedstate

Bây giờ nhập cái này vào cửa hàng.

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

Nó hoạt động hoàn hảo với một dòng mã: plugins: [createPersistedState()]


10

Tôi nghĩ rằng việc sử dụng cookie / localStorage để lưu trạng thái đăng nhập có thể gây ra lỗi trong một số trường hợp.
Firebase đã ghi lại thông tin đăng nhập tại localStorage cho chúng tôi bao gồm expirationTime và refreshToken.
Do đó, tôi sẽ sử dụng Vue tạo hook và Firebase api để kiểm tra trạng thái đăng nhập.
Nếu mã thông báo đã hết hạn, api sẽ làm mới mã thông báo cho chúng tôi.
Vì vậy, chúng tôi có thể đảm bảo hiển thị trạng thái đăng nhập trong ứng dụng của chúng tôi bằng 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.');
            }
        });
    },
});

cách tiếp cận tốt nhất, chính thức và được khuyến nghị chống lại tình huống này
alijunior

8

đưa vào trạng thái:

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

đưa vào các đột biến:

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

hoạt động tốt cho tôi!


1

Tôi đã giải quyết vấn đề này bằng cách đặt lại tiêu đề của mình mỗi khi tải lại cũng tìm nạp dữ liệu người dùng, tôi không biết cách nào tốt hơn ...

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

})
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.