4

Vuex结合sessionStorage存储公用的用户信息

前言

在一个系统中,我们经常会用到用户的用户名、用户手机号、用户ID等信息,可以将它们用于展示在系统中或者根据ID获取权限之类。

因为各个页面都需要这些公用信息,当然是存储在store的状态字中,登录之后就请求远程数据,赋值啦。

但是由于Vue是响应式的,我们存储在store中的状态字一旦刷新或者关闭窗口,网页都会初始化,重置,所以得想个方法动态更新store数据。

问题一:每次刷新页面store中数据都会重置

方法一:

我们需要知道,每次刷新加载一次页面,都会加载一次入口html文件(一般都是App.vue文件,页面间跳转是不会重新加载滴)。
所以可以将获取信息的接口的方法(GetPcMallInfo)放在App.vue中,一刷新就去请求一次接口,重新赋值store中的数据

<template>
    <div id="app">
        <router-view />
    </div>
</template>
<script>
    export default {
        name: 'App',
        created() {
            this.$store.dispatch('GetPcMallInfo', {}).then(() => {}).catch((e) => {})
        }
    }
</script>

缺点:远程请求数据,如果网络延迟,那么store中的数据更新也会出现延迟的情况,那么展示在页面中的用户名之类的数据也会延迟渲染,非常影响客户体验;如果数据量过大,频繁的请求数据也是一种性能损耗。

方法二:

  1. 首先,当然是在登录之后,先请求接口,把公用数据存储在store中,
  2. 其次,在页面刷之新,将store数据存储在sessionStorage中。
    当然还是是还是写在入口html,App.vue文件中啦。

    window.addEventListener('beforeunload', () => {
        sessionStorage.setItem('store', JSON.stringify(this.$store.state))
    })
  3. 最后,刷新后,将sessionStorage中的值赋值给store。由于sessionStorage是本地存储,不需要远程请求,就不会出现延迟的情况啦。

    if (sessionStorage.getItem('store')) {
        this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store'))))
    }

问题二:使用方法二时,关闭窗口,sessionStorage会被清空

这时,虽然关闭了窗口,但是没有关闭浏览器,重新打开网页,还是处于登录状态,但是sessionStorage会清空,那么store中的状态也没了。

这里也有两个方法解决:

  1. 不用sessionStorage存储store的值,用localStorage。关闭当前窗口或浏览器可不会清空localStorage。但是,每次打开网页会保留上一次登录的公共信息。比如上一次是用户A登录,用户B能在localStorage中看到用户A的信息。
  2. 如果有登录信息,但是sessionStorage的值是空的,重新请求GetPcMallInfo方法一次呗。还想什么呢!

终极版

  1. localStorage

    <template>
        <div id="app">
            <router-view />
        </div>
    </template>
    <script>
        // 入口组件
        export default {
            name: 'App',
            created() {
                if (window.localStorage.getItem('store')) {
                    this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(window.localStorage.getItem('store'))))
                }
                window.addEventListener('beforeunload', () => {
                    window.localStorage.setItem('store', JSON.stringify(this.$store.state))
                })
            },
        }
    </script>
  2. 重新请求

    <template>
        <div id="app">
            <router-view />
        </div>
    </template>
    <script>
    import {getToken} from '@/utils/auth' 
        // 入口组件
        export default {
            name: 'App',
            created() {
    
                if (sessionStorage.getItem('store')) {
                    this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store'))))
                }
                window.addEventListener('beforeunload', () => {
                    sessionStorage.setItem('store', JSON.stringify(this.$store.state))
                })
                
                if(this.$store.getters.MallName==''&&getToken()){
                    this.$store.dispatch('GetPcMallInfo', {}).then(() => {}).catch((e) => {})
                }
            },
        }
    </script>

问题三:关闭浏览器了,怎么办

这。。。。。。。不要问

今天的你学废了么

北冥有锅
9 声望1 粉丝