Vue中keep-alive的使用详解且防抖节流基本原理及实现

115 阅读3分钟

1、keep-alive概念:

  • keep-alive是Vue的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁。

2、keep-alive作用:

  • 用来缓存组件,避免多次加载相同的组件,减少性能消耗,提高用户体验。

3、keep-alive使用方式:

方式一:在App.vue中使用keep-alive标签,表示缓存所有页面

 <div id="app">
  	<keep-alive>
	    <tar-bar></tar-bar>
	    <div class="container">
	      <left-menu></left-menu>
	      <Main />
	    </div>
    </keep-alive>
  </div>

方式二:按条件缓存,使用include,exclude判断是否缓存

// 1. 将缓存 name 为 cc 的组件,如果有多个,可用逗号分
  	<keep-alive include='cc'>
      <router-view/>
    </keep-alive>
// 2. 将不缓存 name 为 cc 的组件
	<keep-alive exclude='cc'>
  	  <router-view/>
	</keep-alive>
// 3. 还可使用属性绑定动态判断
	<keep-alive :include='includedComs'>
  	  <router-view/>
	</keep-alive>

方式三:在router目录下的index.js中

  • 第一步:使用meta:{keepAlive = true },表示需要缓存
 const routes = [
  {
    path:'/',
    component:Home,
    meta:{
        keepalive:true
    }
  },
  {
    path:'/login',
    component:Login
  },
   {
      path:'/edit',
      component:Edit,
      meta:{
          istoken: true
      }
   },
  {
      path:'/home',
      component:Home,
      meta:{
          keepalive:true
      }
  }
]
  • 第二步:在App.vue中进行判断
<div id="app">
    <!--keep-alive 表示页面不会被销毁,即保持页面状态-->
    <keep-alive>
      <router-view v-if="$route.meta.keepalive"></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepalive"></router-view>
  </div>

谈一谈防抖节流基本原理及实现

1、防抖:防抖是指在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。(就是在触发某个事件后,在下一次触发之前,中间的间隔时间如果超过设置的时间才会发送请求,一直触发就不会发送请求) 实现代码如下:

// func代表一个函数,里面可能会频繁发生回调或ajax请求,delay表示隔多少秒触发才触发,immediate表示是否立即执行,可传true或false,默认false
function debounce(func,delay,immediate) {
    // result表示返回值
    let timeout,result

    let debounced = function () {
        // 存储触发当前事件的this
        let _this = this
        // 存储event对象
        let args = arguments
        clearTimeout(timeout)
        // 判断是否立即执行,如果不传默认不立即执行
        if (immediate){
            // 立即执行
            let callNow = !timeout
            timeout = setTimeout(()=>{
                timeout = null
            },delay)
            if (callNow) result = func.apply(_this,args)
        } else{
            timeout = setTimeout(function () {
                func.apply(_this,args)
            },delay)
        }
        return result
    }
    debounced.cancel=function () {
        clearTimeout(timeout)
        timeout = null
    }
    return debounced
}

主要应用场景有:

  • scroll事件滚动触发,
  • 搜索框输入查询
  • 表单验证
  • 按钮提交事件
  • 浏览器窗口缩放,resize事件

2、节流:节流是指如果持续触发某个事件,则每隔n秒执行一次。实现代码如下:

// func代表可能会频繁发生回调或ajax请求的函数,delay表示等待时间,options为一个对象,leading =true时代表第一次立即执行,training = true 表示最后一次也会被执行
function throttle(func, delay,options) {
    // 使用定时器和时间戳完成的第三版(第一次会触发,最后一次会触发)
    let context,args,timeout;
    // 之前的时间戳
    let oldTime = 0
    if (!options) options={}
    let later = function () {
        oldTime = new Date().valueOf()
        timeout = null
        func.apply(context,args)
    }
    return function () {
        context = this
        args = arguments

        // 获取当前时间戳
        let now = new Date().valueOf()

        // 判断第一次是否执行
        if (options.leading === false){
            // 不执行
            oldTime = now
        }

        // 第一次会触发
        if (now-oldTime > delay){
            if (timeout){
                // 清空定时器
                clearTimeout(timeout)
                timeout = null
            }
            // 立即执行
            func.apply(context,args)
            // 每隔delay秒执行一次
            oldTime = now
        }else if (!timeout && options.trailing!==false){
            timeout = setTimeout(later,delay)
        }
    }
}

主要应用场景:

  • DOM元素的拖拽功能实现
  • 射击游戏类
  • 计算鼠标移动的距离
  • 监听scroll事件