Tabs

display page access history

Use

Basic Use

Automatic record routes

<template>
  <pro-tabs />
</template>

Custom Type

<template>
  <pro-radio-button v-model="type" :data="data" style="margin-bottom: 16px" />
  <pro-tabs ref="childTabs" :type="type" />
</template>

<script>
import { defineComponent, inject, onMounted, ref, shallowRef } from 'vue'

export default defineComponent({
  setup() {
    const tabs = inject('tabs', undefined) // Get top-level `Tabs` inject
    const childTabs = shallowRef({})
    const type = ref('')
    const data = [
      { value: '', label: 'Default' },
      { value: 'card', label: 'Card' },
      { value: 'border-card', label: 'BorderCard' },
    ]

    onMounted(() => {
      asyncList()
    })

    function asyncList() {
      if (tabs) {
        childTabs.value.list = tabs.value.list
      }
    }

    return {
      childTabs,
      type,
      data,
    }
  },
})
</script>

Keep hidden route

Routes with the hidden flag are automatically closed by default, this behavior can be prevented with keep-hidden-route

<template>
  <pro-tabs keep-hidden-route />
</template>

External call close

Use ref bind Tabs then execute internal methods to close tab

const tabs = inject('tabs') from top-level Layout refer

<template>
  <pro-tabs ref="childTabs" style="margin-bottom: 15px" />
  <el-button @click="childTabs.close('/en-US/guide/')">
    Close homepage
  </el-button>
  <el-button @click="childTabs.closeOther"> Close otherpage </el-button>
  <el-button @click="asyncList"> async </el-button>
</template>

<script>
import { defineComponent, inject, onMounted, shallowRef } from 'vue'

export default defineComponent({
  setup() {
    const tabs = inject('tabs', undefined) // Get top-level `Tabs` inject
    const childTabs = shallowRef({})

    onMounted(() => {
      asyncList()
    })

    function asyncList() {
      if (tabs) {
        childTabs.value.list = tabs.value.list
      }
    }

    return {
      childTabs,
      asyncList,
    }
  },
})
</script>

Before add

Do something before the tab add with the before-add hook. If false is returned or a Promise is returned and then is rejected, add will be prevented.

<template>
  <pro-tabs :before-add="beforeAdd" />
</template>

<script>
import { defineComponent, nextTick } from 'vue'
import { ElNotification } from 'element-plus'

export default defineComponent({
  setup() {
    function beforeAdd(e) {
      console.log('Tabs-before-add', e)
      nextTick(() => {
        ElNotification({
          type: 'success',
          title: 'Success',
          message: 'Come from before-add',
        })
      })
    }

    return {
      beforeAdd,
    }
  },
})
</script>

Before leave

Do something before the tab switch with the before-leave hook. If false is returned or a Promise is returned and then is rejected, add will be prevented.

<template>
  <pro-tabs ref="childTabs" :before-leave="beforeLeave" />
</template>

<script>
import { defineComponent, inject, onMounted, shallowRef } from 'vue'
import { ElNotification } from 'element-plus'

export default defineComponent({
  setup() {
    const tabs = inject('tabs', undefined) // Get top-level `Tabs` inject
    const childTabs = shallowRef({})

    onMounted(() => {
      asyncList()
    })

    function asyncList() {
      if (tabs) {
        childTabs.value.list = tabs.value.list
      }
    }

    function beforeLeave(activeName, oldActiveName) {
      console.log({ activeName, oldActiveName })
      ElNotification({
        type: 'success',
        title: 'Success',
        message: 'Come from before-leave',
      })
      return false
    }

    return {
      childTabs,
      beforeLeave,
    }
  },
})
</script>

Slots

Customize the label content of the tab through label

TIP

Since 1.4.0, the label slot parameter has been changed to RouteLocationNormalizedLoaded

<template>
  <pro-tabs>
    <template #label="{ icon, meta }">
      <div class="tabs-label-content">
        <el-icon :size="16" class="label-icon">
          <component :is="icon" />
        </el-icon>
        <span>{{ meta.title.toUpperCase() }}</span>
      </div>
    </template>
  </pro-tabs>
