ant-design-vue/components/breadcrumb/Breadcrumb.jsx

87 lines
2.7 KiB
Vue
Raw Normal View History

2019-01-12 03:33:27 +00:00
import PropTypes from '../_util/vue-types';
import { cloneElement } from '../_util/vnode';
import { filterEmpty, getComponentFromProp, getSlotOptions } from '../_util/props-util';
import warning from '../_util/warning';
2019-03-13 01:38:54 +00:00
import { ConfigConsumerProps } from '../config-provider';
2019-01-12 03:33:27 +00:00
import BreadcrumbItem from './BreadcrumbItem';
2018-01-15 02:52:16 +00:00
2018-03-10 05:34:26 +00:00
const Route = PropTypes.shape({
path: PropTypes.string,
breadcrumbName: PropTypes.string,
2019-01-12 03:33:27 +00:00
}).loose;
2018-03-10 05:34:26 +00:00
const BreadcrumbProps = {
2019-03-13 01:38:54 +00:00
prefixCls: PropTypes.string,
2018-03-10 05:34:26 +00:00
routes: PropTypes.arrayOf(Route),
params: PropTypes.any,
separator: PropTypes.any,
itemRender: PropTypes.func,
2019-01-12 03:33:27 +00:00
};
2018-03-10 05:34:26 +00:00
2019-01-12 03:33:27 +00:00
function getBreadcrumbName(route, params) {
2018-03-10 05:34:26 +00:00
if (!route.breadcrumbName) {
2019-01-12 03:33:27 +00:00
return null;
2018-01-15 02:52:16 +00:00
}
2019-01-12 03:33:27 +00:00
const paramsKeys = Object.keys(params).join('|');
2018-03-10 05:34:26 +00:00
const name = route.breadcrumbName.replace(
new RegExp(`:(${paramsKeys})`, 'g'),
(replacement, key) => params[key] || replacement,
2019-01-12 03:33:27 +00:00
);
return name;
2018-03-10 05:34:26 +00:00
}
export default {
2018-04-08 13:17:20 +00:00
name: 'ABreadcrumb',
2018-03-10 05:34:26 +00:00
props: BreadcrumbProps,
2019-03-13 01:38:54 +00:00
inject: {
2019-09-11 14:35:25 +00:00
configProvider: { default: () => ConfigConsumerProps },
2019-03-13 01:38:54 +00:00
},
2018-03-10 05:34:26 +00:00
methods: {
2019-01-12 03:33:27 +00:00
defaultItemRender({ route, params, routes, paths }) {
const isLastItem = routes.indexOf(route) === routes.length - 1;
const name = getBreadcrumbName(route, params);
return isLastItem ? <span>{name}</span> : <a href={`#/${paths.join('/')}`}>{name}</a>;
2018-03-10 05:34:26 +00:00
},
},
2019-01-12 03:33:27 +00:00
render() {
let crumbs;
2019-03-13 01:38:54 +00:00
const { prefixCls: customizePrefixCls, routes, params = {}, $slots, $scopedSlots } = this;
2019-09-11 14:35:25 +00:00
const getPrefixCls = this.configProvider.getPrefixCls;
2019-03-13 01:38:54 +00:00
const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls);
2019-01-12 03:33:27 +00:00
const children = filterEmpty($slots.default);
const separator = getComponentFromProp(this, 'separator');
2018-03-10 05:34:26 +00:00
if (routes && routes.length > 0) {
2019-01-12 03:33:27 +00:00
const paths = [];
const itemRender = this.itemRender || $scopedSlots.itemRender || this.defaultItemRender;
crumbs = routes.map(route => {
route.path = route.path || '';
let path = route.path.replace(/^\//, '');
2018-03-10 05:34:26 +00:00
Object.keys(params).forEach(key => {
2019-01-12 03:33:27 +00:00
path = path.replace(`:${key}`, params[key]);
});
2018-03-10 05:34:26 +00:00
if (path) {
2019-01-12 03:33:27 +00:00
paths.push(path);
2018-03-10 05:34:26 +00:00
}
return (
<BreadcrumbItem separator={separator} key={route.breadcrumbName || path}>
{itemRender({ route, params, routes, paths })}
</BreadcrumbItem>
2019-01-12 03:33:27 +00:00
);
});
2018-03-10 05:34:26 +00:00
} else if (children.length) {
crumbs = children.map((element, index) => {
warning(
getSlotOptions(element).__ANT_BREADCRUMB_ITEM,
2019-01-12 03:33:27 +00:00
"Breadcrumb only accepts Breadcrumb.Item as it's children",
);
2018-03-10 05:34:26 +00:00
return cloneElement(element, {
props: { separator },
key: index,
2019-01-12 03:33:27 +00:00
});
});
2018-03-10 05:34:26 +00:00
}
2019-01-12 03:33:27 +00:00
return <div class={prefixCls}>{crumbs}</div>;
2018-03-10 05:34:26 +00:00
},
2019-01-12 03:33:27 +00:00
};