zoukankan      html  css  js  c++  java
  • vue路由管理-保留滚动位置功能、按需加载模块名自定义

    路由管理:保留滚动位置

    其实现与组件的keep-alive相关,仅设置了keep-aive的页面,实施保留回退位置能力。

    keep-alive介绍

    作用

    把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染,提升切换性能。

    相关的生命周期

    created() {
        console.log('created')
    },
    activated() {
        console.log('activated')
    },
    deactivated() {
        console.log('deactivated')
    },
    mounted() {
        console.log('mounted')
    }
    

    执行结果

    • 首次执行该keep-alive组件:
      • 进入:created-> mounted-> activated
      • 离开:deactivated
    • 第二次执行该keep-alive组件:
      • 进入:activated
      • 离开:deactivated
    • 对于没有设置keep-alive的组件:
      • 进入:created-> mounted
      • 离开:空

    activated和deactivated为keep-alive组件特有的生命周期,有什么作用呢?

    由于keep-alive对单页路由生效,不论是后退操作,还是跳转操作,当非首次访问组件时,mounted、created不执行,其中的数据请求也不会发起,所以,其数据不会进行相应更新。这种设定,符合回退操作的数据状态,但对于大多数的单页跳转操作,会出现数据问题。此时,可利用ativated,发起数据请求,更新数据状态。由于是数据驱动的视图,所以,在数据请求到达前,组件使用旧的数据状态,仍然能给用户不错的视觉体验(不会出现白屏之类的)。

    保留滚动位置功能的实现方法

    vue-router中有提供scrollBehavior方法,设置回退位置。但由于本项目中vue的基础布局限制,使得scroll在window or document中无效,因此需要自定义方法。

    相关条件

    仅用户进行回退操作,且设置了router为keep-alive属性的方法,才可进行实际的回退。

    思路

    • a、确认回退操作:通过判断scrollBehavior的savedPosition是否存在;
    • b、是否为keep-alive的组件:通过router上的meta.keepAlive属性判断;
    • c、获取页面离开时的位置:beforeEach钩子(该钩子的生命周期:离开前页面,进入下一页面前)

    实现代码

    // app.vue
    <div class='view-frame'>
        <keep-alive>
            <router-view class="view" v-if="$route.meta.keepAlive"></router-view>
        </keep-alive>
        <router-view class="view" v-if="!$route.meta.keepAlive"></router-view>
    </div>
      
    //  router.js
    let routerList = [{
        ...
        meta: {
            keepAlive: true
        }
    }]
        
    const router = new VueRouter({
        mode: 'history',
          ...
        // 设置返回对应位置的操作
        scrollBehavior(to, from, savedPosition) {
            if (savedPosition && to.meta.keepAlive) {
                let scrollTop = store.state.common.scrollPos[to.name] || 0
                if (!scrollTop) {
                    return
                }
                // 对scroll元素进行设置
                setTimeout(() => {
                    let documentElem = document.querySelector('.v-content')
                    if (documentElem) {
                        documentElem.scrollTop = scrollTop
                    }
                }, 0)
            }
        }
    })
    
    router.beforeEach((to, from, next) => {
        // 记录上一个页面的scroll位置
        if (from.name) {
            let contentElem = document.querySelector('.v-content')
            let scrollTop = contentElem ? contentElem.scrollTop : '0'
            store.state.common.scrollPos[from.name] = scrollTop
        }
        next(
    })
    

    按需加载的优化,提升缓存性能

    了解webpack打包配置的童鞋都知道,webpack提供模块方法,实现按需加载的功能,使得单页应用的首屏性能更高。但打包的方法,常常会影响浏览器缓存,当访问一个资源时,如果其已经加载过,将缓存下来,再次访问时,只需从缓存中取,从而省去了再次请求的时间。因此,有效的打包策略应如是:当文件没有改动时,保持其文件名不变。

    webpack提供两种打包方式

    • a、require():将按照webpack的打包id,进行命名;
    • b、require.ensure():可自定义打包名。

    方法1:

    • 优点:打包名不会重复;
    • 缺点:其打包名受包的前后顺序,数量影响,即使文件没发生变化,也可能改变包名.

    方法2:

    • 优点:仅内容变化才改变包名;便于调试、错误跟踪;可读性强;
    • 中性点:可能出现打包名重复,从而使得两个模块打包到一个文件当中。

    第二种方式更佳,相关代码如下:

    // webpack.js
    output: {
        ....
        chunkFilename: utils.assetsPath('js/[name].[chunkhash].js') 
    }
    
    // router.js
    const home = r => require.ensure([], () => r(require('src/views/home')), 'home')
    let routerList = [{
        ...
        component: home
    }]
    

    如此,会出现包合并的问题,因此需要根据路由模块,对包名进行管理。

    ******更新*******

    打包名的命名第三种方式,采用ES6的import实现,需要进行对应的设置:
    step1:.babelrc文件,删除“comments”配置;如图:

    step2: 如果有eslint检测,则需要在eslint中增加配置;如图:

    step3:修改包的加载方式(require.ensure => import):
    将 const home = r => require.ensure([], () => r(require('src/views/home')), 'home')

    替换成:const home = () => import(/* webpackChunkName: 'home' */ 'src/views/home')

    /* webpackChunkName: 'home' */可实现自定义包名,如果不需要自定义,可将该注释删除。

  • 相关阅读:
    数据挖掘:基本概念理解
    Linux:数据库服务(Mysql安装及链接、远程链接、genelog)
    Linux:WebServer(Nginx 虚拟主机配置与伪静态实现)
    Linux:WebServer(Apacge)
    单例和多线程
    Redis注册成服务
    Redis基础学习
    sqlserver查询使用with(nolock)详解
    JAVA设计模式-策略模式
    JAVA设计模式-代理模式
  • 原文地址:https://www.cnblogs.com/hity-tt/p/7795383.html
Copyright © 2011-2022 走看看