Vue2路由守卫:解决路由传参页面刷新后参数消失的问题

需求

在应用中,经常出现需要点击某个按钮实现新建表单或编辑表单的场景,表单打开时需要从原页面获取一定的参数对表单数据进行初始化。这里就涉及到

1)新建表单,跳转至新页面(点击的表单不同,打开的页面不同)   -> 动态路由

2)从跳转前的页面向新页面传递参数   -> 路由中的参数传递

动态路由

在Vue中,动态路由是指根据特定的路径参数来动态加载路由组件。通过使用动态路由,我们可以根据不同的路径参数加载不同的组件,实现页面的动态切换。

路由中的两种传参方式及其利弊

路由传参可分为query传参和params传参

(1)、query传参

缺点:参数会在地址栏中显示

优点:刷新数据不会丢失

this.$router.push({path: '/path/newpath', query: {
          id: this.form.id, 
          param1:this.form.param1, 
          param1:this.form.param12
        }});

(2)、params传参

优点:参数不会显示在地址栏中

缺点:

  • 仅第一次点击跳转,页面打开状态下,再次点击,因未检查到路由变化(URL变化),不会再次打开页面,如需要每次点击新建都要打开一个新建页面,则无法实现;
  • 刷新时数据会丢失;
this.$router.push({name: 'form.formDetails',    //需要先在路由中为该路由定义name          
          params: {
            id: this.form.unid,     //更多的参数放在params中传递,不会出现在URL中
            param1: this.param1,
            param2: this.param2
          }
        });

解决params传参的两个问题

1、重复点击页面不跳转问题

结合第一种传参方式,可以将唯一标识id放在路径中,实现每次新建都打开一个新页面的需求,如下:(但是如果是编辑需求,因为每次点击表单的id是一样的,仍然不能再另一个窗口中重新打开,甚至都无法跳转到指定表单窗口中,等解决了再来更新

this.$router.push({name: 'form.formDetails',    //需要先在路由中为该路由定义name
          query: {
            id: this.form.unid     //将唯一标识id放在路径中,实现每次点击不同表单时都能使路由发生变化,进而跳转(否则未监测到路由变化,页面不会发生跳转)          
          },
          params: {
            id: this.form.unid,     //更多的参数放在params中传递,不会出现在URL中
            param1: this.param1,
            param2: this.param2
          }
        });

2、解决刷新后参数丢失问题

使用路由守卫来确保参数在页面刷新时不会丢失。关于路由守卫,有一个非常好的博客可以参考:一文带你掌握Vue中的路由守卫_vue.js_脚本之家

我这里仅写我自己的实现,因为只是有限几个表单页面需要解决传参问题,所以我使用了组件内守卫,基本思路:

1、表单页面中,beforeRouteEnter中将接收到的params中的参数保存在全局变量sessionStorage中(注意:此时还没有加载data等,不能使用this)

beforeRouteEnter(to, from, next){ 
    if (to.params.id) {
      // 将参数存储在sessionStorage中,使用唯一标识id作为Key
      sessionStorage.setItem(to.params.id, JSON.stringify(to.params));
    }    

    next();
  },

2、在data中接收sessionStorage中保存的参数:

注意,这里获取参数的id从query中获取,不能从params中取,否则刷新后params丢失,拿不到

data() {
    return {
       //注意,这里获取参数的id从query中获取,不能从params中取,否则刷新后params丢失,拿不到
      routeLinkparams:JSON.parse(sessionStorage.getItem(this.$route.query.id)),
      ....
}

3、在created中,根据需要逐一解析出来

created() {
    console.log("routeLinkparams.param1",this.routeLinkparams.param1);
  },

4、页面关闭前,清理sessionStorage

beforeDestroy() {
    // 清理sessionStorage中的数据
    sessionStorage.removeItem(this.$route.query.id);
    console.log(sessionStorage)
  }

sessionstorage和localstorage区别

sessionStorage和localStorage的主要区别在于它们的生命周期、存储数据的持久性、以及它们的应用场景。

生命周期和存储持久性

sessionStorage:数据仅在当前浏览器窗口或标签页的生命周期内存在。当窗口或标签页关闭时,sessionStorage中的数据就会被清除。因此,它非常适合存储临时数据,如用户会话期间的状态信息。
localStorage:数据没有时间限制,除非用户主动删除或清除浏览器数据,否则数据将一直存在。localStorage适合存储需要长期保存的数据,如用户的偏好设置、登录状态等。

应用场景

sessionStorage:适用于存储用户会话期间需要保留的数据,如购物车内容、用户登录状态等。这些数据在用户关闭浏览器或关闭相关页面后会丢失,因此不需要长期保存。
localStorage:适合存储需要长期保留的数据,如用户的个性化设置、历史记录等。这些数据在用户清除之前会一直存在,甚至在用户更换设备后依然可以访问。

存储大小和类型

存储大小:sessionStorage和localStorage的存储大小通常都是5MB,尽管具体大小可能因浏览器而异。
存储类型:两者都只能存储字符串类型的数据。如果需要存储其他类型的数据,如对象或数组,需要先将其序列化为字符串形式进行存储。

操作方法

两者都提供了类似的方法来操作数据,包括setItem(保存数据)、getItem(获取数据)、removeItem(删除特定数据)和clear(清除所有数据)等。

总结

sessionStorage和localStorage都是HTML5提供的Web Storage API的一部分,用于在客户端存储数据。它们的主要区别在于数据的生命周期、存储的持久性以及适合的应用场景。sessionStorage适合存储临时数据,而localStorage适合存储需要长期保存的数据。两者都有5MB的存储空间限制,且只能存储字符串类型的数据,但可以通过序列化和反序列化的方式存储其他类型的数据。

你可能感兴趣的:(Vue,前端,java,javascript)