From d7426e11d451d34c706dec22111dfe7657668dd5 Mon Sep 17 00:00:00 2001 From: tanjinzhou <415800467@qq.com> Date: Tue, 13 Oct 2020 18:04:02 +0800 Subject: [PATCH] refactor: breadcrumb button by ts --- .../{Breadcrumb.jsx => Breadcrumb.tsx} | 51 ++++++++++++------- ...{BreadcrumbItem.jsx => BreadcrumbItem.tsx} | 12 ++--- ...bSeparator.jsx => BreadcrumbSeparator.tsx} | 6 +-- components/breadcrumb/{index.js => index.ts} | 3 +- .../breadcrumb/style/{index.js => index.ts} | 0 .../{button-group.jsx => button-group.tsx} | 13 ++--- components/button/{button.jsx => button.tsx} | 23 +++++---- components/button/buttonTypes.js | 15 ------ components/button/buttonTypes.ts | 26 ++++++++++ components/button/{index.js => index.ts} | 3 +- .../button/style/{index.js => index.ts} | 0 components/config-provider/index.tsx | 2 +- components/dropdown/dropdown.jsx | 6 +-- components/locale-provider/index.tsx | 10 ++-- components/menu/MenuItem.jsx | 6 +-- components/menu/index.jsx | 6 +-- 16 files changed, 104 insertions(+), 78 deletions(-) rename components/breadcrumb/{Breadcrumb.jsx => Breadcrumb.tsx} (73%) rename components/breadcrumb/{BreadcrumbItem.jsx => BreadcrumbItem.tsx} (88%) rename components/breadcrumb/{BreadcrumbSeparator.jsx => BreadcrumbSeparator.tsx} (89%) rename components/breadcrumb/{index.js => index.ts} (86%) rename components/breadcrumb/style/{index.js => index.ts} (100%) rename components/button/{button-group.jsx => button-group.tsx} (86%) rename components/button/{button.jsx => button.tsx} (91%) delete mode 100644 components/button/buttonTypes.js create mode 100644 components/button/buttonTypes.ts rename components/button/{index.js => index.ts} (78%) rename components/button/style/{index.js => index.ts} (100%) diff --git a/components/breadcrumb/Breadcrumb.jsx b/components/breadcrumb/Breadcrumb.tsx similarity index 73% rename from components/breadcrumb/Breadcrumb.jsx rename to components/breadcrumb/Breadcrumb.tsx index 7d4db596b..9146bef0c 100644 --- a/components/breadcrumb/Breadcrumb.jsx +++ b/components/breadcrumb/Breadcrumb.tsx @@ -1,10 +1,17 @@ -import { inject, cloneVNode } from 'vue'; +import { inject, cloneVNode, defineComponent, PropType } from 'vue'; import PropTypes from '../_util/vue-types'; import { filterEmpty, getComponent, getSlot } from '../_util/props-util'; import warning from '../_util/warning'; import { defaultConfigProvider } from '../config-provider'; import BreadcrumbItem from './BreadcrumbItem'; import Menu from '../menu'; +import { Omit, VueNode } from '../_util/type'; + +export interface Route { + path: string; + breadcrumbName: string; + children?: Omit[]; +} const Route = PropTypes.shape({ path: PropTypes.string, @@ -14,13 +21,20 @@ const Route = PropTypes.shape({ const BreadcrumbProps = { prefixCls: PropTypes.string, - routes: PropTypes.arrayOf(Route), + routes: {type: Array as PropType}, params: PropTypes.any, - separator: PropTypes.any, - itemRender: PropTypes.func, + separator: PropTypes.VNodeChild, + itemRender: { + type: Function as PropType<( + route: Route, + params: any, + routes: Array, + paths: Array, + ) => VueNode> + }, }; -function getBreadcrumbName(route, params) { +function getBreadcrumbName(route: Route, params: any) { if (!route.breadcrumbName) { return null; } @@ -31,8 +45,14 @@ function getBreadcrumbName(route, params) { ); return name; } +function defaultItemRender(opt: {route: Route, params: any, routes: Route[], paths: string[]}): VueNode { + const { route, params, routes, paths } = opt + const isLastItem = routes.indexOf(route) === routes.length - 1; + const name = getBreadcrumbName(route, params); + return isLastItem ? {name} : {name}; +} -export default { +export default defineComponent({ name: 'ABreadcrumb', props: BreadcrumbProps, setup() { @@ -41,12 +61,7 @@ export default { }; }, methods: { - defaultItemRender({ route, params, routes, paths }) { - const isLastItem = routes.indexOf(route) === routes.length - 1; - const name = getBreadcrumbName(route, params); - return isLastItem ? {name} : {name}; - }, - getPath(path, params) { + getPath(path: string, params: any) { path = (path || '').replace(/^\//, ''); Object.keys(params).forEach(key => { path = path.replace(`:${key}`, params[key]); @@ -54,7 +69,7 @@ export default { return path; }, - addChildPath(paths, childPath, params) { + addChildPath(paths: string[], childPath: string = '', params: any) { const originalPaths = [...paths]; const path = this.getPath(childPath, params); if (path) { @@ -63,9 +78,9 @@ export default { return originalPaths; }, - genForRoutes({ routes = [], params = {}, separator, itemRender = this.defaultItemRender }) { + genForRoutes({ routes = [], params = {}, separator, itemRender = defaultItemRender }: any) { const paths = []; - return routes.map(route => { + return routes.map((route: Route) => { const path = this.getPath(route.path, params); if (path) { @@ -104,14 +119,14 @@ export default { }, }, render() { - let crumbs; + let crumbs: VueNode[]; const { prefixCls: customizePrefixCls, routes, params = {}, $slots } = this; const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls); const children = filterEmpty(getSlot(this)); const separator = getComponent(this, 'separator'); - const itemRender = this.itemRender || $slots.itemRender || this.defaultItemRender; + const itemRender = this.itemRender || $slots.itemRender || defaultItemRender; if (routes && routes.length > 0) { // generated by route crumbs = this.genForRoutes({ @@ -133,4 +148,4 @@ export default { } return
{crumbs}
; }, -}; +}); diff --git a/components/breadcrumb/BreadcrumbItem.jsx b/components/breadcrumb/BreadcrumbItem.tsx similarity index 88% rename from components/breadcrumb/BreadcrumbItem.jsx rename to components/breadcrumb/BreadcrumbItem.tsx index 332533d28..270734c00 100644 --- a/components/breadcrumb/BreadcrumbItem.jsx +++ b/components/breadcrumb/BreadcrumbItem.tsx @@ -1,18 +1,18 @@ -import { inject } from 'vue'; +import { defineComponent, inject } from 'vue'; import PropTypes from '../_util/vue-types'; import { hasProp, getComponent, getSlot } from '../_util/props-util'; import { defaultConfigProvider } from '../config-provider'; import DropDown from '../dropdown/dropdown'; import DownOutlined from '@ant-design/icons-vue/DownOutlined'; -export default { +export default defineComponent({ name: 'ABreadcrumbItem', __ANT_BREADCRUMB_ITEM: true, props: { prefixCls: PropTypes.string, href: PropTypes.string, - separator: PropTypes.any.def('/'), - overlay: PropTypes.any, + separator: PropTypes.VNodeChild.def('/'), + overlay: PropTypes.VNodeChild, }, setup() { return { @@ -24,7 +24,7 @@ export default { * if overlay is have * Wrap a DropDown */ - renderBreadcrumbNode(breadcrumbItem, prefixCls) { + renderBreadcrumbNode(breadcrumbItem: any, prefixCls: string) { const overlay = getComponent(this, 'overlay'); if (overlay) { return ( @@ -65,4 +65,4 @@ export default { } return null; }, -}; +}); diff --git a/components/breadcrumb/BreadcrumbSeparator.jsx b/components/breadcrumb/BreadcrumbSeparator.tsx similarity index 89% rename from components/breadcrumb/BreadcrumbSeparator.jsx rename to components/breadcrumb/BreadcrumbSeparator.tsx index 2ad973d54..74a7e8cdd 100644 --- a/components/breadcrumb/BreadcrumbSeparator.jsx +++ b/components/breadcrumb/BreadcrumbSeparator.tsx @@ -1,9 +1,9 @@ -import { inject } from 'vue'; +import { defineComponent, inject } from 'vue'; import { defaultConfigProvider } from '../config-provider'; import PropTypes from '../_util/vue-types'; import { getSlot } from '../_util/props-util'; -export default { +export default defineComponent({ name: 'ABreadcrumbSeparator', __ANT_BREADCRUMB_SEPARATOR: true, props: { @@ -22,4 +22,4 @@ export default { const children = getSlot(this); return {children || '/'}; }, -}; +}); diff --git a/components/breadcrumb/index.js b/components/breadcrumb/index.ts similarity index 86% rename from components/breadcrumb/index.js rename to components/breadcrumb/index.ts index e6cbb7beb..70feae09b 100644 --- a/components/breadcrumb/index.js +++ b/components/breadcrumb/index.ts @@ -1,3 +1,4 @@ +import { App } from 'vue'; import Breadcrumb from './Breadcrumb'; import BreadcrumbItem from './BreadcrumbItem'; import BreadcrumbSeparator from './BreadcrumbSeparator'; @@ -6,7 +7,7 @@ Breadcrumb.Item = BreadcrumbItem; Breadcrumb.Separator = BreadcrumbSeparator; /* istanbul ignore next */ -Breadcrumb.install = function(app) { +Breadcrumb.install = function(app: App) { app.component(Breadcrumb.name, Breadcrumb); app.component(BreadcrumbItem.name, BreadcrumbItem); app.component(BreadcrumbSeparator.name, BreadcrumbSeparator); diff --git a/components/breadcrumb/style/index.js b/components/breadcrumb/style/index.ts similarity index 100% rename from components/breadcrumb/style/index.js rename to components/breadcrumb/style/index.ts diff --git a/components/button/button-group.jsx b/components/button/button-group.tsx similarity index 86% rename from components/button/button-group.jsx rename to components/button/button-group.tsx index 93cc12ed0..842be3c2d 100644 --- a/components/button/button-group.jsx +++ b/components/button/button-group.tsx @@ -1,18 +1,15 @@ -import { inject } from 'vue'; +import { defineComponent, inject } from 'vue'; import { filterEmpty, getSlot } from '../_util/props-util'; import PropTypes from '../_util/vue-types'; import { defaultConfigProvider } from '../config-provider'; +import { tuple } from '../_util/type'; const ButtonGroupProps = { prefixCls: PropTypes.string, - size: { - validator(value) { - return ['small', 'large', 'default'].includes(value); - }, - }, + size: PropTypes.oneOf(tuple('small', 'large', 'default')), }; export { ButtonGroupProps }; -export default { +export default defineComponent({ name: 'AButtonGroup', props: ButtonGroupProps, setup() { @@ -53,4 +50,4 @@ export default { }; return
{filterEmpty(getSlot(this))}
; }, -}; +}); diff --git a/components/button/button.jsx b/components/button/button.tsx similarity index 91% rename from components/button/button.jsx rename to components/button/button.tsx index f03357cd0..8d0293904 100644 --- a/components/button/button.jsx +++ b/components/button/button.tsx @@ -1,4 +1,4 @@ -import { inject, Text } from 'vue'; +import { defineComponent, inject, Text, VNode } from 'vue'; import Wave from '../_util/wave'; import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined'; import buttonTypes from './buttonTypes'; @@ -8,7 +8,7 @@ import { defaultConfigProvider } from '../config-provider'; const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/; const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar); const props = buttonTypes(); -export default { +export default defineComponent({ name: 'AButton', inheritAttrs: false, __ANT_BUTTON: true, @@ -16,11 +16,12 @@ export default { setup() { return { configProvider: inject('configProvider', defaultConfigProvider), + children: [], + iconCom: undefined, + delayTimeout: undefined }; }, data() { - this.children = []; - this.iconCom = undefined; return { sizeMap: { large: 'lg', @@ -67,7 +68,7 @@ export default { ghost, block, $attrs, - } = this; + } = this const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('btn', customizePrefixCls); const autoInsertSpace = this.configProvider.autoInsertSpaceInButton !== false; @@ -87,7 +88,7 @@ export default { } const iconType = sLoading ? 'loading' : this.iconCom; return { - [$attrs.class]: $attrs.class, + [$attrs.class as string]: $attrs.class, [`${prefixCls}`]: true, [`${prefixCls}-${type}`]: type, [`${prefixCls}-${shape}`]: shape, @@ -101,7 +102,7 @@ export default { }, fixTwoCNChar() { // Fix for HOC usage like - const node = this.$refs.buttonNode; + const node = this.$refs.buttonNode as HTMLElement; if (!node) { return; } @@ -114,17 +115,17 @@ export default { this.hasTwoCNChar = false; } }, - handleClick(event) { + handleClick(event: Event) { const { sLoading } = this.$data; if (sLoading) { return; } this.$emit('click', event); }, - insertSpace(child, needInserted) { + insertSpace(child: VNode, needInserted: boolean) { const SPACE = needInserted ? ' ' : ''; if (child.type === Text) { - let text = child.children.trim(); + let text = (child.children as string).trim(); if (isTwoCNChar(text)) { text = text.split('').join(SPACE); } @@ -179,4 +180,4 @@ export default { return {buttonNode}; }, -}; +}); diff --git a/components/button/buttonTypes.js b/components/button/buttonTypes.js deleted file mode 100644 index 0b244a663..000000000 --- a/components/button/buttonTypes.js +++ /dev/null @@ -1,15 +0,0 @@ -import PropTypes, { withUndefined } from '../_util/vue-types'; -export default () => ({ - prefixCls: PropTypes.string, - type: PropTypes.string, - htmlType: PropTypes.oneOf(['button', 'submit', 'reset']).def('button'), - // icon: PropTypes.string, - shape: PropTypes.oneOf(['circle', 'circle-outline', 'round']), - size: PropTypes.oneOf(['small', 'large', 'default']).def('default'), - loading: withUndefined(PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object])), - disabled: PropTypes.looseBool, - ghost: PropTypes.looseBool, - block: PropTypes.looseBool, - icon: PropTypes.any, - onClick: PropTypes.func, -}); diff --git a/components/button/buttonTypes.ts b/components/button/buttonTypes.ts new file mode 100644 index 000000000..a134fbb79 --- /dev/null +++ b/components/button/buttonTypes.ts @@ -0,0 +1,26 @@ +import { tuple } from '../_util/type'; +import PropTypes, { withUndefined } from '../_util/vue-types'; + +const ButtonTypes = tuple('default', 'primary', 'ghost', 'dashed', 'danger', 'link'); +export type ButtonType = typeof ButtonTypes[number]; +const ButtonShapes = tuple('circle', 'circle-outline', 'round'); +export type ButtonShape = typeof ButtonShapes[number]; +const ButtonSizes = tuple('large', 'default', 'small'); +export type ButtonSize = typeof ButtonSizes[number]; +const ButtonHTMLTypes = tuple('submit', 'button', 'reset'); +export type ButtonHTMLType = typeof ButtonHTMLTypes[number]; + +export default () => ({ + prefixCls: PropTypes.string, + type: PropTypes.oneOf(ButtonTypes), + htmlType: PropTypes.oneOf(ButtonHTMLTypes).def('button'), + // icon: PropTypes.string, + shape: PropTypes.oneOf(ButtonShapes), + size: PropTypes.oneOf(ButtonSizes).def('default'), + loading: withUndefined(PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object])), + disabled: PropTypes.looseBool, + ghost: PropTypes.looseBool, + block: PropTypes.looseBool, + icon: PropTypes.VNodeChild, + onClick: PropTypes.func, +}); diff --git a/components/button/index.js b/components/button/index.ts similarity index 78% rename from components/button/index.js rename to components/button/index.ts index 61e788a94..8269c17fe 100644 --- a/components/button/index.js +++ b/components/button/index.ts @@ -1,10 +1,11 @@ +import { App } from 'vue'; import Button from './button'; import ButtonGroup from './button-group'; Button.Group = ButtonGroup; /* istanbul ignore next */ -Button.install = function(app) { +Button.install = function(app: App) { app.component(Button.name, Button); app.component(ButtonGroup.name, ButtonGroup); }; diff --git a/components/button/style/index.js b/components/button/style/index.ts similarity index 100% rename from components/button/style/index.js rename to components/button/style/index.ts diff --git a/components/config-provider/index.tsx b/components/config-provider/index.tsx index c928732ba..6e9c2c728 100644 --- a/components/config-provider/index.tsx +++ b/components/config-provider/index.tsx @@ -142,7 +142,7 @@ const ConfigProvider = defineComponent({ const renderProvider = (legacyLocale: Locale) => { return ( - + {slots.default?.()} ); diff --git a/components/dropdown/dropdown.jsx b/components/dropdown/dropdown.jsx index 561eb4af7..4c10e1bfe 100644 --- a/components/dropdown/dropdown.jsx +++ b/components/dropdown/dropdown.jsx @@ -1,4 +1,4 @@ -import { provide, inject, cloneVNode } from 'vue'; +import { provide, inject, cloneVNode, defineComponent } from 'vue'; import RcDropdown from '../vc-dropdown/src/index'; import DropdownButton from './dropdown-button'; import PropTypes from '../_util/vue-types'; @@ -16,7 +16,7 @@ import { defaultConfigProvider } from '../config-provider'; import RightOutlined from '@ant-design/icons-vue/RightOutlined'; const DropdownProps = getDropdownProps(); -const Dropdown = { +const Dropdown = defineComponent({ name: 'ADropdown', inheritAttrs: false, props: { @@ -107,7 +107,7 @@ const Dropdown = { }; return {dropdownTrigger}; }, -}; +}); Dropdown.Button = DropdownButton; export default Dropdown; diff --git a/components/locale-provider/index.tsx b/components/locale-provider/index.tsx index 1fdb8ffba..cd7b90962 100644 --- a/components/locale-provider/index.tsx +++ b/components/locale-provider/index.tsx @@ -22,7 +22,7 @@ export interface Locale { export interface LocaleProviderProps { locale: Locale; children?: VNode | VNode[]; - _ANT_MARK__?: string; + ANT_MARK__?: string; } export const ANT_MARK = 'internalMark'; @@ -41,11 +41,11 @@ const LocaleProvider = defineComponent({ locale: { type: Object, }, - _ANT_MARK__: PropTypes.string, + ANT_MARK__: PropTypes.string, }, data() { warning( - this._ANT_MARK__ === ANT_MARK, + this.ANT_MARK__ === ANT_MARK, 'LocaleProvider', '`LocaleProvider` is deprecated. Please use `locale` with `ConfigProvider` instead', ); @@ -58,7 +58,7 @@ const LocaleProvider = defineComponent({ }, setup(props) { warning( - props._ANT_MARK__ === ANT_MARK, + props.ANT_MARK__ === ANT_MARK, 'LocaleProvider', '`LocaleProvider` is deprecated. Please use `locale` with `ConfigProvider` instead', ); @@ -67,7 +67,7 @@ const LocaleProvider = defineComponent({ ...props.locale, exist: true, }, - _ANT_MARK__: ANT_MARK, + ANT_MARK__: ANT_MARK, }; provide('localeData', data); return data; diff --git a/components/menu/MenuItem.jsx b/components/menu/MenuItem.jsx index 275c200f6..96ddaad5d 100644 --- a/components/menu/MenuItem.jsx +++ b/components/menu/MenuItem.jsx @@ -1,9 +1,9 @@ -import { inject } from 'vue'; +import { defineComponent, inject } from 'vue'; import { Item, itemProps } from '../vc-menu'; import { getOptionProps, getSlot } from '../_util/props-util'; import Tooltip from '../tooltip'; function noop() {} -export default { +export default defineComponent({ name: 'MenuItem', inheritAttrs: false, props: itemProps, @@ -56,4 +56,4 @@ export default { const item = {children}; return {item}; }, -}; +}); diff --git a/components/menu/index.jsx b/components/menu/index.jsx index 0cc515f32..647947fa7 100644 --- a/components/menu/index.jsx +++ b/components/menu/index.jsx @@ -1,4 +1,4 @@ -import { inject, provide, toRef } from 'vue'; +import { defineComponent, inject, provide, toRef } from 'vue'; import omit from 'omit.js'; import VcMenu, { Divider, ItemGroup } from '../vc-menu'; import SubMenu from './SubMenu'; @@ -47,7 +47,7 @@ export const menuProps = { 'onUpdate:openKeys': PropTypes.func, }; -const Menu = { +const Menu = defineComponent({ name: 'AMenu', inheritAttrs: false, props: menuProps, @@ -294,7 +294,7 @@ const Menu = { return ; }, -}; +}); /* istanbul ignore next */ Menu.install = function(app) {