Vue.js中如何用FilterProp实现FlowRun数据按Tab筛选
Vue.js Tab筛选FlowRun数据实现方案
我是Vue.js新手,目前已创建FlowRunStateTypeTab组件,通过useFlowsMock(2)生成模拟数据。该组件包含多个Tab标签页,我希望根据选中的Tab筛选对应类型的FlowRun数据并展示,推测需借助FilterProp实现此功能。现将相关代码附上,恳请提供技术帮助:
相关代码展示
1. FlowRunStateTypeTab组件代码
<template> <p-tabs v-model:selected="selected" :tabs="tabs" class="flow-run-state-type-tabs"> <template #heading="{ tab }"> <template v-if="tab"> <FlowRunStateTypeCount :state-type="getTabStates(tab.label)" :filter="getStateTypeFilter(tab.label)" /> </template> </template> <template #content="{ tab }"> <p-content> <FlowRunStateTypeTabDescription :state-type="getTabStates(tab.label)" :filter="getStateTypeFilter(tab.label)" /> <FlowRunsAccordion :filter="getStateTypeFilter(tab.label)" /> </p-content> </template> </p-tabs> </template> <script lang="ts" setup> import { useRouteQueryParam } from '@prefecthq/vue-compositions' import { computed } from 'vue' import FlowRunsAccordion from '@/components/FlowRunsAccordion.vue' import FlowRunStateTypeCount from '@/components/FlowRunStateTypeCount.vue' import FlowRunStateTypeTabDescription from '@/components/FlowRunStateTypeTabDescription.vue' import { useFlowRunsCount } from '@/compositions' import { FlowRunsFilter } from '@/models/Filters' import { StateType } from '@/models/StateType' const props = defineProps<{ filter?: FlowRunsFilter, }>() const tabStates: Record<string, StateType[]> = { failed: ['failed', 'crashed'], running: ['running', 'pending', 'cancelling'], completed: ['completed'], scheduled: ['scheduled', 'paused'], cancelled: ['cancelled'], } const { count: cancelledCount } = useFlowRunsCount(getStateTypeFilter('cancelled')) const tabs = computed(() => { const tabNames = Object.keys(tabStates) if (!cancelledCount.value || cancelledCount.value < 1) { tabNames.filter(value => value !== 'cancelled') } return tabNames }) const selected = useRouteQueryParam('flow-run-state', 'failed') function getTabStates(tab: string): StateType[] { return tabStates[tab] } function getStateTypeFilter(tab: string): FlowRunsFilter { const types = getTabStates(tab) return { ...props.filter, flowRuns: { ...props.filter?.flowRuns, state: { ...props.filter?.flowRuns?.state, type: types, }, }, sort: 'EXPECTED_START_TIME_DESC', } } </script> <style> .flow-run-state-type-tabs .p-tab { @apply flex-grow flex items-center justify-center } </style>
2. 调用FlowRunStateTypeTab的组件代码
<template> <ComponentPage title="DashboardTimeSpanFilter"> <FlowRunStateTypeTab /> </ComponentPage> </template> <script lang="ts" setup> import { ref } from 'vue'; import { secondsInDay } from 'date-fns'; import ComponentPage from '@/demo/components/ComponentPage.vue'; import { FlowRunStateTypeTab } from '@/components'; import { FlowRunsFilter } from '@/models'; const selected = ref(secondsInDay); </script>
3. FlowRunFilter类型定义
export type FlowRunFilter = { operator?: Operation, id?: string[], notId?: string[], name?: string[], nameLike?: string, tags?: TagFilter, deploymentIdOperator?: Operation, deploymentId?: string[], deploymentIdNull?: boolean, workQueueNameOperator?: Operation, workQueueName?: string[], workQueueNameIsNull?: boolean, state?: StateFilter, flowVersion?: string[], expectedStartTimeBefore?: Date, expectedStartTimeAfter?: Date, nextExpectedStartTimeBefore?: Date, nextExpectedStartTimeAfter?: Date, startTimeBefore?: Date, startTimeAfter?: Date, startTimeNull?: boolean, parentTaskRunIdOperator?: Operation, parentTaskRunId?: string[], parentTaskRunIdNull?: boolean, }
4. FlowRunList演示组件代码
<template> <ComponentPage title="FlowRunList"> <FlowRunList :flow-runs="flowRuns" class="color-mode-default" /> </ComponentPage> </template> <script lang="ts" setup> import FlowRunList from '@/components/FlowRunList.vue' import ComponentPage from '@/demo/components/ComponentPage.vue' import { useFlowRunsMock } from '@/demo/compositions/useFlowRunsMock' const flowRuns = useFlowRunsMock(5) </script>
问题修复与实现方案
1. 修复Tabs计算属性的过滤失效问题
原代码中tabNames.filter(value => value !== 'cancelled')没有重新赋值,导致过滤逻辑不生效,修改如下:
const tabs = computed(() => { let tabNames = Object.keys(tabStates) if (!cancelledCount.value || cancelledCount.value < 1) { tabNames = tabNames.filter(value => value !== 'cancelled') } return tabNames })
2. 传递模拟数据并实现Tab筛选逻辑
步骤1:修改调用组件,传递模拟数据
<template> <ComponentPage title="DashboardTimeSpanFilter"> <FlowRunStateTypeTab :flow-runs="flowRuns" /> </ComponentPage> </template> <script lang="ts" setup> import { ref } from 'vue'; import ComponentPage from '@/demo/components/ComponentPage.vue'; import { FlowRunStateTypeTab } from '@/components'; import { useFlowRunsMock } from '@/demo/compositions/useFlowRunsMock'; // 生成模拟数据 const flowRuns = useFlowRunsMock(2) const selected = ref(secondsInDay); </script>
步骤2:改造FlowRunStateTypeTab组件,添加筛选逻辑
<template> <p-tabs v-model:selected="selected" :tabs="tabs" class="flow-run-state-type-tabs"> <template #heading="{ tab }"> <template v-if="tab"> <FlowRunStateTypeCount :state-type="getTabStates(tab)" :count="filteredFlowRunsByTab(tab).length" /> </template> </template> <template #content="{ tab }"> <p-content> <FlowRunStateTypeTabDescription :state-type="getTabStates(tab)" /> <FlowRunsAccordion :flow-runs="filteredFlowRunsByTab(tab)" /> </p-content> </template> </p-tabs> </template> <script lang="ts" setup> import { useRouteQueryParam } from '@prefecthq/vue-compositions' import { computed } from 'vue' import FlowRunsAccordion from '@/components/FlowRunsAccordion.vue' import FlowRunStateTypeCount from '@/components/FlowRunStateTypeCount.vue' import FlowRunStateTypeTabDescription from '@/components/FlowRunStateTypeTabDescription.vue' import { FlowRun } from '@/models/FlowRun' import { StateType } from '@/models/StateType' const props = defineProps<{ flowRuns: FlowRun[], }>() const tabStates: Record<string, StateType[]> = { failed: ['failed', 'crashed'], running: ['running', 'pending', 'cancelling'], completed: ['completed'], scheduled: ['scheduled', 'paused'], cancelled: ['cancelled'], } const selected = useRouteQueryParam('flow-run-state', 'failed') // 根据Tab名称筛选对应状态的FlowRun数据 function filteredFlowRunsByTab(tab: string): FlowRun[] { const targetStates = tabStates[tab] || [] return props.flowRuns.filter(run => targetStates.includes(run.state.type)) } function getTabStates(tab: string): StateType[] { return tabStates[tab] || [] } const tabs = computed(() => { let tabNames = Object.keys(tabStates) // 移除无对应数据的cancelled标签页 const hasCancelledRuns = props.flowRuns.some(run => run.state.type === 'cancelled') if (!hasCancelledRuns) { tabNames = tabNames.filter(name => name !== 'cancelled') } return tabNames }) </script> <style> .flow-run-state-type-tabs .p-tab { @apply flex-grow flex items-center justify-center } </style>
3. 调整子组件接收筛选后的数据
以FlowRunsAccordion为例,改为直接接收筛选后的FlowRun数组:
<template> <div v-for="run in flowRuns" :key="run.id" class="flow-run-item"> <!-- 这里渲染FlowRun的具体内容 --> <h3>{{ run.name }}</h3> <p>状态:{{ run.state.type }}</p> </div> </template> <script lang="ts" setup> import { defineProps } from 'vue' import { FlowRun } from '@/models/FlowRun' defineProps<{ flowRuns: FlowRun[] }>() </script>
内容的提问来源于stack exchange,提问作者AayushGupta69
相关产品推荐
相关产品推荐

