• vue3组件篇 Breadcrum


    组件介绍

    面包屑”(Breadcrumbs)是一种用于用户界面导航的常见元素,通常以水平线条或文本链接的形式呈现。它们用于显示用户的当前位置,并提供了导航路径,以便用户可以迅速回到之前的页面或浏览层次结构中的其他页面。以下是关于面包屑组件的介绍和特点:

    1. 导航路径显示:

      • 面包屑通常以文本链接的方式显示,表示用户的当前位置以及导航路径中的其他页面。这有助于用户了解他们的位置,并可以点击链接返回到上一级页面。
    2. 层次结构导航:

      • 面包屑经常用于导航层次结构的页面,例如网站的目录结构、文件系统或产品目录。用户可以通过点击面包屑中的链接来快速浏览不同级别的页面。
    3. 可视化导航:

      • 除了文本链接,面包屑可以包括图标或其他视觉元素,以提供更直观的导航路径。这可以有助于用户更容易地理解层次结构。
    4. 返回功能:

      • 面包屑通常包括一个返回到上一级页面的链接。用户可以通过点击面包屑中的上一级链接来返回到前一个页面。
    5. 点击导航:

      • 用户可以通过点击面包屑中的不同链接来导航到特定页面。这提供了一种非常直观的导航方式,而不需要使用浏览器的后退按钮。
    6. 自定义路径:

      • 面包屑组件通常允许开发人员自定义导航路径,以满足特定应用程序或网站的需求。
    7. 响应式设计:

      • 面包屑组件通常支持响应式设计,以适应不同屏幕尺寸和设备类型。它们可以自动调整布局以适应移动设备和桌面计算机。
    8. 可访问性:

      • 良好的面包屑组件应该考虑到可访问性,以确保它们对于使用辅助技术的用户也是可访问的。

    面包屑是网站和应用程序中导航和用户体验的重要组成部分。它们帮助用户更好地理解网站的结构,提供了直观的导航方式,减少了迷失在复杂网站结构中的可能性。许多前端框架和库提供了面包屑组件,或者你可以自行实现一个,以满足特定项目的需求。

    开发思路

    一个面包屑组件需要完成哪些功能?

    1. 自定义每一级的内容
    2. 自定义间隔符
    3. 能够自定义每一级的点击事件
    4. 结合vue的路由进行页面的一些跳转
    5. 当前激活的路由在面包屑中应该有独特的样式,和点击事件不生效

    组件安装与使用

    需要先安装vue3-dxui

    yarn add vue3-dxui
    
    • 1

    或者

    npm install vue3-dxui
    
    • 1

    全局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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    按需引入

    <script>
    import { Card } from 'vue3-dxui'
    
    export default {
      components: {
      	Card
      }
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    config1 = [
        {
          text: 'Home',
          path: '/'
        },
        {
          text: 'BreadCrumnb',
          path: 'breadcrumnb'
        }
      ]
    <BreadCrumnb :config="config1" />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    更自由的方式

    	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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    组件代码

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    我创造了两个组件,BreadcrumbItem和BreadCrumnb。

    BreadcrumbItem

    这个组件相当于面包屑里面的每一级,是一个小部件,我在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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    BreadCrumnb

    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    参数说明

    参数说明
    config生成面包屑的配置,数组对象,对象里面分别配置text和path
    separator面包屑路由与路由之间的间隔符

    关于dxui组件库

    dxui组件库是我个人搭建的vue3 前端交互组件库,倾向于pc网站的交互模式。

    1. 如果你有任何问题,请在博客下方评论留言,我尽可能24小时内回复。
    2. dxui新上线的官网域名变更 http://dxui.cn
    3. npm 官方链接 https://www.npmjs.com/package/vue3-dxui
    4. 如果你想看完整源码 https://github.com/757363985/dxui

    在这里插入图片描述

  • 相关阅读:
    基于Pytorch框架的轻量级卷积神经网络垃圾分类识别系统
    NSSM部署window服务
    HTTP协议3)----对于网络层的详细讲解
    windows中elasticsearch7中添加用户名密码验证
    MySQL锁机制
    操作系统的主要功能
    Hadoop入门(三):本地运行模式和完全分布模式,集群分发脚本、远程同步、集群分发
    Linux 的端口区间及设置
    分享股票下单API接口的方式和API攻略
    剑指offer——JZ86 在二叉树中找到两个节点的最近公共祖先 解题思路与具体代码【C++】
  • 原文地址:https://blog.csdn.net/glorydx/article/details/126613740