[improvement] ContactList: tsx (#2794)

This commit is contained in:
neverland 2019-02-19 14:30:30 +08:00 committed by GitHub
parent c55b33f447
commit 8c6ab91f6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 24 deletions

View File

@ -9,7 +9,8 @@ import { CreateElement, RenderContext } from 'vue/types';
import { ScopedSlot, DefaultSlots } from '../utils/use/sfc'; import { ScopedSlot, DefaultSlots } from '../utils/use/sfc';
import { Mods } from '../utils/use/bem'; import { Mods } from '../utils/use/bem';
export type CellProps = RouteProps & SharedCellProps & { export type CellProps = RouteProps &
SharedCellProps & {
size?: string; size?: string;
clickable?: boolean; clickable?: boolean;
arrowDirection?: string; arrowDirection?: string;
@ -106,4 +107,4 @@ Cell.props = {
arrowDirection: String arrowDirection: String
}; };
export default sfc<CellProps, CellEvents>(Cell); export default sfc<CellProps, CellEvents, CellSlots>(Cell);

View File

@ -130,7 +130,6 @@ export default {
/> />
``` ```
### ContactCard API ### ContactCard API
| 参数 | 说明 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
@ -187,4 +186,4 @@ export default {
|------|------|------| |------|------|------|
| id | 每位联系人的唯一标识 | `String | Number` | | id | 每位联系人的唯一标识 | `String | Number` |
| name | 联系人姓名 | `String` | | name | 联系人姓名 | `String` |
| tel | 联系人手机号 | `String` | | tel | 联系人手机号 | `String | Number` |

View File

@ -1,4 +1,4 @@
import { use, noop } from '../utils'; import { use } from '../utils';
import { emit, inherit } from '../utils/functional'; import { emit, inherit } from '../utils/functional';
import Icon from '../icon'; import Icon from '../icon';
import Cell from '../cell'; import Cell from '../cell';
@ -6,9 +6,30 @@ import Button from '../button';
import Radio from '../radio'; import Radio from '../radio';
import RadioGroup from '../radio-group'; import RadioGroup from '../radio-group';
// Types
import { CreateElement, RenderContext } from 'vue/types';
import { DefaultSlots } from '../utils/use/sfc';
export type ContactListItem = {
id: string | number;
tel: string | number;
name: string;
};
export type ContactListProps = {
value?: any;
list: ContactListItem[];
addText?: string;
};
const [sfc, bem, t] = use('contact-list'); const [sfc, bem, t] = use('contact-list');
function ContactList(h, props, slots, ctx) { function ContactList(
h: CreateElement,
props: ContactListProps,
slots: DefaultSlots,
ctx: RenderContext<ContactListProps>
) {
const List = props.list.map((item, index) => ( const List = props.list.map((item, index) => (
<Cell <Cell
key={item.id} key={item.id}
@ -50,14 +71,16 @@ function ContactList(h, props, slots, ctx) {
type="danger" type="danger"
class={bem('add')} class={bem('add')}
text={props.addText || t('addText')} text={props.addText || t('addText')}
onClick={ctx.listeners.add || noop} onClick={() => {
emit(ctx, 'add');
}}
/> />
</div> </div>
); );
} }
ContactList.props = { ContactList.props = {
value: null, value: null as any,
list: Array, list: Array,
addText: String addText: String
}; };

View File

@ -13,7 +13,7 @@ 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> = (props?: Props) => VNode[] | undefined; export type ScopedSlot<Props = any> = (props?: Props) => VNode[] | VNode | undefined;
export type DefaultSlots = { export type DefaultSlots = {
default?: ScopedSlot; default?: ScopedSlot;
@ -35,8 +35,6 @@ export interface VantComponentOptions extends ComponentOptions<Vue> {
export type DefaultProps = Record<string, any>; export type DefaultProps = Record<string, any>;
export type DefaultEvents = {};
export type FunctionalComponent< export type FunctionalComponent<
Props = DefaultProps, Props = DefaultProps,
PropDefs = PropsDefinition<Props> PropDefs = PropsDefinition<Props>
@ -52,18 +50,17 @@ export type FunctionalComponent<
inject?: InjectOptions; inject?: InjectOptions;
}; };
export type TsxBaseProps = { export type TsxBaseProps<Slots> = {
key: string | number; key: string | number;
// hack for jsx prop spread // hack for jsx prop spread
props: any; props: any;
class: any; class: any;
style: { style: object[] | object;
[key: string]: string | number; scopedSlots: Slots;
};
}; };
export type TsxComponent<Props, Events> = ( export type TsxComponent<Props, Events, Slots> = (
props: Partial<Props & Events & TsxBaseProps> props: Partial<Props & Events & TsxBaseProps<Slots>>
) => VNode; ) => VNode;
const arrayProp = { const arrayProp = {
@ -120,9 +117,9 @@ function transformFunctionalComponent(
}; };
} }
export default (name: string) => <Props = DefaultProps, Events = DefaultEvents>( export default (name: string) => <Props = DefaultProps, Events = {}, Slots = {}>(
sfc: VantComponentOptions | FunctionalComponent sfc: VantComponentOptions | FunctionalComponent
): TsxComponent<Props, Events> => { ): TsxComponent<Props, Events, Slots> => {
if (typeof sfc === 'function') { if (typeof sfc === 'function') {
sfc = transformFunctionalComponent(sfc); sfc = transformFunctionalComponent(sfc);
} }
@ -139,5 +136,5 @@ export default (name: string) => <Props = DefaultProps, Events = DefaultEvents>(
sfc.name = name; sfc.name = name;
sfc.install = install; sfc.install = install;
return sfc as TsxComponent<Props, Events>; return sfc as TsxComponent<Props, Events, Slots>;
}; };