[improvement] optimize sfc type definitions (#2778)

This commit is contained in:
neverland 2019-02-18 17:34:32 +08:00 committed by GitHub
parent 0013185d38
commit 78174e4550
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 131 additions and 97 deletions

View File

@ -4,15 +4,32 @@ import { routeProps, RouteProps, functionalRoute } from '../mixins/router';
import Loading from '../loading'; import Loading from '../loading';
// Types // Types
import { FunctionalComponent } from '../utils/use/sfc'; import { CreateElement, RenderContext } from 'vue/types';
import { DefaultSlots } from '../utils/use/sfc';
export type ButtonProps = RouteProps & {
tag?: string;
type?: string;
size?: string;
text?: string;
block?: boolean;
plain?: boolean;
round?: boolean;
square?: boolean;
loading?: boolean;
disabled?: boolean;
nativeType?: string;
loadingText?: string;
bottomAction?: boolean;
};
const [sfc, bem] = use('button'); const [sfc, bem] = use('button');
const Button: FunctionalComponent<ButtonProps> = function ( function Button(
h, h: CreateElement,
props, props: ButtonProps,
slots, slots: DefaultSlots,
ctx ctx: RenderContext<ButtonProps>
) { ) {
const { tag, type, disabled, loading, loadingText } = props; const { tag, type, disabled, loading, loadingText } = props;
@ -55,23 +72,7 @@ const Button: FunctionalComponent<ButtonProps> = function (
)} )}
</tag> </tag>
); );
}; }
export type ButtonProps = RouteProps & {
tag?: string;
type?: string;
size?: string;
text?: string;
block?: boolean;
plain?: boolean;
round?: boolean;
square?: boolean;
loading?: boolean;
disabled?: boolean;
nativeType?: string;
loadingText?: string;
bottomAction?: boolean;
};
Button.props = { Button.props = {
...routeProps, ...routeProps,

View File

@ -2,15 +2,20 @@ import { use } from '../utils';
import { inherit } from '../utils/functional'; import { inherit } from '../utils/functional';
// Types // Types
import { FunctionalComponent } from '../utils/use/sfc'; import { CreateElement, RenderContext } from 'vue/types';
import { DefaultSlots } from '../utils/use/sfc';
export type CellGroupProps = {
border?: boolean
};
const [sfc, bem] = use('cell-group'); const [sfc, bem] = use('cell-group');
const CellGroup: FunctionalComponent<CellGroupProps> = function ( function CellGroup(
h, h: CreateElement,
props, props: CellGroupProps,
slots, slots: DefaultSlots,
ctx ctx: RenderContext<CellGroupProps>
) { ) {
return ( return (
<div <div
@ -20,11 +25,7 @@ const CellGroup: FunctionalComponent<CellGroupProps> = function (
{slots.default && slots.default()} {slots.default && slots.default()}
</div> </div>
); );
}; }
export type CellGroupProps = {
border?: boolean
};
CellGroup.props = { CellGroup.props = {
border: { border: {

View File

@ -5,12 +5,31 @@ import { routeProps, functionalRoute } from '../mixins/router';
import Icon from '../icon'; import Icon from '../icon';
// Types // Types
import { FunctionalComponent } from '../utils/use/sfc'; import { CreateElement, RenderContext } from 'vue/types';
import { ScopedSlot, DefaultSlots } from '../utils/use/sfc';
import { Mods } from '../utils/use/bem'; import { Mods } from '../utils/use/bem';
export type CellProps = SharedCellProps & {
size?: string;
clickable?: boolean;
arrowDirection?: string;
};
export type CellSlots = DefaultSlots & {
icon?: ScopedSlot;
title?: ScopedSlot;
extra?: ScopedSlot;
'right-icon'?: ScopedSlot;
};
const [sfc, bem] = use('cell'); const [sfc, bem] = use('cell');
const Cell: FunctionalComponent<CellProps> = function (h, props, slots, ctx) { function Cell(
h: CreateElement,
props: CellProps,
slots: CellSlots,
ctx: RenderContext<CellProps>
) {
const { icon, size, title, label, value, isLink, arrowDirection } = props; const { icon, size, title, label, value, isLink, arrowDirection } = props;
const showTitle = slots.title || isDef(title); const showTitle = slots.title || isDef(title);
@ -65,11 +84,7 @@ const Cell: FunctionalComponent<CellProps> = function (h, props, slots, ctx) {
} }
return ( return (
<div <div class={bem(classes)} onClick={onClick} {...inherit(ctx)}>
class={bem(classes)}
onClick={onClick}
{...inherit(ctx)}
>
{LeftIcon} {LeftIcon}
{Title} {Title}
{Value} {Value}
@ -77,12 +92,6 @@ const Cell: FunctionalComponent<CellProps> = function (h, props, slots, ctx) {
{slots.extra && slots.extra()} {slots.extra && slots.extra()}
</div> </div>
); );
};
export type CellProps = SharedCellProps & {
size?: string;
clickable?: boolean;
arrowDirection?: string;
} }
Cell.props = { Cell.props = {

View File

@ -4,11 +4,25 @@ import Info from '../info';
import isSrc from '../utils/validate/src'; import isSrc from '../utils/validate/src';
// Types // Types
import { FunctionalComponent } from '../utils/use/sfc'; import { CreateElement, RenderContext } from 'vue/types';
import { DefaultSlots } from '../utils/use/sfc';
export type IconProps = {
name: string;
size?: string;
color?: string;
info?: string | number;
classPrefix?: string;
};
const [sfc] = use('icon'); const [sfc] = use('icon');
const Icon: FunctionalComponent<IconProps> = function (h, props, slots, ctx) { function Icon(
h: CreateElement,
props: IconProps,
slots: DefaultSlots,
ctx: RenderContext<IconProps>
) {
const urlIcon = isSrc(props.name); const urlIcon = isSrc(props.name);
return ( return (
@ -28,15 +42,7 @@ const Icon: FunctionalComponent<IconProps> = function (h, props, slots, ctx) {
<Info info={props.info} /> <Info info={props.info} />
</i> </i>
); );
}; }
export type IconProps = {
name: string;
size?: string;
color?: string;
info?: string | number;
classPrefix?: string;
};
Icon.props = { Icon.props = {
name: String, name: String,

View File

@ -2,11 +2,21 @@ import { use, isDef } from '../utils';
import { inherit } from '../utils/functional'; import { inherit } from '../utils/functional';
// Types // Types
import { FunctionalComponent } from '../utils/use/sfc'; import { CreateElement, RenderContext } from 'vue/types';
import { DefaultSlots } from '../utils/use/sfc';
export type InfoProps = {
info?: string | number;
};
const [sfc, bem] = use('info'); const [sfc, bem] = use('info');
const Info: FunctionalComponent<InfoProps> = function (h, props, slots, ctx) { function Info(
h: CreateElement,
props: InfoProps,
slots: DefaultSlots,
ctx: RenderContext<InfoProps>
) {
if (!isDef(props.info)) { if (!isDef(props.info)) {
return; return;
} }
@ -16,11 +26,7 @@ const Info: FunctionalComponent<InfoProps> = function (h, props, slots, ctx) {
{props.info} {props.info}
</div> </div>
); );
}; }
export type InfoProps = {
info?: string | number;
};
Info.props = { Info.props = {
info: [String, Number] info: [String, Number]

View File

@ -2,16 +2,23 @@ import { use } from '../utils';
import { inherit } from '../utils/functional'; import { inherit } from '../utils/functional';
// Types // Types
import { FunctionalComponent } from '../utils/use/sfc'; import { CreateElement, RenderContext } from 'vue/types';
import { DefaultSlots } from '../utils/use/sfc';
export type LoadingProps = {
size?: string;
type?: string;
color?: string;
};
const [sfc, bem] = use('loading'); const [sfc, bem] = use('loading');
const DEFAULT_COLOR = '#c9c9c9'; const DEFAULT_COLOR = '#c9c9c9';
const Loading: FunctionalComponent<LoadingProps> = function ( function Loading(
h, h: CreateElement,
props, props: LoadingProps,
slots, slots: DefaultSlots,
ctx ctx: RenderContext<LoadingProps>
) { ) {
const { color, size, type } = props; const { color, size, type } = props;
@ -44,13 +51,7 @@ const Loading: FunctionalComponent<LoadingProps> = function (
</span> </span>
</div> </div>
); );
}; }
export type LoadingProps = {
size?: string;
type?: string;
color?: string;
};
Loading.props = { Loading.props = {
size: String, size: String,

View File

@ -3,7 +3,18 @@ import { inherit } from '../utils/functional';
import { RED, BLUE, GREEN, GRAY_DARK } from '../utils/color'; import { RED, BLUE, GREEN, GRAY_DARK } from '../utils/color';
// Types // Types
import { FunctionalComponent } from '../utils/use/sfc'; import { CreateElement, RenderContext } from 'vue/types';
import { DefaultSlots } from '../utils/use/sfc';
export type TagProps = {
size?: string;
type?: string;
mark?: boolean;
color?: string;
plain?: boolean;
round?: boolean;
textColor?: string;
};
const [sfc, bem] = use('tag'); const [sfc, bem] = use('tag');
@ -13,8 +24,13 @@ const COLOR_MAP: { [key: string]: string } = {
success: GREEN success: GREEN
}; };
const Tag: FunctionalComponent<TagProps> = function (h, props, slots, ctx) { function Tag(
const { type, mark, plain, round, size } = ctx.props; h: CreateElement,
props: TagProps,
slots: DefaultSlots,
ctx: RenderContext<TagProps>
) {
const { type, mark, plain, round, size } = props;
const color = props.color || (type && COLOR_MAP[type]) || GRAY_DARK; const color = props.color || (type && COLOR_MAP[type]) || GRAY_DARK;
const key = plain ? 'color' : 'backgroundColor'; const key = plain ? 'color' : 'backgroundColor';
@ -43,17 +59,7 @@ const Tag: FunctionalComponent<TagProps> = function (h, props, slots, ctx) {
{slots.default && slots.default()} {slots.default && slots.default()}
</span> </span>
); );
}; }
export type TagProps = {
size?: string;
type?: string;
mark?: boolean;
color?: string;
plain?: boolean;
round?: boolean;
textColor?: string;
};
Tag.props = { Tag.props = {
size: String, size: String,

View File

@ -13,13 +13,16 @@ import Vue, {
import { VNode } from 'vue/types/vnode'; import { VNode } from 'vue/types/vnode';
import { InjectOptions, PropsDefinition } from 'vue/types/options'; import { InjectOptions, PropsDefinition } from 'vue/types/options';
export type ScopedSlot = (props?: any) => VNode[] | undefined; export type ScopedSlot<Props = any> = (props?: Props) => VNode[] | undefined;
export type ScopedSlots = { export type DefaultSlots = {
[key: string]: ScopedSlot | undefined;
default?: ScopedSlot; default?: ScopedSlot;
}; };
export type ScopedSlots = DefaultSlots & {
[key: string]: ScopedSlot | undefined;
};
export type ModelOptions = { export type ModelOptions = {
prop?: string; prop?: string;
event?: string; event?: string;
@ -50,7 +53,7 @@ export type FunctionalComponent<
export type TsxBaseProps = { export type TsxBaseProps = {
class?: any; class?: any;
style?: any; style?: any;
} };
export type TsxComponent<T> = (props: T & TsxBaseProps) => VNode; export type TsxComponent<T> = (props: T & TsxBaseProps) => VNode;
const arrayProp = { const arrayProp = {
@ -102,7 +105,8 @@ function transformFunctionalComponent(
functional: true, functional: true,
props: pure.props, props: pure.props,
model: pure.model, model: pure.model,
render: (h, context): any => pure(h, context.props, unifySlots(context), context) render: (h, context): any =>
pure(h, context.props, unifySlots(context), context)
}; };
} }