You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 04:07:07