Vue 防抖與節流の使用

場景

在一個電影項目中,我想在電影的列表中,保存下拉的當前位置,防止你切換頁面後,再切換回當前的電影列表頁,他就又回到電影的第一條數據。
這時候,我不想每次只要滑動一點,就保存當前位置,我想隔一段時間,保存一次,這時候,就能夠使用防抖和節流。git

概念

說白了,防抖節流就是使用定時器來實現咱們的目的。bash

關於定時器的用法,請移步:JS中經常使用計時器的用法session

防抖(debounce):app

在事件被觸發n秒後再執行回調,若是在這n秒內又被觸發,則從新計時。函數

典型的案例就是輸入框搜索:輸入結束後n秒才進行搜索請求,n秒內又輸入的內容,則從新計時。post

節流(throttle):ui

規定在一個單位時間內,只能觸發一次函數,若是這個單位時間內觸發屢次函數,只有一次生效。this

典型的案例就是鼠標不斷點擊觸發,規定在n秒內屢次點擊只生效一次。spa

用法

防抖(debounce)

下拉列表,隔一段時間保存當前下拉位置。code

咱們能夠在mounted鉤子中實現咱們的防抖:

// 防抖  定時器
let timer;

//list就是電影列表	ref="list"	$el獲取DOM元素
this.$refs.list.$el.addEventListener("scroll", e => {
	console.log("---->",e.target.scrollTop)	//不使用防抖
	if (timer) {
		//清空timer
		clearTimeout(timer);
	}
	timer = setTimeout(() => {
		console.log(e.target.scrollTop)	//使用防抖
		
		//在sessionStorage中保存當前下拉位置
		// sessionStorage.setItem("position", e.target.scrollTop);
	}, 75);		//75ms爲最佳
});
複製代碼

效果演示(隔一段時間保存當前位置):
---->爲不使用防抖,沒加的則使用防抖

圖片加載失敗!

輸入框搜索隔段時間進行搜索請求:

<template>
  <div>
    <input type="text" @keyup="debounce" />
  </div>
</template>

<script>
//定義 timer
let timer;
export default {
  methods: {
    debounce: function() {
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(() => {
        console.log("防抖...");
        timer = undefined;
      }, 2000);
    }
  }
};
</script>
複製代碼

圖片加載失敗!

節流(throttle)

在n秒內點擊屢次,只有一次生效。

<template>
  <div>
    <button @click="throttle">按鈕</button>
  </div>
</template>

<script>
//定義
let timer, lastTime;
let now = +new Date();
export default {
  methods: {
    throttle: function() {
      if (lastTime && now - lastTime < 200) { 
        clearTimeout(timer);
      }
      timer = setTimeout(() => {
        console.log("點擊...");
        lastTime = +new Date();
      }, 200);
    }
  }
};
</script>
複製代碼

效果演示:

圖片加載失敗!

補充

固然,也能夠對這兩個方法進行封裝,以便在多處使用。

/**
 * 函數防抖 (只執行最後一次點擊)
 */
export const Debounce = (fn, t) => {
    let delay = t || 500;
    let timer;
    return function () {
        let args = arguments;
        if(timer){
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            timer = null;
            fn.apply(this, args);
        }, delay);
    }
};
/*
 * 函數節流
 */
export const Throttle = (fn, t) => {
    let last;
    let timer;
    let interval = t || 500;
    return function () {
        let args = arguments;
        let now = +new Date();
        if (last && now - last < interval) {
            clearTimeout(timer);
            timer = setTimeout(() => {
                last = now;
                fn.apply(this, args);
            }, interval);
        } else {
            last = now;
            fn.apply(this, args);
        }
    }
};
複製代碼

V_V

相關文章
相關標籤/搜索