从0到1仿照ant制作面包屑导航栏 | 青训营笔记

166 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第19天

前言

首先要知道什么是面包屑,面包屑导航可以将浏览过的页面记录下来,方便很快速的跳转回某一个页面。

参考文章

vue3——自己封装面包屑导航组件 - 掘金 (juejin.cn)

Vue手把手带你撸项目系列之动态面包屑 - 掘金 (juejin.cn)

具体实现

第一步是要把面包屑的html结构搭好,需要几个插槽,采用什么样的结构 目前来看使用两级结构就OK了。

父:breadcumb

子:item,如果需要下拉菜单,在这里放一个插槽实现就好了

后面要引入我们自己的图标库进行使用,这样更合适,目前先把大的结构写好

问题1

让最后一个的标签不显示,一直无法成功 对这个last-child的理解不够深,还是没有真正的理解,要实际写到才能理解

解决1

是对css的伪类选择器没有整明白

&是breadcrumb-item
        &:nth-last-child(1) {
            .kl-breadcrumb-item-separator {
                display: none;
            }
        }

(对于伪类选择器还要再好好了解一下)

问题2

文档站采用vitepress,不能使用vue-router,所以源码也就无法使用router-link(使用的时候会显示无法使用router-link)

解决 2

所以最后只能采用router的函数式编程来解决问题。

这里自己的问题就在于没有理解只要在html写了标签,在dom树上都会渲染出来,所以哪怕没有用到这个标签也会报错,要正确理解。

源码

breadcrumb

<template>
    <div :class="[n()]">
        <slot></slot>
    </div>
</template>

<script setup lang="ts">
import './breadcrumb.scss'
import { createNamespace } from '@kunlun-design/utils'
import { BreadCrumbProps } from './breadcrumb'
import { provide, ref } from 'vue'

const props = defineProps(BreadCrumbProps)

const separator = ref(props.separator)
provide('separator', separator)

defineOptions({
    name: 'KlBreadCrumb'
})

const { n } = createNamespace('breadcrumb')
</script>

<style scoped lang="scss"></style>

breadcrumb-item

<template>
    <span :class="[n()]">
        <span v-if="to" @click="onClick" class="kl-breadcrumb-item-link">
            <slot></slot>
        </span>
        <span v-else>
            <slot></slot>
        </span>
        <span class="kl-breadcrumb-item-separator">{{ separator }}</span>
    </span>
</template>

<script setup lang="ts">
import './breadcrumb.scss'
import { createNamespace } from '@kunlun-design/utils'
import { BreadCrumbItemProps } from './breadcrumb-item'
import { getCurrentInstance, inject } from 'vue'
import type { Router } from 'vue-router'

const instance = getCurrentInstance()!
const props = defineProps(BreadCrumbItemProps)
const separator = inject('separator')

defineOptions({
    name: 'KlBreadCrumbItem'
})

const { n } = createNamespace('breadcrumb-item')

const router = instance.appContext.config.globalProperties.$router as Router


const onClick = () => {
    if (!props.to || !router) return
    props.replace ? router.replace(props.to) : router.push(props.to)
}
</script>

<style scoped lang="scss"></style>

scss

@import '../../styles/common.scss';

.kl-breadcrumb {
    display: flex;
    align-items: center;
    padding: var(--kl-padding);
    background-color: var(--kl-bg-color);
    color: var(--kl-font-color);
    width: 100%;
    list-style: none;
    box-sizing: border-box;

    &-item {

        &-link,
        a {
            text-decoration: none;
            color: #666;
            transition: all 0.3s;

            &:hover {
                color: #27ba9b;
                cursor: pointer;
            }
        }

        &:nth-last-child(1) {
            .kl-breadcrumb-item-separator {
                display: none;
            }
        }

        span {
            padding: 0px 2px;
        }
    }
}