Skip to content

Commit

Permalink
feat(Breadcrumb): 新增面包屑组件 (#706)
Browse files Browse the repository at this point in the history
* feat: 面包屑组件开发完成

* feat: pr问题修改

* feat: 移除icon和menu

* docs: 文档格式化

* feat: pr问题修改

* feat: 移除to和replace

---------

Co-authored-by: blankzhang <[email protected]>
  • Loading branch information
zym19960704 and blankzhang authored Apr 1, 2024
1 parent a5eb9ee commit 96192c1
Show file tree
Hide file tree
Showing 15 changed files with 276 additions and 2 deletions.
1 change: 1 addition & 0 deletions components/_style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ import './avatarGroup/style';
import './progress/style';
import './transfer/style';
import './input-file/style';
import './breadcrumb/style';
2 changes: 2 additions & 0 deletions components/avatar/avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from 'vue';
import getPrefixCls from '../_util/getPrefixCls';
import { PictureFailOutlined } from '../icon';
import { useTheme } from '../_theme/useTheme';
import { avatarProps } from './props';
import { sizeMap } from './const';

Expand All @@ -19,6 +20,7 @@ export default defineComponent({
props: avatarProps,
emits: ['error'],
setup(props, { emit, slots }) {
useTheme();
const avatarCls = computed(() => {
return [
`${prefixCls}`,
Expand Down
2 changes: 2 additions & 0 deletions components/avatarGroup/avatarGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import getPrefixCls from '../_util/getPrefixCls';
import { FAvatar } from '../avatar';
import { FTooltip } from '../tooltip';
import { useTheme } from '../_theme/useTheme';
import { avatarGroupProps } from './props';

const prefixCls = getPrefixCls('avatar-group');
Expand All @@ -16,6 +17,7 @@ export default defineComponent({
name: 'FAvatarGroup',
props: avatarGroupProps,
setup(props, { slots }) {
useTheme();
// 渲染option
const renderAvatarByOption = (num?: number) => {
const avatarList = props.options.map((avatar, index) => {
Expand Down
36 changes: 36 additions & 0 deletions components/breadcrumb/breadcrumb-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { computed, defineComponent, inject } from 'vue';
import { useTheme } from '../_theme/useTheme';
import { BREADCRUMB_KEY, itemCls } from './const';

export default defineComponent({
name: 'FBreadcrumbItem',
emits: ['click'],
setup(props, { emit, slots }) {
useTheme();

const { props: parentProps } = inject(BREADCRUMB_KEY);

const itemStyle = computed(() => {
return {
fontSize: `${parentProps.fontSize}px`,
lineHeight: 1,
};
});

// 处理点击跳转的事件
const handleClick = () => {
// 触发用户自定义的click事件
emit('click');
};

return () => (
<div
class={itemCls}
style={itemStyle.value}
onClick={() => handleClick()}
>
{slots.default?.()}
</div>
);
},
});
46 changes: 46 additions & 0 deletions components/breadcrumb/breadcrumb.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { computed, defineComponent, provide } from 'vue';
import { useTheme } from '../_theme/useTheme';
import { breadcrumbProps } from './props';
import { BREADCRUMB_KEY, prefixCls } from './const';

export default defineComponent({
name: 'FBreadcrumb',
props: breadcrumbProps,
setup(props, { slots }) {
useTheme();

provide(BREADCRUMB_KEY, {
props: props,
});
const breadcrumbStyle = computed(() => {
return {
fontSize: `${props.fontSize}px`,
};
});

const breadItemArr = computed(() => {
return slots.default ? slots.default() : [];
});

// 渲染所有的层级
const renderAllItem = () => {
return breadItemArr.value.map((item, index) => {
return (
<div class={`${prefixCls}-child`}>
{item}
{/* 渲染分隔符 */}
<div class={`${prefixCls}-separator`}>
{index !== breadItemArr.value.length - 1 &&
props.separator}
</div>
</div>
);
});
};
return () => (
<div class={prefixCls} style={breadcrumbStyle.value}>
{slots.default && renderAllItem()}
</div>
);
},
});
10 changes: 10 additions & 0 deletions components/breadcrumb/const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { type InjectionKey } from 'vue';
import getPrefixCls from '../_util/getPrefixCls';
import { type BreadcrumbInject } from './props';

export const prefixCls = getPrefixCls('breadcrumb');

export const itemCls = getPrefixCls('breadcrumb-item');

export const BREADCRUMB_KEY: InjectionKey<BreadcrumbInject> =
Symbol('BREADCRUMB_KEY');
19 changes: 19 additions & 0 deletions components/breadcrumb/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { withInstall } from '../_util/withInstall';
import Breadcrumb from './breadcrumb';
import BreadcrumbItem from './breadcrumb-item';
import type { SFCWithInstall } from '../_util/interface';

export { breadcrumbProps } from './props';
export type { BreadcrumbProps } from './props';

type BreadcrumbType = SFCWithInstall<typeof Breadcrumb>;
export const FBreadcrumb = withInstall<BreadcrumbType>(
Breadcrumb as BreadcrumbType,
);

type BreadCrumbItemType = SFCWithInstall<typeof BreadcrumbItem>;
export const FBreadCrumbItem = withInstall<BreadCrumbItemType>(
BreadcrumbItem as BreadCrumbItemType,
);

export default FBreadcrumb;
25 changes: 25 additions & 0 deletions components/breadcrumb/props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { type ComponentObjectPropsOptions } from 'vue';
import {
type ExtractPublicPropTypes,
type ComponentInnerProps,
} from '../_util/interface';

export const breadcrumbProps = {
// 分隔符,默认为/
separator: {
type: String,
default: '/',
},
fontSize: {
type: Number,
default: 14,
},
} as const satisfies ComponentObjectPropsOptions;

export type BreadcrumbProps = ExtractPublicPropTypes<typeof breadcrumbProps>;

type BreadcrumbInnerProps = ComponentInnerProps<typeof breadcrumbProps>;

export type BreadcrumbInject = {
props: BreadcrumbInnerProps;
};
42 changes: 42 additions & 0 deletions components/breadcrumb/style/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';

@breadcrumb: ~'@{cls-prefix}-breadcrumb';
@text-color: var(--f-sub-head-color);

@breadcrumb-item: ~'@{cls-prefix}-breadcrumb-item';
@hover-text-color: var(--f-font-color-base);

.@{breadcrumb} {
display: flex;
flex-wrap: wrap;
align-items: center;
color: @text-color;

&-child {
display: flex;
align-items: center;

.icon {
margin-right: 4px;
}
}

&-separator {
display: flex;
align-items: center;
justify-content: center;
min-width: 14px;
margin: 0 4px;
line-height: 1;
}
}

.@{breadcrumb-item} {
margin: 4px 0;

&:hover {
color: @hover-text-color;
cursor: pointer;
}
}
2 changes: 2 additions & 0 deletions components/breadcrumb/style/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '../../style';
import './index.less';
1 change: 1 addition & 0 deletions components/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ export * from './avatarGroup';
export * from './progress';
export * from './transfer';
export * from './input-file';
export * from './breadcrumb';
32 changes: 32 additions & 0 deletions docs/.vitepress/components/breadcrumb/base.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<FForm :labelWidth="60">
<FFormItem label="分隔符:">
<FInput v-model="separator" class="form-item"></FInput>
</FFormItem>
<FFormItem label="字体大小:">
<FInputNumber v-model="fontSize" class="form-item"></FInputNumber>
</FFormItem>
</FForm>
<FDivider></FDivider>
<FBreadcrumb :separator="separator" :fontSize="fontSize">
<FBreadcrumbItem>首页</FBreadcrumbItem>
<FBreadcrumbItem>二级页面 </FBreadcrumbItem>
<FBreadcrumbItem>三级页面</FBreadcrumbItem>
<FBreadcrumbItem>四级页面</FBreadcrumbItem>
<FBreadcrumbItem>五级页面</FBreadcrumbItem>
</FBreadcrumb>
</template>

<script setup>
import { ref } from 'vue';
const separator = ref('/');
const fontSize = ref(14);
</script>

<style>
.form-item {
width: 100px;
}
</style>
17 changes: 17 additions & 0 deletions docs/.vitepress/components/breadcrumb/click.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<FBreadcrumb>
<FBreadcrumbItem @click="handleClick">首页</FBreadcrumbItem>
<FBreadcrumbItem>
<router-link :to="{ path: 'apple', query: { color: 'red' } }">
二级页面
</router-link>
</FBreadcrumbItem>
<FBreadcrumbItem>三级页面</FBreadcrumbItem>
</FBreadcrumb>
</template>

<script setup>
const handleClick = () => {
window.location.href = '/';
};
</script>
35 changes: 35 additions & 0 deletions docs/.vitepress/components/breadcrumb/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Breadcrumb 面包屑

显示当前页面的路径,快速返回之前的任意页面。

## 组件注册

```js
import { FBreadcrumb } from '@fesjs/fes-design';

app.use(FBreadcrumb);
```

## 代码演示

### 基础用法

:::demo
base.vue
:::

### 自定义点击事件
自定义某个item的点击事件。
同时点击行为,也可以和 vue-router 一起结合使用。

:::demo
click.vue
:::

## Breadcrumb Props

| 属性 | 说明 | 类型 | 默认值 |
| --------- | ----------------- | -------- | ------ |
| separator | 分隔符,默认为`/` | `string` | `-` |
| fontSize | 字体大小 | `number` | `14` |

8 changes: 6 additions & 2 deletions docs/.vitepress/configs/sidebar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,17 @@ const sidebarConfig: Record<string, DefaultTheme.Config['sidebar']> = {
text: '导航组件',
items: [
{
text: 'Menu 导航菜单',
link: '/zh/components/menu',
text: 'Breadcrumb 面包屑',
link: '/zh/components/breadcrumb',
},
{
text: 'Dropdown 下拉菜单',
link: '/zh/components/dropdown',
},
{
text: 'Menu 导航菜单',
link: '/zh/components/menu',
},
{
text: 'Steps 步骤条',
link: '/zh/components/steps',
Expand Down

0 comments on commit 96192c1

Please sign in to comment.