Vue

2022.03.07

Vue3 自製 breadcrumb 導航麵包屑元件


準備事項

我這邊的範例會以嵌套路由為主,為的是讓階層也能自動顯示。如果你的網站沒有使用嵌套路由,可以用其他的方法對 array 進行處理喔。

實作 Breadcrumb 元件

設定嵌套路由

打開 router/index.js,設定好路由。我的 UserIndex 沒有實體資料,所以當使用者瀏覽這一頁時,我會透過 redirect 將他們導到 userList

import { createRouter, createWebHistory } from 'vue-router'
import UserIndex from '@/views/User/Index'
const routes = [
  {
    path: '/user',
    redirect: { name: 'userList' },
    name: 'user',
    component: UserIndex,
    meta: { titlea: '用戶管理' },
    children: [
      {
        path: 'list',
        name: 'userList',
        component: () => import('@/views/User/List'),
        meta: { title: '用戶列表' }
      },
      {
        path: 'add',
        name: 'userAdd',
        component: () => import('@/views/User/Add'),
        meta: { title: '新增用戶' }
      },
      {
        path: ':id',
        name: 'userSingleList',
        component: () => import('@/views/User/Single'),
        meta: { title: '用戶資訊' }
      },
      {
        path: 'edit/:id',
        name: 'userEdit',
        component: () => import('@/views/User/Edit'),
        meta: { title: '編輯用戶' }
      }
    ]
  }
]

路由位置

@/views/User/Index 裡面只會放 breadcrumb 元件以及 router-view

<template>
  <Breadcrumb />
  <router-view />
</template>
<script>
import Breadcrumb from '@/components/Breadcrumb.vue'
export default {
  components: { Breadcrumb }
}
</script>

製作導航(breadcrumb) 元件

<template>
  <ol class="flex">
    <li v-for="(item, i) in breadcrumbList" :key="i" class="pl-2">
      <router-link :to="item.path">{{ item.meta.title }}</router-link>
    </li>
  </ol>
</template>

這邊用到的是 routermatched 屬性,他可以顯示 router 設定的 meta

<script>
import { ref, watch, onMounted } from 'vue'
import { useRoute } from 'vue-router'
export default {
  name: 'Breadcrumb',
  setup () {
    const route = useRoute()
    const breadcrumbList = ref([])
    const isHome = () => {
      return route.name === 'Home'
    }
    const getBreadcrumbs = () => {
      let matched = route.matched
      if (!isHome(matched[0])) {
        matched = [{ path: '/', meta: { title: '首頁' } }].concat(matched)
      }
      breadcrumbList.value = matched
    }
    watch(route, () => {
      getBreadcrumbs()
    })
    onMounted(() => {
      getBreadcrumbs()
    })
    return { breadcrumbList, getBreadcrumbs }
  }
}
</script>

最後用 after 語法簡單調整一下樣式:

<style scoped>
  li::after {
    content: '/';
    display: inline-block;
    padding-left: .5rem;
  }
  li:last-child::after {
    content: '';
  }
</style>

圖片範例

最後放上實際顯示的效果:


更多 Vue 相關文章

guest
0 則留言
Inline Feedbacks
View all comments
Copyright (C) MUKI space* / Reborn Theme All Rights Reserved.