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

Vue中Tailwind CSS Tabs组件渲染异常问题求助

DaisyUI Tabs组件布局异常修复

问题描述

按照DaisyUI官方文档实现Tabs组件后,出现布局异常:标签栏虽能横向排列,但内容插槽被插入到每个标签组件之间,导致选中除最后一个标签外的其他标签时,标签栏布局被打乱。

具体现象:

  • 未选中任何标签时:未选中标签时的截图
  • 选中最后一个标签时:选中最后一个标签时的截图
  • 选中中间标签时:标签3与其他标签仍在一行,但偏移至屏幕右侧需滚动查看选中中间标签时的截图

问题原因

你的代码错误地将<div role="tabpanel">放在了每个标签对应的<li>元素内部。DaisyUI的Tabs组件要求标签面板(tabpanel)必须与标签列表(<ul>)同级,而非嵌套在标签项中。当选中某个标签时,面板内容会被显示,若面板嵌套在标签项里,会直接破坏标签栏的flex布局,导致标签项尺寸异常。

修复后的代码

<script setup>
import { computed, inject, ref } from 'vue';

import AmortizationTable from './AmortizationTable.vue';
import constants from '../constants/constants';

const props = defineProps(['id', 'title', 'type']);
const emits = defineEmits(['exit-details-panel']);

const budgetPrimitives = inject('budgetPrimitives');
const builders = inject('builders');
const loanPrimitives = inject('loanPrimitives');
const visuals = inject('visuals');

const monthlyBudgets = ref(budgetPrimitives.monthlyBudgets);

const loan = computed(() => {
  const currentLoanId = loanPrimitives.currentLoanId?.value;
  return props.type === constants.LOAN && currentLoanId
    ? loanPrimitives.getLoan(currentLoanId)
    : loanPrimitives.getLoan(constants.TOTALS);
});

const paymentSummary = computed(() => {
  const currentLoanId = loanPrimitives.currentLoanId?.value;
  return props.type === constants.LOAN && currentLoanId
    ? visuals.paymentSummaries.value[currentLoanId]
    : visuals.paymentSummaries.value.totals;
});

const generateKey = (...args) => args.map((arg) => arg.id || arg).join('');

const emitExit = () => {
  emits('exit-details-panel');
};
</script>

<template>
  <base-modal :id="props.id">
    <template #header>
      <h2>{{ title }}</h2>
    </template>
    <template #body>
      <div role="tablist" class="tabs tabs-bordered w-full">
        <!-- 标签栏 -->
        <ul class="flex flex-row">
          <li v-for="(budget, index) in monthlyBudgets" :key="generateKey(loan, budget)">
            <input
              type="radio"
              name="amortization_tables"
              :id="`tab-${generateKey(loan, budget)}`"
              role="tab"
              class="tab"
              :aria-label="`Tab ${budgetPrimitives.getBudgetIndex(budget.id)}`"
            >
          </li>
        </ul>

        <!-- 标签面板:与标签栏同级 -->
        <div
          v-for="(budget, index) in monthlyBudgets"
          :key="`panel-${generateKey(loan, budget)}`"
          role="tabpanel"
          :aria-labelledby="`tab-${generateKey(loan, budget)}`"
          class="tab-content p-10"
        >
          <AmortizationTable
            :id="`amortizationTable-${generateKey(loan, budget)}`"
            :keyPrefix="generateKey(loan, budget)"
            :paymentSummary="paymentSummary[budget.id]"
            :title="
              builders.buildAmortizationTableTitle(
                loan,
                budget,
                loanPrimitives.getLoanIndex(loan.id)
              )
            "
          />
        </div>
      </div>
    </template>
    <template #actions>
      <base-button :class="['createButton']" @click="emitExit">Close</base-button>
    </template>
  </base-modal>
</template>

<style scoped>
input::after {}
</style>

关键调整说明

  1. 将所有tabpanel从<li>中移出,放到<ul>的同级位置,保持与标签栏平行的结构
  2. 给每个radio和对应的tabpanel设置匹配的id和aria-labelledby属性,确保语义化关联
  3. 修正原代码中index未在v-for中声明的问题

内容的提问来源于stack exchange,提问作者K Pekosh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 19:13:08