• Vue 使用History记录上一页面的数据


    UI

    ![](https://img2018.cnblogs.com/blog/1504257/201811/1504257-20181102140311509-821423154.jpg) ![](https://img2018.cnblogs.com/blog/1504257/201811/1504257-20181102140318832-1421357415.jpg)

    需求

    1. 从列表页的第二页进入详情页,返回时列表页仍然显示在第二页;
    2. 从列表页的第二页进入详情页,返回时列表页的筛选条件仍然存在。

    <!--more-->

    技术选择

    1. 使用vue-router组件,通过this.$router.push({path: path, query: query});方式,将页码选择条件作为参数存储在url中,这种方式在上面的UI设计中是可行的,但是当列表页中包含tab组件时(分页组件是公用的),会因为push的因素(因为push会打开新页面)导致一些问题(PS:也可能是本人技术能力的原因),未实现。
    2. 使用History API(HTML5开始支持),通过history.replaceState方式,将页码作为参数存储在url中,将选择条件存储在history中(尚不清楚数据具体是存储在哪里);通过location.hash方式获取页码;通过history.state方式获取存储的选择条件。

    具体实现--技术选择2

    开关

    为分页组件添加一个开关(openroute),因为需要灰度上线,万一有问题,要调整的页面也只有一个。代码如下:

    &lt;script&gt;
      export default {
        props: {
          openroute: {
            type: Boolean,
            default: () =&gt; (true)
          }
        },
      }
    &lt;/script&gt;
    

    分页组件中存储页码选择条件&获取页码

    &lt;script&gt;
      export default {
        methods: {
          fetchData(page) {
              //请求参数
            let params = this.params;
            //请求页码
            let newPage;
            //openroute处理
            if (this.openroute) {
              //为url添上#page
              if (page) {
                history.replaceState(params.data, document.title, "#" + page);
              } else {
                if (history.state) {
                  if (!history.state.key &amp;&amp; location.hash &amp;&amp; location.hash.split("#") &amp;&amp; location.hash.split("#")[1]) {
                    if (JSON.stringify(history.state) !== JSON.stringify(params.data)) { //选择条件变更则请求第一页
                      history.replaceState(params.data, document.title, "#1");
                    } else {
                      history.replaceState(params.data, document.title, "#" + location.hash.split("#")[1]);
                    }
                  } else {
                    history.replaceState(params.data, document.title, "#1");
                  }
                } else {
                  if (location.hash &amp;&amp; location.hash.split("#") &amp;&amp; location.hash.split("#")[1]) {
                    history.replaceState(params.data, document.title, "#" + location.hash.split("#")[1]);
                  } else {
                    history.replaceState(params.data, document.title, "#1");
                  }
                }
              }
              //获取url后面的#page
              if (location.hash &amp;&amp; location.hash.split("#") &amp;&amp; location.hash.split("#")[1]) {
                newPage = Number(location.hash.split("#")[1]);
              } else {
                newPage = 1;
              }
            } else {
              newPage = page;
            }
            //请求数据,获得结果,传递给列表页面
          }
        }
      }
    &lt;/script&gt;
    

    列表页面获取选择条件

    目前可能是因为框架设计的问题,没法在请求数据之前通过Object.assign方式为替换初始变量,所以先这样处理(笨方法,各位大佬有解决办法麻烦指导下,谢谢):

    &lt;script&gt;
      export default {
        data() {
          return {
            form: {
              aaa: (history.state &amp;&amp; history.state.aaa) ? history.state.aaa : null,
              bbb: (history.state &amp;&amp; history.state.bbb) ? history.state.bbb : null,
              ccc: (history.state &amp;&amp; history.state.ccc) ? history.state.ccc : null
            },
          };
        }
      };
    &lt;/script&gt;
    

    已解决,初始变量不需要动,可以通过以下方式实现:

    created(){
      //获取缓存的数据
      if (history.state) {
        Object.assign(this.form, history.state)
        if (this.form.key) {
          delete this.form.key
        }
      }
    },
    

    这里记录下:之前以为created方法是在分页组件的watch监听之后执行的,后来发现被误导了(因为之前是通过Object.assign(true, this.form, history.state)方式实现数据赋值的,但是并没有成功)。下面做个小总结:

    Object.assign(true, a, b);”和“Object.assign(a, b);”有什么区别?

    结论:前者:改a不影响b;后者:改a影响b

    分析(这篇文章有源码分析(<font color='red'>求解答:WebStorm中如何关联源码?</font>),很棒):https://www.cnblogs.com/libin...

    FAQ

    • 需要使用history.replaceState方式是因为:它不会将更改后的url压到history栈中,所以不会增加回退和前进的操作步数;
    • 使用history.replaceState方式,可存储的state大小不能操作640k;
    • 可能存在浏览器兼容性问题,请从此处查阅:https://caniuse.com/#feat=his...

    Demo Or Source

    因为是公司项目,所以目前没有Demo或源码

    参考文章

    原文地址:https://segmentfault.com/a/1190000016876337
  • 相关阅读:
    Redhat7 安装 yum源(亲测有效)
    Win10开启FTP与配置(完整无错版)
    DataStage中Transformer的函数大全
    缺省值是什么
    扫描线
    2021.07.02笔记-DP
    2021.07.02-2膜你赛
    2021.07.01膜你赛
    2021.06.21模拟赛
    2021.06.09模拟赛
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9895911.html
Copyright © 2020-2023  润新知