云迈博客

您现在的位置是:首页 > 前端技术 > Vue > 正文

Vue

vue跳转页面刷新问题

彭静2021-08-31Vue779
1.页面不刷新A进入到B页面,再次进入到A页面时会重新请求接口数据,重新渲染DOM解决方法:用容器组件,将页面缓存起来;是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染D

1.页面不刷新
A进入到B页面,再次进入到A页面时会重新请求接口数据,重新渲染DOM
解决方法:
用 <keep-alive>容器组件,将页面缓存起来;<keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
第一步:在配置路由页面router.js配置需要缓存的页面

routes: [
    {
        path: '/index',
        component: ()=>import('@/components/data_center/xxx/index.vue'),
        meta: {
            keepAlive: true, // 是否缓存   
        }
    }
]

第二步:在APP.vue中需要进行是否缓存的设置

<template>
  <div id="app">
    <keep-alive>
          <!-- 如果当前打开页面的路由中 keepAlive: true (开启了缓存时) -->
          <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>

    <!-- 如果当前打开页面的路由中 没有 或者为 keepAlive: false (关闭缓存时[默认就是false]) -->
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>

二、页面刷新
1.在路由配置里面设置了keep-alive的页面里面,返回页面或者再次this.route.push跳转时页面不刷新,同一路由携带不同参数,本质上是重用相同的组件实例,默认在跳转路由时会采用缓存策略,并不会刷新当前路由组件,因此不会调用组件的生命周期挂钩,不会调用接口
解决方法:
如果因为设置了keep-alive导致页面不刷新,可以针对该页面关闭keep-alive

meta: {
  keepAlive: false, // 是否缓存   
 }

2.可以使用activated周期函数代替mounted函数,把列表页的请求接口的方法放到activated里面

3.监听路由变化(不推荐、用户体验不好)

watch: {
    $route(to, from) {
      if (this.$route.query.id) {
        console.log( "获取页面数据" );
      }
    }
},
// 或者使用beforeRouteUpdate 导航守卫监听路由变化
beforeRouteUpdate(to, from, next) {
    console.log(this.$route.query.id);
    if (this.$route.query.id) {
      console.info("获取页面数据");
    }
    next();
},

注意:
1.当页面刷新后,此时会认为路由并未发生改变,虽然此时watch中的$route或者beforeRouteUpdate 路由监听均视作无变化,但是会正常执行生命周期,因此不存在刷新出错的问题;
2.只有在这种情况下严格按照官网:对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,beforeRouteUpdate才起作用

4.给路由添加唯一key
如果想强制刷新,可以在根路由上为其分配一个唯一key。采用$route.fullpath作为其唯一key。这样vue就回认为内部路由每个都是不同的路由,在跳转时便会强制刷新组件。

<!-- App.vue根组件代码 -->
<template>
  <div class="app">
      <div class="slide">
          <ul>
              <li><router-link to="/page1/freddy">freddy</router-link></li>    
              <li><router-link to="/page1/nick">nick</router-link></li>    
              <li><router-link to="/page1/mike">mike</router-link></li>    
          </ul>    
      </div>
      <div class="content">
             <router-view :key="key"></router-view>
      </div>
  </div>
</template>

<script>
    export default{
    data(){
        return {}
    },
    computed:{
        key(){
            return this.$route.path + Math.random();
        }
    }
    }
</script>

5.使用provide和inject结合使用 - 利用v-if原理重载路由给<router-view v-if="routerAlive"></router-view>增加一个不同v-if值,来先摧毁,然后再重新创建起到刷新页面的效果。

<!-- App.vue根组件代码 -->
<template>
  <div class="app">
      <div class="slide">
          <ul>
              <li>
              <router-link to="/page1/freddy">freddy</router-link>
              </li>
          </ul>    
      </div>
      <div class="content">
             <router-view v-if="routerAlive"></router-view>
      </div>
  </div>
</template>

<script>
    export default{
    data(){
        return {
        routerAlive:true
        }
    },
    provide(){    //在父组件中创建属性
            return {
                routerRefresh: this.routerRefresh
            }
        },
    methods:{
        routerRefresh(){
        this.routerAlive = false;
        this.$nextTick(()=>{
            this.routerAlive = true;
            });
        }
    }
    }
</script>

this.$nextTick(()=>{}) 的用法是等this.routerAlive = false; 触发后再执行 this.routerAlive = true; 从而起到摧毁再创建的效果。
inject:[‘routerRefresh’], //在子组件中注入在父组件中出创建的属性
this.routerRefresh();//调用

路由回退最好用this.$router.go(-1)或this.$router.back()。
keep-alive只对SPA页面有用,传统的多页面不起作用。

发表评论

评论列表

  • 这篇文章还没有收到评论,赶紧来抢沙发吧~