“面包屑”(Breadcrumbs)是一种用于用户界面导航的常见元素,通常以水平线条或文本链接的形式呈现。它们用于显示用户的当前位置,并提供了导航路径,以便用户可以迅速回到之前的页面或浏览层次结构中的其他页面。以下是关于面包屑组件的介绍和特点:
导航路径显示:
层次结构导航:
可视化导航:
返回功能:
点击导航:
自定义路径:
响应式设计:
可访问性:
面包屑是网站和应用程序中导航和用户体验的重要组成部分。它们帮助用户更好地理解网站的结构,提供了直观的导航方式,减少了迷失在复杂网站结构中的可能性。许多前端框架和库提供了面包屑组件,或者你可以自行实现一个,以满足特定项目的需求。
一个面包屑组件需要完成哪些功能?
需要先安装vue3-dxui
yarn add vue3-dxui
或者
npm install vue3-dxui
全局main.ts中引入css
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import 'vue3-dxui/dxui/dxui.css'
createApp(App).use(store).use(router).mount('#app')
按需引入
<script>
import { Card } from 'vue3-dxui'
export default {
components: {
Card
}
}
</script>
config1 = [
{
text: 'Home',
path: '/'
},
{
text: 'BreadCrumnb',
path: 'breadcrumnb'
}
]
<BreadCrumnb :config="config1" />
更自由的方式
components: {
BreadCrumnb,
BreadCrumnbItem: BreadCrumnb.item
}
<BreadCrumnb>
<BreadCrumnbItem class="name-no-end" :config="{
path: '/',
text: 'Home'
}"></BreadCrumnbItem>
<span :style="{margin: '0 12px'}">|</span>
<BreadCrumnbItem class="name-end">BreadCrumnb</BreadCrumnbItem>
</BreadCrumnb>
export interface Data {
[key: string]: any
}
export type ConfigPathItemType = {
text: string
path: string
query?: object
replace?: boolean
onClick?: () => void
}
export type ConfigPathType = ConfigPathItemType[]
export type ConfigNameItemType = {
text: string
name: string
params?: object
replace?: boolean
onClick?: () => void
}
export type ConfigNameType = ConfigNameItemType[]
export type ConfigItemType = ConfigPathItemType | ConfigNameItemType
export type ConfigType = ConfigPathType | ConfigNameType
我创造了两个组件,BreadcrumbItem和BreadCrumnb。
这个组件相当于面包屑里面的每一级,是一个小部件,我在BreadCrumnb内部实现里面也用到了它。
<template>
<span @click="breadCrumbItemClick" :class="className">
<slot v-if="showDefaultContent" />
<template v-else>{{ config.text }}</template>
</span>
</template>
<script lang="ts">
import { ComponentInternalInstance, getCurrentInstance, PropType, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ConfigItemType, Data } from './types/index'
export default {
props: {
// 通过传递类名,来自定义样式
className: {
require: false,
default: '',
type: String
},
config: {
require: false,
default: undefined,
type: Object as PropType<ConfigItemType>
}
},
setup(props: Data) {
const currentInstance: ComponentInternalInstance | null = getCurrentInstance()
const userRouter = useRouter()
const breadCrumbItemClick = function (e: Event) {
e.stopPropagation()
e.stopImmediatePropagation()
const config = props.config as ConfigItemType
// 如果没有配置onClick,就通过userRouter触发路由
if (config && typeof config.onClick !== 'function') {
userRouter.push({
...(props.config as any)
})
} else if (config && typeof config.onClick === 'function') {
// 如果自定义了点击事件,就触发自定义的事件
config.onClick()
} else {
// 如果使用这个组件直接@click来自定义点击事件,也是可以的,但config不能配置才行
currentInstance?.emit('click', e)
}
}
const showDefaultContent = ref(false)
const defaultContent = currentInstance?.slots.default
if (defaultContent) {
showDefaultContent.value = true
}
return {
showDefaultContent,
breadCrumbItemClick
}
}
}
</script>
<style lang="scss" scoped>
@import '@/scss/layout.scss';
.dx-breadcrumb-warpper {
width: 100%;
display: flex;
flex-wrap: wrap;
.name-no-end {
color: $grey-color;
cursor: pointer;
&:hover {
color: $black-color;
}
}
.dx-breadcrumb-division {
margin: 0 12px;
}
}
</style>
<template>
<div class="dx-breadcrumb-warpper">
<slot v-if="showCustomContent" />
<template v-else>
<div class="dx-breadcrumb-item" v-for="(item, index) in config" :key="item.name">
<BreadcrumbItem
v-if="index < config.length - 1"
className="name-no-end"
:config="item"
>{{ item.text }}</BreadcrumbItem
>
<BreadcrumbItem v-else class="name-end">{{ item.text }}</BreadcrumbItem>
<span v-if="index < config.length - 1" class="dx-breadcrumb-division">
{{ separator }}
</span>
</div>
</template>
</div>
</template>
<script lang="ts">
import { ComponentInternalInstance, getCurrentInstance, ref, PropType } from 'vue'
import BreadcrumbItem from './BreadcrumbItem.vue'
import { ConfigType } from './types/index'
export default {
props: {
config: {
required: false,
type: Array as PropType<ConfigType>
},
separator: {
required: false,
default: '/',
type: String
}
},
components: {
BreadcrumbItem
},
setup() {
const currentInstance: ComponentInternalInstance | null = getCurrentInstance()
// 自定义内容是否显示
const showCustomContent = ref(false)
const customContent = currentInstance?.slots.default
if (customContent) {
showCustomContent.value = true
}
return {
showCustomContent
}
},
// 我将BreadcrumbItem组件用这种方式注入在这个组件中,使用BreadcrumbItem可以通过 BreadCrumnb.item
item: BreadcrumbItem
}
</script>
<style lang="scss" scoped>
@import '@/scss/layout.scss';
.dx-breadcrumb-warpper {
width: 100%;
display: flex;
flex-wrap: wrap;
.name-no-end {
color: $grey-color;
cursor: pointer;
&:hover {
color: $black-color;
}
}
.dx-breadcrumb-division {
margin: 0 12px;
}
}
</style>
| 参数 | 说明 |
|---|---|
| config | 生成面包屑的配置,数组对象,对象里面分别配置text和path |
| separator | 面包屑路由与路由之间的间隔符 |
dxui组件库是我个人搭建的vue3 前端交互组件库,倾向于pc网站的交互模式。
