过滤嵌套(递归)数据(Vue 2)
Filter on nested (recursive) data ( Vue 2 )
这是我的 JSON 数据的示例:
"data":[
{
"id":01,
"name":"test",
"parent_id":null,
"children":[
{
"id":15,
"name":"subChild",
"parent_id":21,
"children":[
{
"id":148,
"name":"subSubChild",
"parent_id":22,
"children":[
....
]
}
]
}
]
},
我想按级别过滤此级别。我做了这个方法:
computed: {
filteredData: function () {
let filterData = this.filter.toLowerCase()
return _.pickBy(this.data, (value, key) => {
return _.startsWith(value.name.toLowerCase(), filterData)
})
},
这只适用于第一个 "level",我尝试了几种解决方案,但 none 对儿童有效。
所以,我希望能够按多个级别进行过滤。
如果你有想法!
谢谢
递归函数可以派上用场来实现这个特定目的。
尝试以下方法,为了更好地查看,请单击下方 运行 代码段 按钮旁边的 Full page
link .
new Vue({
el: '#app',
data() {
return {
filter: '',
maintainStructure: false,
data: [{
"id": 01,
"name": "test",
"parent_id": null,
"children": [{
"id": 15,
"name": "subChild",
"parent_id": 21,
"children": [
{
"id": 148,
"name": "subSubChild",
"parent_id": 22,
"children": []
},
{
"id": 150,
"name": "subSubChild3",
"parent_id": 24,
"children": []
}
]
}]
}]
}
},
methods: {
$_find(items, predicate) {
let matches = [];
for (let item of items) {
if (predicate(item)) {
matches.push(item);
}
else if (item.children.length) {
let subMatches = this.$_find(item.children, predicate);
if (subMatches.length) {
if (this.maintainStructure) {
matches.push({
...item,
children: subMatches
});
}
else {
matches.push(subMatches);
}
}
}
}
return matches;
},
filterBy(item) {
return item.name.toLowerCase().startsWith(this.filter.toLowerCase());
}
},
computed: {
filteredData() {
return this.$_find(this.data, this.filterBy);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>
<label>Filter by <code>item.name</code>:</label>
<input v-model.trim="filter" placeholder="e.g. subsub" />
</div>
<div>
<label>
<input type="checkbox" v-model="maintainStructure" /> Maintain structure
</label>
</div>
<hr />
<pre>{{filteredData}}</pre>
</div>
请注意,我在函数前加上 $_
前缀,以将其标记为 private 函数(如 this Style Guide 中所推荐),因为我们'我们不会在其他任何地方调用它。
这是我的 JSON 数据的示例:
"data":[
{
"id":01,
"name":"test",
"parent_id":null,
"children":[
{
"id":15,
"name":"subChild",
"parent_id":21,
"children":[
{
"id":148,
"name":"subSubChild",
"parent_id":22,
"children":[
....
]
}
]
}
]
},
我想按级别过滤此级别。我做了这个方法:
computed: {
filteredData: function () {
let filterData = this.filter.toLowerCase()
return _.pickBy(this.data, (value, key) => {
return _.startsWith(value.name.toLowerCase(), filterData)
})
},
这只适用于第一个 "level",我尝试了几种解决方案,但 none 对儿童有效。
所以,我希望能够按多个级别进行过滤。
如果你有想法! 谢谢
递归函数可以派上用场来实现这个特定目的。
尝试以下方法,为了更好地查看,请单击下方 运行 代码段 按钮旁边的 Full page
link .
new Vue({
el: '#app',
data() {
return {
filter: '',
maintainStructure: false,
data: [{
"id": 01,
"name": "test",
"parent_id": null,
"children": [{
"id": 15,
"name": "subChild",
"parent_id": 21,
"children": [
{
"id": 148,
"name": "subSubChild",
"parent_id": 22,
"children": []
},
{
"id": 150,
"name": "subSubChild3",
"parent_id": 24,
"children": []
}
]
}]
}]
}
},
methods: {
$_find(items, predicate) {
let matches = [];
for (let item of items) {
if (predicate(item)) {
matches.push(item);
}
else if (item.children.length) {
let subMatches = this.$_find(item.children, predicate);
if (subMatches.length) {
if (this.maintainStructure) {
matches.push({
...item,
children: subMatches
});
}
else {
matches.push(subMatches);
}
}
}
}
return matches;
},
filterBy(item) {
return item.name.toLowerCase().startsWith(this.filter.toLowerCase());
}
},
computed: {
filteredData() {
return this.$_find(this.data, this.filterBy);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>
<label>Filter by <code>item.name</code>:</label>
<input v-model.trim="filter" placeholder="e.g. subsub" />
</div>
<div>
<label>
<input type="checkbox" v-model="maintainStructure" /> Maintain structure
</label>
</div>
<hr />
<pre>{{filteredData}}</pre>
</div>
请注意,我在函数前加上 $_
前缀,以将其标记为 private 函数(如 this Style Guide 中所推荐),因为我们'我们不会在其他任何地方调用它。