如何在 Vue 3 中为 axios 调用使用去抖功能
How can I use a debounce function for an axios call in Vue 3
我有使用 axios 从 PHP 脚本获取 JSON 数据的代码。目前此调用是在输入字段时触发的。
除了每次按键都会触发调用外,这很好。我想将此功能去抖动半秒钟。
我尝试从我创建的另一个名为 debounce.js 的文件中导入一个函数,其中包含:
const debounce = (fn, delay) => {
let timeout
return (...args) => {
if (timeout) {
clearTimeout(timeout)
}
timeout = setTimeout(() => {
fn(...args)
}, delay)
}
}
export default debounce
我想给这个方法添加去抖:
async fetchResults(){
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}
我想将这个去抖动函数包裹在整个方法中,因为我想对整个方法进行去抖动,而不仅仅是检索数据部分。所以我尝试了这个:
setup(){
async fetchResults = debounce(() => {
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}, 500)
return { fetchResults }
}
但是我遇到这样的语法错误。我怎样才能为整个 fetchResults 方法正确地实现这个去抖?
这是我没有语法错误的完整 JS 代码:
import debounce from './assets/js/debounce.js'
let app = Vue.createApp({
data: function(){
return{
// Object to fill with JSON response
results:[],
showResultDiv: false,
totalResults: 0,
finishedCall: false
}
},
computed: {
// Limit total results in searchdropdown to 6
resultsToShow() {
return this.results.slice(0, 6)
},
// Set the actual unlimited result amount to totalResults with matching string
resultString(){
if(this.totalResults == 1){
return this.totalResults + ' resultaat'
}else{
return this.totalResults + ' resultaten'
}
}
},
methods:{
// Function to show div with loading dots until json returned
loadDiv(condition){
this.showResultDiv = condition
},
async fetchResults(){
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}
}
})
app.mount('#v_search');
你没有说明你遇到了什么语法错误以及发生在什么地方。
虽然我找到了一个,但您似乎想要创建一个函数表达式。
文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function
问题出在你的语法上:
setup(){
async fetchResults = debounce(() => {
await axios.post('includes/searchproducts_json.php', {
您不能使用 async
定义函数表达式,此外,您的 await
无效,因为它所在的函数没有 async
.
应该是:
setup() {
const fetchResults = debounce(async () => {
await axios.post('')
如果你不想使用任何额外的包,你可以像这样在 Vue 3 中使用 debounce。
<input type="search" v-model="query" />
const app = Vue.createApp({
data() {
return {
query: "",
results: [],
};
},
methods: {
debounce(func, timeout = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, timeout);
};
},
fetchResults(query) {
this.debounce(async () => {
await axios
.post("includes/searchproducts_json.php", {
searchterm: query,
})
.then((response) => {
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true;
this.results = response.data.results;
this.totalResults = response.data.total_results;
this.finishedCall = true;
} else {
this.showResultDiv = false;
}
})
.catch((error) => {
console.error(error);
})
.finally(() => {
this.finishedCall = true;
});
}, 500);
},
},
computed: {
query: {
get() {
return this.query;
},
set(val) {
this.fetchResults(val);
this.query = val;
},
},
},
});
我有使用 axios 从 PHP 脚本获取 JSON 数据的代码。目前此调用是在输入字段时触发的。
除了每次按键都会触发调用外,这很好。我想将此功能去抖动半秒钟。
我尝试从我创建的另一个名为 debounce.js 的文件中导入一个函数,其中包含:
const debounce = (fn, delay) => {
let timeout
return (...args) => {
if (timeout) {
clearTimeout(timeout)
}
timeout = setTimeout(() => {
fn(...args)
}, delay)
}
}
export default debounce
我想给这个方法添加去抖:
async fetchResults(){
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}
我想将这个去抖动函数包裹在整个方法中,因为我想对整个方法进行去抖动,而不仅仅是检索数据部分。所以我尝试了这个:
setup(){
async fetchResults = debounce(() => {
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}, 500)
return { fetchResults }
}
但是我遇到这样的语法错误。我怎样才能为整个 fetchResults 方法正确地实现这个去抖?
这是我没有语法错误的完整 JS 代码:
import debounce from './assets/js/debounce.js'
let app = Vue.createApp({
data: function(){
return{
// Object to fill with JSON response
results:[],
showResultDiv: false,
totalResults: 0,
finishedCall: false
}
},
computed: {
// Limit total results in searchdropdown to 6
resultsToShow() {
return this.results.slice(0, 6)
},
// Set the actual unlimited result amount to totalResults with matching string
resultString(){
if(this.totalResults == 1){
return this.totalResults + ' resultaat'
}else{
return this.totalResults + ' resultaten'
}
}
},
methods:{
// Function to show div with loading dots until json returned
loadDiv(condition){
this.showResultDiv = condition
},
async fetchResults(){
await axios.post('includes/searchproducts_json.php', {
// Post data, add value of input to searchterm
searchterm: this.$refs.searchterm.value
})
.then((response)=>{
// Check if status is 200 (OK) and total_results is not 0
// If true show results div and fill data
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true
this.results = response.data.results
this.totalResults = response.data.total_results
this.finishedCall = true
}else{
this.showResultDiv = false
}
})
.catch((error)=>{
console.log(error)
})
.then((response)=>{
// Get length of returned object and add to results
this.finishedCall = true
})
}
}
})
app.mount('#v_search');
你没有说明你遇到了什么语法错误以及发生在什么地方。
虽然我找到了一个,但您似乎想要创建一个函数表达式。
文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function
问题出在你的语法上:
setup(){
async fetchResults = debounce(() => {
await axios.post('includes/searchproducts_json.php', {
您不能使用 async
定义函数表达式,此外,您的 await
无效,因为它所在的函数没有 async
.
应该是:
setup() {
const fetchResults = debounce(async () => {
await axios.post('')
如果你不想使用任何额外的包,你可以像这样在 Vue 3 中使用 debounce。
<input type="search" v-model="query" />
const app = Vue.createApp({
data() {
return {
query: "",
results: [],
};
},
methods: {
debounce(func, timeout = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, timeout);
};
},
fetchResults(query) {
this.debounce(async () => {
await axios
.post("includes/searchproducts_json.php", {
searchterm: query,
})
.then((response) => {
if (response.status === 200 && response.data.total_results != 0) {
this.showResultDiv = true;
this.results = response.data.results;
this.totalResults = response.data.total_results;
this.finishedCall = true;
} else {
this.showResultDiv = false;
}
})
.catch((error) => {
console.error(error);
})
.finally(() => {
this.finishedCall = true;
});
}, 500);
},
},
computed: {
query: {
get() {
return this.query;
},
set(val) {
this.fetchResults(val);
this.query = val;
},
},
},
});