我有使用 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;
},
},
},
});
对于那些像我一样使用 Vue Composition Api 找到方法的人:
<input @input="debounceSearch" v-model="searchstring">
以任何你喜欢的方式添加lodash
// bootstrap.js
window._ = require('lodash'); // option1
// yourFile.vue
<script setup>
import _ from 'lodash' // option2
import debounce from 'lodash/debounce' // option3
调用你的函数
// yourFile.vue
// for option 1 & 2
const debounceSearch = _.debounce(() => {fetchResults();}, 400)
// For option 3
const debounceSearch = debounce(() => {fetchResults();}, 400)
const fetchResults = () => {
// run your axios.post(url, data) code here
}
</script>