• vue 路由缓存 路由嵌套 路由守卫 监听物理返回


    最近开发vue项目,遇到的一些问题,这里整合一下,看到一些博客已经有写相关知识,然后自己再次记录一下。

    这是关于vue路由相关比较常见的问题,以后遇到相关路由的问题,会不断更新这篇博客。

    需求1:从填写表单A页面跳转到B页面,然后再从B页面返回到A页面,实现A页面的所填的数据保留

    一.设置路由缓存:

      1.App.vue中加入<keep-alive>  具体代码如下:

      

    <template>
      <div id="app">
        <!--<img src="./assets/logo.png">-->
        <keep-alive>
          <router-view v-if="$route.meta.keepAlive">
            <!-- 这里是会被缓存的视图组件A -->
          </router-view>
        </keep-alive>
        <router-view v-if="!$route.meta.keepAlive">
          <!-- 这里是不被缓存的视图组件B -->
        </router-view>
      </div>
    </template>

      2.在路由配置文件index.js里面增加meta标签,代码如下:

      

    
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'Initinfo',
          component: Initinfo
        },
          {
              path: '/B',
              name:'B',
              component: CredentialsDetails,
              meta:{keepAlive:false}
          },
          {
              path: '/A',
              name:'A',
              component: ASeal,
              meta:{keepAlive:true}
          }
    
      ]
    })
     

    ok,做到这里,就能实现以上需求1。

    需求2:在需求1基础上,增加一个需求就是,缓存A表单页面滚动位置,代码如下:

    export default new Router({
    
        //使用keep-alive后,可能存在滚动条问题的解决问题
        mode:'hash',//默认是hash模式   且有history
        scrollBehavior(to,from,savePosition) { // 在点击浏览器的“前进/后退”,或者切换导航的时候触发。
            console.log(to) // to:要进入的目标路由对象,到哪里去
            console.log(from) // from:离开的路由对象,哪里来
            console.log(savePosition) // savePosition:会记录滚动条的坐标,点击前进/后退的时候记录值{x:?,y:?}
            if(savePosition){
                return savePosition;
            }else{
                return {
                    x: 0,
                    y: 0
                }
            }
        },
        routes: [
            {
                path: '/',
                name: 'Initinfo',
                component: Initinfo
            },
            {
                path: '/B',
                name:'B',
                component: CredentialsDetails,
                meta:{keepAlive:false}
            },
            {
                path: '/A',
                name:'A',
                component: ASeal,
                meta:{keepAlive:true}
            }
    
        ]
    })

     需求3:

      1.默认显示 A

      2. B跳到 A,A 不刷新

      3. C跳到 A,A 刷新

      https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

      以上是路由守卫官网,可以参考,下面介绍两个守卫:beforeRouteLeave,beforeRouteEnter

      1.在路由的index.js文件,和以上路由一样,设置A页面的meta属性,代码如下:

    {
        path: '/A',
        name:'A',
        component: ASeal,
        meta:{keepAlive:true}
     }

          2. 在B组件设置 beforeRouteLeave:代码如下:

    export default {
        beforeRouteLeave(to, from, next) {
            console.log(to);
            console.log(from)
            // 设置下一个路由的 meta
            to.meta.keepAlive = true;  // 让 A 缓存,即不刷新
            next();//确保要调用 next 方法,否则钩子就不会被 resolved
        }
    };    

      3.在C组件设置 beforeRouteLeave:代码如下:

    export default {
        beforeRouteLeave(to, from, next) {
            console.log(to);
            console.log(from)
            // 设置下一个路由的 meta
            to.meta.keepAlive = false;  // 让 A不缓存,即刷新
            next();//确保要调用 next 方法,否则钩子就不会被 resolved
        }
    };   

    ok,以上代码即可满足需求3

    需求4:

      1.A-->B-->C-->D   从A页面依次进入BCD页面,现在我要在D页面点击返回(手机或者浏览器物理返回键)回到A页面

      2.A-->E-->D  从A页面一次进入ED页面,现在我在D页面点击返回(手机或者浏览器物理返回键)回到E页面

           以上的需求总结来说就是,根据不同的渠道进入D页面的时候,当点击返回的时候,进入不同的页面

      1.首先我在入口main.js里面声明了一个全局变量(当然你可以按照自己的方式去声明一个变量)

    global.beforeRouteName = "";

      2.然后在D组件中,声明路由守卫:beforeRouteEnter,代码如下:

      刚进入该组件时,便会进入beforeRouteEnter,在此先赋值:

     beforeRouteEnter(to,from,next){
         global.beforeRouteName = from.name;   //给全局变量赋值
         next();
     },

      然后在mounted里面判断浏览器是否支持popstate

    mounted(){
       //判断浏览器是否支持popstate
       if(window.history && window.history.pushState){
          history.pushState(null,null,document.URL);
           window.addEventListener('popstate',this.goBack,false);
       }
     }

      其次在methods里面写goBack方法,代码如下:

    goBack(){
        if(global.beforeRouteName == "C"){     //判断,当获取上个页面进来的路由是C的时候,返回到A页面
           this.$router.push({name:'A'});    
        }else if(global.beforeRouteName == "E"){  //判断,当获取上个页面进来的路由是E的时候,返回上一页
           history.go(-1);
        }else{
           this.$router.push({name:'A'});   //判断,当有其他返回值的时候,默认返回到A页面(这个随意设置,一般不会有这种情况)
        }
     }

      最后一定不要忘记:在destroyed要取消监听,不然这个监听一直存在,代码如下:

    destroyed(){
        window.removeEventListener('popstate',this.goBack,false);
    }

     到此需求4就解决了。

     刚刚看了下代码,其实路由守卫做这个返回控制其实更简单。只要好好使用beforeRouteLeave这个守卫就能简单解决以上问题

  • 相关阅读:
    python内建eval, exec 和exec函数的用法
    wxPython控件学习之wx.grid.Grid (包括对GridCellEditor和GridCelRender的扩展,以支持更多的grid cell 样式, 以GridCellColorEditor为例)
    wxPython控件学习之wx.ComboBox
    tar 解压缩命令
    ios是否安装了某应用
    iPhone IOS中DEB如何安装
    一种简便获取iPhone IMEI 的方法
    iOSOpenDevtroubleshoot
    Mac&iOS Socket编程
    Debian Binary Package Building HOWTO
  • 原文地址:https://www.cnblogs.com/start-ming/p/10243079.html
Copyright © 2020-2023  润新知