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: []
}
}
}
我正在根据用户输入过滤一系列大项目,但速度变慢了。所以,想要实现 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: []
}
}
}