使用 Vue.js 过滤对象
Filter object with Vue.js
我有一个 Vue.js 组件页面,它从我的后端获取一些数据:
<script setup>
const props = defineProps({
records: {
type: Object,
},
});
</script>
我有三个不同的 filters/states,我希望我的用户能够 select 来自:
- 未标记
- 完成
- 跳过
下面是我如何获取不同过滤器的记录。我正在使用 collect.js
来更轻松地处理对象:
let getRecords = () => {
return collect(props.records)
}
const getUnlabeledRecords = () => {
return getRecords()
.where('skipped', false)
.where('processed', false);
}
const getCompletedRecords = () => {
return getRecords()
.where('processed', true);
}
const getSkippedRecords = () => {
return getRecords()
.where('processed', false)
.where('skipped', true);
}
//Load all records on page load.
const allRecords = ref(getUnlabeledRecords());
//Show current record to the user.
const current = ref(allRecords.value.first());
然后我的用户可以单击他们想要的过滤器:
<a :class="{'bg-gray-100' : currentFilter === 'Unlabeled' }"
@click="allRecords = getUnlabeledRecords(), currentFilter = 'Unlabeled'">
Unlabeled ({{ getUnlabeledRecords().count() }})
</a>
<a :class="{'bg-gray-100' : currentFilter === 'Skipped' }"
@click="allRecords = getSkippedRecords(), currentFilter = 'Skipped'">
Skipped ({{ getSkippedRecords().count() }})
</a>
<a :class="{'bg-gray-100' : currentFilter === 'Completed' }"
@click="allRecords = getCompletedRecords(), currentFilter = 'Completed'">
Completed ({{ getCompletedRecords().count() }})
</a>
上面的代码可以工作,但是感觉很“笨拙”,而且可扩展性不是很好。比如说,我想引入更高级的过滤 - 或者只是其他“过滤选项”,我必须重复很多代码。
有人对我如何更好地做到这一点有建议吗?
这个问题有点笼统,因为我们不知道您的数据格式,也不知道您将来可能需要什么过滤器。这使得很难给你一个真正好的答案。然而,一个简单的胜利似乎是引入一个过滤器 class/object 来保存您想要过滤的内容的详细信息,例如:
const filters = [
{
text: 'Unlabeled',
statesToFilterOn: [
{ key: 'skipped', value: false },
{ key: 'processed', value: false },
]
},
{
text: 'Skipped',
statesToFilterOn: [
{ key: 'skipped', value: true },
{ key: 'processed', value: false },
]
}
]
现在您可以使用 getFilteredData 方法获取过滤后的数据:
const currentFilteredData = ref(getRecords());
const currentFilter = ref();
function applyFilter(filter) {
currentFilter.value = filter;
currentFilteredData.value = getFilteredData(filter);
}
function getFilteredData(filter) {
let filtered = getRecords();
filter.statesToFilterOn.forEach(state => {
filtered = filtered.where(state.key, state.value);
});
return filtered;
}
你的 UI 可以是这样的:
<a
v-for="filter in filters"
:key="filter.text"
@click="applyFilter(filter)"
>
{{ filter.text }} ({{ getFilteredData(filter).count }})
</a>
现在,如果您想添加更多过滤器,只需将一个过滤器添加到 filters
数组即可。您可以根据需要多次执行此操作,除了 filters 数组外,您无需更改任何内容。我认为这是我根据所提供的信息所能给出的最佳答案。
我有一个 Vue.js 组件页面,它从我的后端获取一些数据:
<script setup>
const props = defineProps({
records: {
type: Object,
},
});
</script>
我有三个不同的 filters/states,我希望我的用户能够 select 来自:
- 未标记
- 完成
- 跳过
下面是我如何获取不同过滤器的记录。我正在使用 collect.js
来更轻松地处理对象:
let getRecords = () => {
return collect(props.records)
}
const getUnlabeledRecords = () => {
return getRecords()
.where('skipped', false)
.where('processed', false);
}
const getCompletedRecords = () => {
return getRecords()
.where('processed', true);
}
const getSkippedRecords = () => {
return getRecords()
.where('processed', false)
.where('skipped', true);
}
//Load all records on page load.
const allRecords = ref(getUnlabeledRecords());
//Show current record to the user.
const current = ref(allRecords.value.first());
然后我的用户可以单击他们想要的过滤器:
<a :class="{'bg-gray-100' : currentFilter === 'Unlabeled' }"
@click="allRecords = getUnlabeledRecords(), currentFilter = 'Unlabeled'">
Unlabeled ({{ getUnlabeledRecords().count() }})
</a>
<a :class="{'bg-gray-100' : currentFilter === 'Skipped' }"
@click="allRecords = getSkippedRecords(), currentFilter = 'Skipped'">
Skipped ({{ getSkippedRecords().count() }})
</a>
<a :class="{'bg-gray-100' : currentFilter === 'Completed' }"
@click="allRecords = getCompletedRecords(), currentFilter = 'Completed'">
Completed ({{ getCompletedRecords().count() }})
</a>
上面的代码可以工作,但是感觉很“笨拙”,而且可扩展性不是很好。比如说,我想引入更高级的过滤 - 或者只是其他“过滤选项”,我必须重复很多代码。
有人对我如何更好地做到这一点有建议吗?
这个问题有点笼统,因为我们不知道您的数据格式,也不知道您将来可能需要什么过滤器。这使得很难给你一个真正好的答案。然而,一个简单的胜利似乎是引入一个过滤器 class/object 来保存您想要过滤的内容的详细信息,例如:
const filters = [
{
text: 'Unlabeled',
statesToFilterOn: [
{ key: 'skipped', value: false },
{ key: 'processed', value: false },
]
},
{
text: 'Skipped',
statesToFilterOn: [
{ key: 'skipped', value: true },
{ key: 'processed', value: false },
]
}
]
现在您可以使用 getFilteredData 方法获取过滤后的数据:
const currentFilteredData = ref(getRecords());
const currentFilter = ref();
function applyFilter(filter) {
currentFilter.value = filter;
currentFilteredData.value = getFilteredData(filter);
}
function getFilteredData(filter) {
let filtered = getRecords();
filter.statesToFilterOn.forEach(state => {
filtered = filtered.where(state.key, state.value);
});
return filtered;
}
你的 UI 可以是这样的:
<a
v-for="filter in filters"
:key="filter.text"
@click="applyFilter(filter)"
>
{{ filter.text }} ({{ getFilteredData(filter).count }})
</a>
现在,如果您想添加更多过滤器,只需将一个过滤器添加到 filters
数组即可。您可以根据需要多次执行此操作,除了 filters 数组外,您无需更改任何内容。我认为这是我根据所提供的信息所能给出的最佳答案。