条件覆盖 Primevue Class p-accordion-header

Condtional overwrite Primevue Class p-accordion-header

我正在尝试找到一个解决方案来覆盖 primevue 组件 class p-accordion-header 以根据我可以通过 variantNumber 获得的渲染组件的状态具有不同的样式.

我的代码是这样的:

  <Accordion :multiple="true">
    <AccordionTab
      v-for="variantNumber in variants?.keys()"
      :key="'V' + variantNumber"
    >
    </AccordionTab>
  </Accordion>

其中 variants 是一个简单列表。

假设我有一个函数 returns 当前的 class 名字叫做 getCurrentVariantClass(variantNumber)

  1. 我无法将 class 添加到 AccordionTab,因为它是一个非 props 属性。
  2. 我试图在 AccordionTab 周围包裹一个 div 或一个简单的 html 标签,并在其中添加一个 class 但组件不会呈现。

我应该如何有条件地覆盖 p-accordion-header 的样式?

为了能够自定义 AccordionTab 以接收 variant 道具,我们可以创建一个使用 extends 选项的新组件,并在其中添加道具:

<!-- MyAccordionTab.vue -->
<script>
import { defineComponent } from 'vue'
import AccordionTab from 'primevue/accordiontab'

export default defineComponent({
  name: 'AccordionTab', // must be named "AccordionTab" for Accordion to detect it
  extends: AccordionTab,
  props: {
    variant: Number, 
  },
  render: AccordionTab.render,
})
</script>

使用上面相同的技术,扩展 Accordion 组件以覆盖其 getTabHeadherClass() method,根据给定的 tab 的 [=14] 有条件地添加 class =] 道具:

<!-- MyAccordion.vue -->
<script>
import { defineComponent } from 'vue'
import Accordion from 'primevue/accordion'

export default defineComponent({
  extends: Accordion,
  methods: {
    getTabHeaderClass(tab, i) {
      const headerClasses = Accordion.methods.getTabHeaderClass.call(this, tab, i)
      const variantClass = this.getCurrentVariantClass(tab.props.variant)
      return headerClasses.concat(variantClass)
    },
    getCurrentVariantClass(variantNumber) {
      switch (variantNumber) {
        case 1:
          return 'p-accordion-header-variant-a'
        case 2:
          return 'p-accordion-header-variant-b'
        case 3:
          return 'p-accordion-header-variant-c'
      }
    },
  },
  render: Accordion.render,
})
</script>

<style scoped>
.p-accordion-header-variant-a .p-accordion-header-link {
  border: solid 1px red;
}
.p-accordion-header-variant-b .p-accordion-header-link {
  border: solid 1px green;
}
.p-accordion-header-variant-c .p-accordion-header-link {
  border: solid 1px blue;
}
</style>

最后,在您的应用中使用这些新组件:

<!-- App.vue -->
<script setup>
import Accordion from '@/components/MyAccordion.vue'
import AccordionTab from '@/components/MyAccordionTab.vue'

const tabs = [/*...*/]
</script>

<template>
  <Accordion multiple>
    <AccordionTab v-for="tab in tabs" :key="tab.title" :variant="tab.variant" :header="tab.title">
      <p>{{ tab.content }}</p>
    </AccordionTab>
  </Accordion>
</template>

demo