</template>

<style scoped>
.tabs-label-content {
  display: flex;
  align-items: center;
  justify-content: center;
}
.tabs-label-content .label-icon {
  margin-right: 6px;
}
</style>

Contextmenu

Since 1.4.0, the Tabs component supports displaying the right-click menu through the contextmenu configuration

TIP

If you enable the refresh feature, you need to configure the refreshPath attribute additionally and add the corresponding route information to vue-router

Reference route configuration
import {
  createMemoryHistory,
  createRouter as _createRouter,
  createWebHistory,
  Router,
} from 'vue-router'
import BaseLayout from '../layout/Layout.vue'
import enUS from './en-US'
import zhCN from './zh-CN'
import dev from './dev'
import { langs } from '../utils/index'
import type { RouteRecordRaw } from 'vue-router'

const routes: RouteRecordRaw[] = [
  {
    path: '/dev/refresh',
    component: BaseLayout,
    meta: { hidden: true },
    children: [
      {
        path: '/dev/refresh',
        component: () => import('../layout/Refresh.vue'),
        meta: { hidden: true },
      },
    ],
  },
  ...enUS,
  ...zhCN,
]

export function createRouter(): Router {
  const baseUrl = import.meta.env.BASE_URL
  const router = _createRouter({
    history: import.meta.env.SSR
      ? createMemoryHistory(baseUrl)
      : createWebHistory(baseUrl),
    routes: import.meta.env.MODE === 'production' ? routes : routes.concat(dev),
    scrollBehavior(to, from, savedPosition) {
      if (to.hash) {
        return new Promise((resolve) => {
          setTimeout(() => {
            resolve({
              el: to.hash,
              top: 94,
              behavior: 'smooth',
            })
          }, 600) // Wait for the animation to finish
        })
      } else if (savedPosition) {
        return savedPosition
      } else {
        return { top: 0 }
      }
    },
  })

  router.beforeEach((from) => {
    if (from.path === '/') {
      const lang = navigator.language
      return langs.find((item) => item.key === lang) ? lang : langs[0].key
    }
  })

  return router
}
<template>
  <pro-tabs ref="childTabs" contextmenu refresh-path="/dev/refresh" />
</template>

<script>
import { defineComponent, inject, onMounted, shallowRef } from 'vue'

export default defineComponent({
  setup() {
    const tabs = inject('tabs', undefined) // Get top-level `Tabs` inject
    const childTabs = shallowRef({})

    onMounted(() => {
      asyncList()
    })

    function asyncList() {
      if (tabs) {
        childTabs.value.list = tabs.value.list
      }
    }

    return {
      childTabs,
    }
  },
})
</script>

Props

NameDescriptionTypeAccepted ValuesDefault
typetype of Tabstringcard / border-card-
tab-positionposition of tabsstringtop / right / bottom / lefttop
stretchwhether width of tab automatically fits its containerboolean-false
keep-hidden-routeWhether to keep the route with the hidden flag, it is automatically closed by defaultboolean-false
contextmenuThe right-click menu configurationboolean / object ({ refresh?: boolean, left?: boolean, right?: boolean, others?: boolean })-false
refreshPathRefresh path, used to refresh the tab pagestring--
before-addhook function before add tab. If false is returned or a Promise is returned and then is rejected, add will be preventedFunction({ route, oldPath, list, close, closeOther })--
before-leavehook function before switching tab. If false is returned or a Promise is returned and then is rejected, switching will be preventedFunction(activeName, oldActiveName)--

Events

NameDescriptionType
tab-clicktriggers when a tab is clicked(pane: TabsPaneContext, ev: Event) => void
tab-changetriggers when activeName is changed(name: TabPaneName) => void
tab-removetriggers when tab-remove button is clicked(name: TabPaneName) => void

Methods

NameDescriptionType
listaccess history listRef<RouteLocationNormalizedLoaded[]>
closeclose some tab from tabs(path: string) => void
closeOtherclose other tab from tabs() => void

Slots

NameDescriptionType
labelcustomize the label content of the tabRouteLocationNormalizedLoaded