# keep-alive (opens new window)

//需要缓存的页面直接在router中添加
meta: {
 keepAlive: true // true 表示需要使用缓存 false表示不需要被缓存
 }
 
 //在app.vue中
 <div id="app">
    <!-- 缓存所有的页面 -->
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
1
2
3
4
5
6
7
8
9
10
11
12
13

# 前进刷新 后退不刷新 (opens new window)

  • 方法二
 watch: {
    $route (newValue, oldValue) {
      if (oldValue.name !== 'articleDetail' && this.$route.name == 'merchants') {
        Object.assign(this.$data, this.$options.data())
        this.routeInit(); 
        //执行created的请求
        if (this.$refs.list) {
          this.$refs.list.onRefresh(this.listParams);
        }
      }
    }
    
    //methods
     routeInit () {
      this.listParams.url = this.$authApi.yqzsList; //watch拿不到路由参数
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  • 方法三
//route.js
const routes = [
    {
        path: '/',  //首页
        name: 'index',
       	component: Index,
        meta: {
            title: '首页',
            myKeepAlive:true,  //表示该组件缓存
        },
    },
]

1
2
3
4
5
6
7
8
9
10
11
12
13

然后在含有router的路由出口文件中

<template>
    <div>
        <keep-alive :include="keepAliveView">
            <router-view></router-view>
        </keep-alive>
    </div>
</template>
<script>
export default {
    data(){
        return {
            keepAliveView:'',  //需要缓存的组件名称列表,用逗号分隔
        };
    },
    created(){
        this.getKeepAliveView();
    },
    methods:{
        getKeepAliveView(){  //每一帧都获取可缓存列表,防止前进时设置缓存会慢一步
            const self = this;
            requestAnimationFrame(function func(){
                let list = self.$router.options.routes.filter(item=>{
                    return item.meta.myKeepAlive;
                }).map(item=>{
                    return item.component.name;  //这里使用的是组件名。keep-alive是根据组件名判断展示那个组件,如果组件名和路由配置的名称一样可以直接写 item.name (如果配置了路由懒加载的话没有component.name)
                });
                self.keepAliveView = "," + list.join(",");  //必须首部加逗号。
                requestAnimationFrame(func);
            });
        },
    },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

当需要缓存时,给相应页面的相应路由myKeepAlive设置为true就行了,不需要缓存时设置为false。
当然,很多需求是前进缓存,后退清除缓存。(这里提供一个简单方法,网上很多都是这样的)

//添加全局路由守卫,用来判断页面前进或是后退
router.beforeEach((to, from, next) => {  //页面跳转后添加时间戳参数
    if (typeof to.query._t !== "undefined") {
        next();
    } else {
        to.query._t = new Date().getTime().toString();
        next(to);
    }
});

1
2
3
4
5
6
7
8
9
10

在需要用到的地方

watch:{
    $route(to,from){  //当页面返回时将取消缓存
        if (parseInt(to.query._t) < parseInt(from.query._t)){  //表示是返回页面
            if(from.name === this.$options.name){  //如果是当前页面返回的话(this.$options.name是当前组件的名字)
                from.meta.myKeepAlive = false;
            }
        }
    },
},

1
2
3
4
5
6
7
8
9
10

当页面返回的时候设置它的myKeepAlive为false,为什么不是直接用from或者to,因为返回页面包括从上一个页面返回或者返回当前页面,from,to都可能不是当前出口的路由对象。

# vue缓存页面返回到指定滚动位置 (opens new window)

//需要滚动的区域
<div class='main' id='main'>
    //内容
</div>
1
2
3
4
export default{
    data(){
        return{
           scroll:'' 
        }
    },
  mounted() {
    const main = document.getElementById('#main');
    main.addEventListener('scroll', this.handleScroll);
  },
  activated() {
    const main = document.getElementById('#main');
    if (this.scroll > 0) {
      main.scrollTo(0, this.scroll);
      this.scroll = 0;
      main.addEventListener('scroll', this.handleScroll());
    }
  }, 
    methods:{
      handleScroll() {
      const main = document.getElementById('main');
      this.scroll = main.scrollTop;
    },
    }
}

//让元素回到顶部
const main = document.getElementById('#main');
        main.scrollTop = 0;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
lastUpdate: 5/13/2021, 5:35:14 PM