vue使用防抖debounce

6,427 阅读1分钟

在我们日常开发中,有些输入动作,需要请求后端接口,比如关键词搜索,但是有不能短时间频繁调用,避免对服务器造成过大压力,此时可以考虑使用防抖

基本使用

防抖函数,我是直接使用第三方库 lodash

在事件被触发n秒后再次执行回调,如果在这n秒内又被触发,则重新计时

例子

在线示例

在输入关键字时,回去搜索对应历史描述信息,如果存在历史描述有,就沿用历史的描述

<template>
  <div>
    <el-input
      class="w300"
      v-model="search"
      @input="handleInput"
      placeholder="请输入关键字"
    />
    <el-input class="w300 ml20" v-model="desc" placeholder="请输入描述" />
  </div>
</template>

<script>
const _debounce = require("lodash/debounce"); // eslint-disable-line
export default {
  data() {
    return {
      search: "",
      desc: "",
    };
  },
  methods: {
    handleInput: _debounce(function (v) {
      this.mockDescHistory().then((res) => {
        console.log(res);
        if (res.data.desc) {
          this.desc = res.data.desc;
        }
      });
    }, 800),
    mockDescHistory() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve({
            data: { desc: "666" + new Date().getTime() },
            code: 5000,
          });
        }, 200);
      });
    },
  },
};
</script>

<style scoped>
.w300 {
  width: 300px;
}
.ml20 {
  margin-left: 20px;
}
</style>

传递自定义参数

有时候,在遇到列表中嵌套有输入框时,需要把当前项一些信息传递到输入框中,做一些自定义逻辑处理,可以参考如下例子

例子

在线示例

<template>
  <div>
    <div
      v-for="(item, index) in info"
      :key="`info-item${index}`"
      class="item mt20"
    >
      <el-input
        v-model="item.name"
        placeholder="请输入名称"
        class="w300"
        @input="(v) => handleInput(v, item)"
      ></el-input>
      <el-input
        v-model="item.desc"
        placeholder="请输入描述"
        class="w300 ml20"
      ></el-input>
      <el-button type="primary" class="ml20" @click="handleRemove"
        >移除</el-button
      >
    </div>
    <div class="mt20">
      <el-button type="primary" @click="handleAdd">新增</el-button>
    </div>
  </div>
</template>

<script>
const _debounce = require("lodash/debounce"); // eslint-disable-line

export default {
  name: "HelloWorld",
  data() {
    return {
      search: "",
      info: [
        {
          name: "",
          desc: "",
        },
      ],
    };
  },
  methods: {
    // 防抖
    handleInput: _debounce(function (v, item) {
      this.mockDescHistory().then((res) => {
        console.log(res);
        if (res.data.desc) {
          item.desc = res.data.desc;
        }
      });
    }, 800),
    handleAdd() {
      this.info.push({ name: "", desc: "" });
    },
    handleRemove(index) {
      this.info.splice(index, 1);
    },
    mockDescHistory() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve({
            data: { desc: "666" + new Date().getTime() },
            code: 5000,
          });
        }, 200);
      });
    },
  },
};
</script>

<style scoped>
.w300 {
  width: 300px;
}
.ml20 {
  margin-left: 20px;
}
.mt20 {
  margin-top: 20px;
}
</style>