繁体   English   中英

如何在 Vue 3 中使用去抖动 function 进行 axios 调用

[英]How can I use a debounce function for an axios call in Vue 3

我有使用 axios 从 PHP 脚本获取 JSON 数据的代码。目前此调用是在输入字段的输入时触发的。

这很好,除了每次按键都会触发呼叫。 我想将这个 function 去抖半秒钟。

我尝试从另一个我创建的名为 debounce.js 的文件导入 function,其中包含:

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
    })
}

我想将这个 debounce function 包裹在整个方法中,因为我想对整个方法进行 debounce,而不仅仅是检索数据部分。 所以我尝试了这个:

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');

如果你不想使用任何额外的包,你可以像这样在 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;
      },
    },
  },
});

你没有说你有什么语法错误以及在哪里。

我找到了一个,看起来你想创建一个 function 表达式。

文档: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function

问题是你的语法:

setup(){
    async fetchResults = debounce(() => {
        await axios.post('includes/searchproducts_json.php', {

您不能使用async定义 function 表达式,此外,您的await无效,因为它所在的 function 没有async

它应该是:

setup() {
  const fetchResults = debounce(async () => {
    await axios.post('')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM