zoukankan      html  css  js  c++  java
  • 用混入的方法引入vuex,并且解决vuex刷新页面值丢失的问题

    前段时间,做了个官网项目,客户要求将首页的域名后面的参数去除干净,然后就把#去掉了,一转脸,客户让去掉子页面地址栏上的参数,这很棘手,因为子页面的内容是根据子页面地址栏上的参数而定的,如果要去掉这些参数,怎么在跳转页面时也可以拿到上一个页面所存的变量呢?于是,想起了vuex,但是vuex有一个问题是,一旦刷新页面,vuex中的值会丢失,那怎么解决呢?就是在存变量值的同时在session中也存一份数据,在取变量值时,如果刷新了页面,变量值肯定就不存在了,这时我么你可以判断vuex中的变量是否有值,若果有值就直接取,如果没值,就从sessionStorage中拿,(需要注意的时,在最初,一定是存值在先,取值在后,否者,还没存,先取了,肯定取到个null值)。解决了vuex值刷新页面丢失问题后,又想,每次引入vuex,设置什么computed,methods什么的,很麻烦,如果是很多页面都会用到vuex中的某几个变量,在每个页面都引入vuex,再设置computed,methods等,显得很繁琐,于是想起了mixins,vue中的一种混入机制。下面来看看具体的代码:

    store.js

    黄色背景的代码解决了vuex刷新页面值丢失的问题

    import Vue from "vue";
    import Vuex from "vuex";
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      state: {//声明变量
        val:"",//变量
      },
      getters:{//获取值
        getVal(state){
          if(state.val){
            return state.val;
          }else{
            return sessionStorage.getItem("val")
          }
        }
      },
      mutations: {//值如何变化
        setVal(state,value){
          state.val=value;
          sessionStorage.setItem("val",value);//在session中存一下
        }
      },
      actions: {//异步执行   可以按顺序调用多个mutations的方法
        asyncSetVal({commit,state},value){
          commit("setVal",value);
        }
      }
    });

    下面,看看如何使用混入(在src目录下建立mixins/mixinVuex.js)

     mixinVuex.js(混入的代码会比父页面先执行)

    import {mapGetters,mapActions} from "vuex"
    
    
    
    export default {
        computed:{
            ...mapGetters([
                'getVal'//获取到state.val数据。
            ])
        },
        watch:{
    
        },
        data() {
            return {
                mixinName: 'mixin'
            }
        },
        created() {
            
        },
        mounted() {
    
        },
        methods: {
            ...mapActions([
                "asyncSetVal"
            ]),
        }
    }

    接下来看看如何把mixinVuex.js混入到某个页面

    <template>
        <div class="homeBox">
            //...
            
        </div>
    </template>
    
    <script>
    import mixinVuex from '@/mixins/mixinVuex.js'; // 引入mixin文件
    export default {
        name: "home",
        mixins:[mixinVuex],
        data(){
            return{}
        },
        methods: {
            homeInit(lang){//初始化
                var self=this;
            },
            toChildPage(){
                this.asyncSetVal("变量");
                this.$router.push({name:"childPage"});
            },
            toChildPage2(){
                this.asyncSetVal("变量2");
                this.$router.push({name:"childPage"});
            }
        }
    };
    </script>
    
    <style scoped>
        .homeBox{
    
        }
    </style>

    ok  结束

     另一种解决 vuex刷新后store中值丢失问题:

    另一种方法:

    vue store的值刷新就被覆盖解决方案

     

    《转》最近在用vue写pc端项目,用vuex来做全局的状态管理, 发现当刷新网页后,保存在vuex实例store里的数据会丢失。

    1. 产生原因
    2. 解决思路
    3. 解决过程
    1. 产生原因
    其实很简单,因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值。

    2. 解决思路
    一种是state里的数据全部是通过请求来触发action或mutation来改变

    一种是将state里的数据保存一份到本地存储(localStorage、sessionStorage、cookie)中

    很显然,第一种方案基本不可行,除非项目很小或者vuex存储的数据很少。而第二种可以保证刷新页面数据不丢失且易于读取。

    3. 解决过程
    首先得选择合适的客户端存储

    localStorage是永久存储在本地,除非你主动去删除;

    sessionStorage是存储到当前页面关闭为止;

    cookie则根据你设置的有效时间来存储,但缺点是不能储存大数据且不易读取。

    我选择的是sessionStorage,选择的原因vue是单页面应用,操作都是在一个页面跳转路由,另一个原因是sessionStorage可以保证打开页面时sessionStorage的数据为空,而如果是localStorage则会读取上一次打开页面的数据。

    然后是怎么用sessionStorage来保存state里的数据。

    第一种方案

    由于state里的数据是响应式,所以sessionStorage存储也要跟随变化。又由于vuex规定所有state里数据必须通过mutation方法来修改,所以第一种方案就是mutation修改state的同时修改sessionStorage对应存储的属性

    第二种方案

    第一种方案确实可以解决问题,但这种方法很明显让人觉得怪异,都这样了,那不如直接用sessionStorage来做状态管理。

    那怎么才能不用每次修改state时同时也要修改sessionStorage呢?这时我们可以换一个思路,因为我们是只有在刷新页面时才会丢失state里的数据,那有没有办法在点击页面刷新时先将state数据保存到sessionStorage,然后才真正刷新页面?

    当然有,beforeunload这个事件在页面刷新时先触发的。那这个事件应该在哪里触发呢?我们总不能每个页面都监听这个事件,所以我选择放在app.vue这个入口组件中,这样就可以保证每次刷新页面都可以触发。

    具体的代码如下:

    复制代码
     1 export default {
     2 name: 'App',
     3 created () {
     4 //在页面加载时读取sessionStorage里的状态信息
     5 if (sessionStorage.getItem("store") ) {
     6 this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
     7 }
     8 
     9 //在页面刷新时将vuex里的信息保存到sessionStorage里
    10 window.addEventListener("beforeunload",()=>{
    11 sessionStorage.setItem("store",JSON.stringify(this.$store.state))
    12 })
    13 }
    14 }
    复制代码

    自己项目中用到的,亲测可用:

    new Vue({
      router,
      store,
      render: h => h(App),
      created() {
        if (localStorage.getItem("meetingManagerStore") ) {
          console.log("页面加载时,将本地存储中的值存到stroe中")
          this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(localStorage.getItem("meetingManagerStore"))))
        };
        window.addEventListener("beforeunload",()=>{
          console.log("页面刷新前,将vuex中的所有值存到localStorage中")
          localStorage.setItem("meetingManagerStore",JSON.stringify(this.$store.state))
        })
      },
    }).$mount("#app");

    这样做过后,就相当于vuex的值刷新页面时就永远不会丢失了,灰常好用

  • 相关阅读:
    原子核结构壳模型:粒子空穴转换
    第十二周学习总结
    构建之法读书笔记5
    5.21学习总结——android开发实现用户头像的上传
    5.20团队活动
    构建之法读书笔记4
    团队项目第一阶段验收
    HTML+CSS设计个人主页
    C++文件流
    面向对象程序设计_虚函数的应用
  • 原文地址:https://www.cnblogs.com/fqh123/p/11950447.html
Copyright © 2011-2022 走看看