美文网首页
2021-04-23

2021-04-23

作者: 小王子__ | 来源:发表于2021-04-23 21:30 被阅读0次

    30道大概率会考到的题( 16-18题)

    本章内容

    • 16,页面重排(回流)、重绘,及如何避免
    • 17,IIFE是什么?作用是什么?
    • 18,vue导航守卫

    16,页面重排(回流)、重绘,及如何避免

    当Render tree(Dom tree和css tree结合)因为元素的尺寸、布局、隐藏等改变而需要重新渲染。就会涉及重绘和重排。重排一定触发重绘,重绘不一定触发重排。每个页面至少需要一次重排,就是页面第一次渲染的时候。

    重绘

    只改变自身样式,不会影响其他元素,元素样式改变(宽高、大小、位置不变),比如:background-color

    重排

    元素的宽高、大小、位置发生改变,触发重新布局导致Render tree重新计算布局和渲染,比如:页面初次渲染时、浏览器窗口尺寸变化(重排是根据视口大小计算元素的大小位置的)等

    常见的会触发重排的情况:

    1,页面初次渲染
    2,元素的显示隐藏
    3,元素内容的改变(文本变化、图片被另一个不同尺寸的图片代替、input输入文字等)
    4,浏览器窗口变化
    5,元素大小、位置的改变(宽高、内边距、边框、fixed定位的元素在拖动滚动条时一直触发重排、计算offsetWidth、offsetHeight等)
    
    如何避免重排

    1,多次样式的修改合并为一次
    2,让元素脱离文档流

    // 1,隐藏元素进行修改后再显示
    let dom = document.getElementById('div')
    dom.style.display = 'none'
    dom.style.width = '100px'
    dom.style.padding = '5px'
    dom.style.display = 'block'
    
    // 2,使用createDocumentFragment创建一个子元素,然后再拷贝到文档中
    let dom = document.getElementById('dom')
    let ele = document.createDocumentFragment().appendChild(document.createElement('p'))
    ele.style.width = '100px'
    ele.style.padding = '5px'
    dom.appendChild(ele)
    
    // 3,将原元素拷贝出一个独立的节点,操作这个节点,再覆盖原元素
    let dom = document.getElementById('dom')
    let cloneDom = dom.cloneNode(true)
    cloneDom.style.width = '100px'
    cloneDom.style.padding = '5px'
    dom.parentNode.replaceChild(cloneDom, dom)
    

    3,缓存布局信息
    尽量减少对布局信息的查询次数,可将其fu赋值给局部变量,使用局部变量参与计算

    // 错误写法
    div.style.left = div.offsetLeft + 1 + 'px'
    
    // 正确写法
    let curLeft = div.offsetLeft
    div.style.left = ++curLeft + 1 + 'px'
    

    4,使用虚拟DOM的框架vue/react
    5,使用window.requestAnimationFrame()或window.reqeustIdleCallback()来优化渲染

    文章参考:https://segmentfault.com/a/1190000016990089

    17,IIFE是什么?作用是什么?

    IIFE:立即调用的函数表达式。语法:(function (){})()

    (function () {
      return 'iii'
    })()
    // iii
    

    IIFE作用:隔离作用域,避免与全局作用域内的变量命名冲突或污染全局命名空间

    18,vue导航守卫

    • 全局守卫
    • 路由独享守卫
    • 路由组件内的守卫
    1,全局守卫

    vue-router全局有三个守卫:

    1,router.beforeEach 全局前置守卫 进入路由之前

    2,router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用

    3,router.afterEach 全局后置钩子 进入路由之后

    // main.js
    import router from './router' // 引入路由
    router.beforeEach((to, from, next) => { 
      next()
    })
    router.beforeResolve((to, from, next) => {
      next()
    })
    router.afterEach((to, from) => {
      console.log('afterEach 全局后置钩子')
    })
    
    // to: Route: 将要进入的路由对象
    // from: Route: 当前导航正要离开的路由
    // next: Function: 一定要调用该方法来resolve这个钩子。执行效果依赖next方法的调用参数。
    
    2,路由独享守卫
    {
      path: '/home',
      component: resolve => require(['../views/Home.vue'], resolve),
      meta: {
          title: '首页'
      },
      beforeEnter: (to, from, next) => {
        // 会在全局前置守卫后面调用,所以不会被全局守卫覆盖
      },
      beforeLeave: (to, from, next) => {
    
      }
    }
    
    3,路由组件内的守卫

    1, beforeRouteEnter 进入路由前, 在路由独享守卫后调用, 不能获取组件实例this,组件实例还没被创建

    2,beforeRouteUpdate路由复用同一个组件时, 在当前路由改变,但是该组件被复用时调用,可以访问组件实例this

    3,beforeRouteLeave离开当前路由时,导航离开该组件的对应路由时调用,可以访问组件实例this

    beforeRouteLeave(to, from, next) {
      next()
    },
    beforeRouteEnter(to, from, next) {
      next()
    },
    beforeRouteUpdate(to, from, next) {
      next()
    },
    computed: {},
    method: {}
    

    相关文章

      网友评论

          本文标题:2021-04-23

          本文链接:https://www.haomeiwen.com/subject/eiuhrltx.html