• keep-alive 实现后退不刷新并保持滚动位置


    vue可以通过<keep-alive>元素包裹组件,实现缓存,下次使用时不需要重新创建该组件。但存在一个问题:keep-alive包裹的组件中有滚动元素时,keep-alive不会储存滚动位置。实现后退不刷新主要依据keep-alive组件的activated和deactivated这两个生命周期钩子函数。

    vue钩子函数的执行顺序:
    不使用keep-alive

    beforeRouteEnter --> created --> mounted --> destroyed

    vi设计http://www.maiqicn.com 办公资源网站大全https://www.wode007.com

    使用keep-alive
    初次进入页面,beforeRouteEnter --> created --> mounted --> activated --> deactivated
    再次进入缓存的页面,只会触发beforeRouteEnter -->activated --> deactivated。created和mounted不会再执行。
    其中,activated在keep-alive组件激活时调用.deactivated在keep-alive组件被停用时调用.

    Demo实现了后退不刷新,并且返回时滚动到上次浏览的深度。

    该demo中,包含三个链接导航。

    home --> pageA --> pageB --> pageC

    依次前进,每次前进到一个新页面都需要获取数据,而按下后退键后,
    从pageC返回到pageB,pageB不再获取新数据,而是使用之前缓存的数据。
    从pageB返回到pageA时,pageA不再获取新数据,而是使用之前的数据。并且当pageA存在滚动条时,返回时会滚动到上次浏览高度。
    所以,pageA和pageB需要缓存,pageC不需要缓存。

    //router.js
    import Vue from 'vue';
    import Router from 'vue-router';
    Vue.use(Router);
    
    const router = new Router({
      mode: 'hash',
      routes: [
        {
          path: '/',
          name: 'home',
          component: () =>
            import('./views/Home.vue'),
          meta: {
            title: '首页',
            keepAlive: false //此组件不需要被缓存
          }
        },
        {
          path: '/pageA',
          name: 'pageA',
          component: () =>
              import('./views/pageA.vue'),
          meta: {
            title: 'pageA',
            keepAlive: true,
            isBack: false
          }
        },
        {
          path: '/pageB',
          name: 'pageB',
          component: () =>
              import('./views/pageB.vue'),
          meta: {
            title: 'pageB',
            keepAlive: true,
            isBack: false
          }
        },
        {
          path: '/pageC',
          name: 'pageC',
          component: () =>
              import('./views/pageC.vue'),
          meta: {
            title: 'pageC',
            keepAlive: false
          }
        }
      ]
    });
    export default router;
    
    //pageA.vue
    <template>
        <div class="page-a">
            <h1>pageA</h1>
            <div>
                <div class="item" v-for="item in items" @click="goPageB">
                    {{ item }}
                </div>
            </div>
            <h1 @click="goPageB">go pageB</h1>
        </div>
    </template>
    
    
    <script>
        export default {
            name: 'PageA',
            data() {
                return {
                    msg: "我是PageA页面",
                    items: Array.from({length:50}, (v,k) => k),
                    data: "",
                    scrollTop: 0
                };
            },
            beforeRouteEnter(to, from, next) {
                if(from.name == 'pageB'){
                    to.meta.isBack = true;
                }
    
                next();
            },
            mounted() {
                console.log('mounted....');
                // this指向组件的实例,$el指向当前组件的DOM元素
                const $el = this.$el;
                //滚动事件
                $el.addEventListener("scroll", () => {
                    //记录位置
                    this.scrollTop = $el.scrollTop;
                });
            },
            activated() {
                if(!this.$route.meta.isBack){
                    // 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据
                    this.getData();
                } else {
                    //恢复滚动条高度
                    if(this.scrollTop) {
                        setTimeout(() => {
                            this.$el.scrollTop = this.scrollTop;
                        }, 100);
                    }
                }
                // 恢复成默认的false,避免isBack一直是true
                this.$route.meta.isBack = false;
    
            },
            methods: {
                getData() {
                    // getData方法,模拟从后台请求数据
                    this.data = "数据";
                    console.log('get data')
                },
                goPageB(){
                    this.$router.push({ path: "/pageB" });
                },
                back() {
                    this.$router.push({ path: "/" });
                }
            },
        }
    </script>
    <style>
        .page-a {
            height: 100vh;
            overflow-y: auto;
        }
        .item {
            margin: 5px;
            padding: 10px;
            background: #ccc;
        }
    </style>
  • 相关阅读:
    Mac电脑Tomcat下载及安装(详细)
    PhantomJS 一个隐形的浏览器
    expected_conditions 库的使用方法
    selenium新的定位方法,更简洁很方便
    一写貌似有用的学习网站
    selenium定位方式源码的存放位置
    給查詢出來的列 命名一個名字的方法
    小程式测试 笔记
    nginx ssi 配置小细节(一)
    HTML页面上获取鼠标的位置(备忘)
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/13714313.html
Copyright © 2020-2023  润新知