函数防抖(debounce)的应用场景
连续的事件,只需触发一次的回调场景有:搜索框搜索输入。只需要用户最后一次输入完再发送请求 手机号、邮箱格式的输入验证检测窗口大小的resize 。只需窗口调整完成后,计算窗口的大小,防止重复渲染
函数节流(throttle)的应用场景
间隔一段时间执行一次回调的场景有:滚动加载,加载更多或滚动到底部监听谷歌搜索框,搜索联想功能高频点击提交,表单重复提交省市信息对应字母快速选择
1.防抖
export const boDebounce = (func, wait, immediate) => {console.log("进入防抖");let timeout;return function () {const context = this;const args = [...arguments];if (timeout) clearTimeout(timeout);if (immediate) {const callNow = !timeout;timeout = setTimeout(() => {timeout = null;}, wait)if (callNow) func.apply(context, args)}else {timeout = setTimeout(() => {func.apply(context, args)}, wait);}}}使用:<template><div><el-input v-model="input" @input="getSearch"> </el-input><el-input v-model="nowInput" @input="getNowSearch"> </el-input></div></template><script>import { debounce, nowDebounce } from "@/store/debounce.js";export default {data() {return {input: "",nowInput: "",};},methods: {getSearch: boDebounce(function () {console.log("拿到数据");},1000,false),getSearch: debounce(function () {console.log("拿到数据");}, 1000),getNowSearch: nowDebounce(function () {console.log("立即拿到数据");}, 1000),},};</script>
2.节流
export const boThrottle = (func, wait, type) => {console.log("进入节流")let previous;let timeoutif (type === "now") {previous = 0;} else if (type === "late") {timeout;}return function () {let context = this;let args = arguments;if (type === "now") {let now = Date.now();if (now - previous > wait) {func.apply(context, args);previous = now;}} else if (type === "late") {if (!timeout) {timeout = setTimeout(() => {timeout = null;func.apply(context, args)}, wait)}}}}使用:<template><div><div class="mouseDiv" @mousemove="mouseNoMoveEvent">{{ mouseNowNum }}</div><div class="mouseDiv" @mousemove="mouseMoveEvent">{{ mouseNum }}</div></div></template><script>import {throttle,nowThrottle,boThrottle} from "@/store/debounce.js";export default {data() {return {mouseNowNum: 0,mouseNum: 0,};},methods: {mouseNoMoveEvent: nowThrottle(function () {this.mouseNowNum++;console.log("立即执行");}, 1000),mouseMoveEvent: throttle(function () {this.mouseNum++;console.log("延迟执行");}, 1000),mouseNoMoveEvent: boThrottle(function () {this.mouseNowNum++;console.log("立即执行");},1000,"now"),mouseMoveEvent: boThrottle(function () {this.mouseNum++;console.log("延迟执行");},1000,"late"),},};</script><style>.mouseDiv {margin: 20px auto;width: 1000px;height: 400px;line-height: 400px;text-align: center;font-size: 30px;background-color: lightblue;}</style>
3.节流 时间戳版,立即执行版
export const nowThrottle = (func, wait) => {console.log("进入节流")var previous = 0;return function () {let now = Date.now();let context = this;let args = arguments;if (now - previous > wait) {func.apply(context, args);previous = now;}}}
4.节流 计时器版,延迟执行版
export const throttle = (func, wait) => {console.log("进入节流")let timeout;return function () {let context = this;let args = arguments;if (!timeout) {timeout = setTimeout(() => {timeout = null;func.apply(context, args)}, wait)}}}
