使用Vue类组件语法取消通知/限制方法



我正在开发一个组件,当搜索栏中的文本发生变化时,该组件会查询外部API,我正在尝试取消该查询,使其只能每2秒执行一次。我正在尝试使用lodash的debounce函数来实现这一点,并发现了多篇博客文章和SO关于将其与Vue组件一起使用的问题,但事情很复杂,因为我使用的是Typescript和Vue类组件语法(https://class-component.vuejs.org/)。老实说,我对这两件事都很陌生。

我发现一篇博客文章概述了如何使用基于对象的Vue组件语法来实现这一点,但它不适用于类组件语法。基于对象的语法允许您将方法封装在_.debounce中,如下所示:

export default {
methods: {
throttledMethod: _.debounce(() => {
console.log('I only get fired once every two seconds, max!')
}, 2000)
}
}

有没有一种方法可以对Vue类组件语法进行类似的处理?

以下是我的代码的相关部分(没有任何去抖动的尝试(:

<template>
<input
v-model="searchQuery"
@keydown="doSearch"
>
</template>
<script lang="ts">
import axios from 'axios';
import _ from 'lodash';
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class FooSearch extends Vue {
// data
searchQuery = '';
results = [];
// methods
async doSearch() {
try {
const response = await axios.get('https://api.example.org/search', {
params: {
query: this.searchQuery,
}
});
this.results = response.data.results;
} catch(error) {
console.log('error');
console.log(error);
}
}
</script>

这里已经讨论过了。

基本上,你需要定义你的基本函数(就像你对doSearch所做的那样(,然后定义新的去抖动函数:

public doSearchDebounced = _.debounce(this.doSearch, 2000)

现在yu只需要调用doSearchDebounced而不是doSearch

虽然上面已经回答了,但我认为我们应该在vue-class-component中充分利用createDecorator,并集成lodash来简化Debounce和Throttle的使用。

创建装饰器.ts


import { createDecorator } from "vue-class-component";
import _ from "lodash";
export const Debounce = (waitMs: number) =>
createDecorator((options, key) => {
if (options.methods && options.methods[key]) {
const originalMethod = options.methods[key];
const debounceMethod = _.debounce(originalMethod, waitMs, {
leading: false,
trailing: true,
});
options.methods[key] = async function (...args: any) {
await debounceMethod.apply(this, args);
};
}
});
export const Throttle = (waitMs: number) =>
createDecorator((options, key) => {
if (options.methods && options.methods[key]) {
const originalMethod = options.methods[key];
const throttleMethod = _.throttle(originalMethod, waitMs, {
leading: true,
trailing: false,
});
options.methods[key] = async function (...args: any) {
await throttleMethod.apply(this, args);
};
}
});

重构代码并使用decorator。

<template>
<input
v-model="searchQuery"
@keydown="doSearch"
>
</template>
<script lang="ts">
import axios from 'axios';
import { Component, Vue } from 'vue-property-decorator';
import { Debounce } from "@/decorator";
@Component
export default class FooSearch extends Vue {
// data
searchQuery = '';
results = [];
// add the Debounce annotation
@Debounce(1500)
async doSearch() {
try {
const response = await axios.get('https://api.example.org/search', {
params: {
query: this.searchQuery,
}
});
this.results = response.data.results;
} catch(error) {
console.log('error');
console.log(error);
}
}
</script>

你可以像那样做

<script lang='ts'>   
import { debounce } from 'decko'
@debounce(1000)
async doSearch() {
....
}
</script>

相关内容

最新更新