VueJS 使用 Lodash Debounce 计算 属性

VueJS Computed Property with Lodash Debounce

我正在根据用户输入过滤一系列大项目,但速度变慢了。所以,想要实现 Lodash 去抖动。但是,去抖不会影响任何东西。

以下是 HTML 中的搜索输入字段,用户在其中键入以筛选数组。

<input v-model="search" type="text"/>

在下文中,我循环遍历 filteredIcons 计算的 属性 以显示项目。

<section v-if="icons.length">
  <button v-for="(icon, index) in filteredIcons" :key="index">
    <span v-html="icon.icon"></span>
    <span v-text="icon.name"></span>
  </button>
</section>

这就是 icons 大数组并通过计算 属性 过滤的地方。

import { debounce } from "lodash";

export default {
  data() {
    return {
      icons: [
               {
                 "author":"svg",
                 "icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M13 16v5a1 1 0 01-1 1H9l-3-6a2 2 0 01-2-2 2 2 0 01-2-2v-2c0-1.1.9-2 2-2 0-1.1.9-2 2-2h7.59l4-4H20a2 2 0 012 2v14a2 2 0 01-2 2h-2.41l-4-4H13zm0-2h1.41l4 4H20V4h-1.59l-4 4H13v6zm-2 0V8H6v2H4v2h2v2h5zm0 2H8.24l2 4H11v-4z\"/></svg>",
                 "name":"icon-announcement.svg"
               },
               {
                 "author":"svg",
                 "icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M20 9v10a2 2 0 01-2 2H6a2 2 0 01-2-2V9a2 2 0 01-2-2V5c0-1.1.9-2 2-2h16a2 2 0 012 2v2a2 2 0 01-2 2zm0-2V5H4v2h16zM6 9v10h12V9H6zm4 2h4a1 1 0 010 2h-4a1 1 0 010-2z\"/></svg>",
                 "name":"icon-archive.svg"
               }
             ],
      search: ""
    };
  },
  computed: {
    filteredIcons: {
      get() {
        return this.icons;
      },
      set: debounce(function() {
        this.icons = this.icons.filter(icon => {
          icon.name.toLowerCase().includes(this.search.toLowerCase());
        });
      }, 500)
    }
  }
}

我很难理解为什么这不起作用,以及通过实施去抖来过滤数组中的大型数据项的最佳方法是什么。任何提示将不胜感激。

您的过滤函数未 returning String#includes 的结果,这导致所有项目都不匹配过滤器,从而导致一个空数组。您可以将 return 关键字添加到 return 结果:

const filteredIcons = this.icons.filter(icon => {
  return icon.name.toLowerCase().includes(this.search.toLowerCase())
})

...或者您可以删除括号和分号:

const filteredIcons = this.icons.filter(icon => icon.name.toLowerCase().includes(this.search.toLowerCase()))

此外,去抖应该发生在用户输入上;不在计算 setter 上。我会在输入的 v-model(即 search)上使用 watcher,然后对结果进行去抖动:

export default {
  watch: {
    search: {
      handler(search) {
        this.setIconsDebounced(search)
      },
      immediate: true
    }
  },
  methods: {
    setIconsDebounced: _.debounce(function(search) {
      this.filteredIcons = this.icons.filter(/*...*/)
    }, 500)
  }
}

这消除了对计算道具的需要,但你仍然需要一个变量来保存过滤后的图标,所以在你的数据道具中声明一个:

export default {
  data() {
    return {
      filteredIcons: []
    }
  }
}

demo