返回博客列表

Arco Tabs + animatecss 动画

2026-01-29
2 min read
vue

用法 组件

用法

<Tabs :tabs="[{title: '订单明细',slot: 'details'},{title: '结算明细',slot: 'settle'},{title: '结算明细2',slot: 'settle2'}]">
        <template #details>
          <EditorTable :editor="editor" v-model="data.orderDetails" :columns="detailsCls"/>
        </template>
        <template #settle>
          <EditorTable :editor="editor" v-model="data.orderDetails" :columns="detailsCls"/>
        </template>
        <template #settle2>
        </template>
      </Tabs>

组件

<template>
  <div class="tabsWrapper">
    <a-card :bordered="false">
      <a-tabs type="rounded"
              class="custom-tabs"
              v-model:active-key="activeKey"
              @change="handleChange"
      >
        <a-tab-pane v-for="tab in props.tabs" :key="tab.slot">
          <template #title>
            {{ tab.title }}
          </template>
          <slot :name="tab.slot"/>
        </a-tab-pane>
      </a-tabs>
    </a-card>
  </div>
</template>

<script setup lang="ts">
export interface TabTableProps {
  title: string;
  slot: string;
}

export interface TabsProps {
  tabs: TabTableProps[]
}

const props = withDefaults(defineProps<TabsProps>(), {
  tabs: []
})

// 当前激活的 key
const activeKey = ref(props.tabs.length ? props.tabs[0].slot : "");

// 上一次的 key
const prevKey = ref(activeKey.value);

// 动画方向
const animation = ref("");

const left = ['fadeInLeft', 'slideInLeft'];

const right = ['fadeInRight', 'slideInRight'];

/**
 * 切换 tab 时触发
 */
function handleChange(newKey: string) {
  const oldIndex = props.tabs.findIndex((t) => t.slot === prevKey.value);
  const newIndex = props.tabs.findIndex((t) => t.slot === newKey);

  if (oldIndex < newIndex) {
    animation.value = left[1];
  } else {
    animation.value = right[1];
  }

  prevKey.value = newKey;
}
</script>

<style scoped lang="scss">
#container {
}

.tabsWrapper {
  :deep(.arco-card-body) {
    padding: 5px 0px !important;
  }

  :deep(.arco-tabs-nav::before) {
    //display: none !important;;
  }

  :deep(.arco-tabs-content) {
    padding: 5px 0;
  }

  :deep(.arco-tabs-nav-tab-list) {
    padding: 5px;
    background-color: var(--color-fill-1);
    border-radius: 5px;

    position: relative;
  }

  :deep(.arco-tabs-nav-type-rounded .arco-tabs-tab) {
    border-radius: 5px;
  }

  :deep(.arco-tabs-tab:hover) {
    background-color: var(--color-fill-1);
  }

  :deep(.arco-tabs-nav-type-rounded .arco-tabs-tab-active) {
    background-color: var(--color-bg-2);
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    transition: background-color .3ms ease-in-out;
    animation: v-bind(animation);
    animation-duration: .3s;
  }

}
</style>

返回博客列表
最后更新于 2026-01-29
想法或问题?在 GitHub Issue 下方参与讨论
去评论