mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-23 18:00:27 +08:00
[improvement] Functional components be just functions (#2735)
This commit is contained in:
parent
166397dad4
commit
5a9143c736
@ -4,10 +4,50 @@ import Loading from '../loading';
|
|||||||
|
|
||||||
const [sfc, bem] = use('button');
|
const [sfc, bem] = use('button');
|
||||||
|
|
||||||
export default sfc({
|
function Button(h, props, slots, ctx) {
|
||||||
functional: true,
|
const { type, disabled, loading, loadingText } = props;
|
||||||
|
|
||||||
props: {
|
const onClick = event => {
|
||||||
|
if (!loading && !disabled) {
|
||||||
|
emit(ctx, 'click', event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<props.tag
|
||||||
|
type={props.nativeType}
|
||||||
|
disabled={disabled}
|
||||||
|
class={bem([
|
||||||
|
type,
|
||||||
|
props.size,
|
||||||
|
{
|
||||||
|
loading,
|
||||||
|
disabled,
|
||||||
|
block: props.block,
|
||||||
|
plain: props.plain,
|
||||||
|
round: props.round,
|
||||||
|
square: props.square,
|
||||||
|
'bottom-action': props.bottomAction
|
||||||
|
}
|
||||||
|
])}
|
||||||
|
onClick={onClick}
|
||||||
|
{...inherit(ctx)}
|
||||||
|
>
|
||||||
|
{loading ? (
|
||||||
|
[
|
||||||
|
<Loading size="20px" color={type === 'default' ? undefined : ''} />,
|
||||||
|
loadingText && <span class={bem('loading-text')}>{loadingText}</span>
|
||||||
|
]
|
||||||
|
) : (
|
||||||
|
<span class={bem('text')}>
|
||||||
|
{slots.default ? slots.default() : props.text}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</props.tag>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Button.props = {
|
||||||
text: String,
|
text: String,
|
||||||
block: Boolean,
|
block: Boolean,
|
||||||
plain: Boolean,
|
plain: Boolean,
|
||||||
@ -30,49 +70,6 @@ export default sfc({
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'normal'
|
default: 'normal'
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
render(h, context) {
|
export default sfc(Button);
|
||||||
const { props } = context;
|
|
||||||
const { type, disabled, loading, loadingText } = props;
|
|
||||||
|
|
||||||
const onClick = event => {
|
|
||||||
if (!loading && !disabled) {
|
|
||||||
emit(context, 'click', event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<props.tag
|
|
||||||
type={props.nativeType}
|
|
||||||
disabled={disabled}
|
|
||||||
class={bem([
|
|
||||||
type,
|
|
||||||
props.size,
|
|
||||||
{
|
|
||||||
loading,
|
|
||||||
disabled,
|
|
||||||
block: props.block,
|
|
||||||
plain: props.plain,
|
|
||||||
round: props.round,
|
|
||||||
square: props.square,
|
|
||||||
'bottom-action': props.bottomAction
|
|
||||||
}
|
|
||||||
])}
|
|
||||||
onClick={onClick}
|
|
||||||
{...inherit(context)}
|
|
||||||
>
|
|
||||||
{loading ? (
|
|
||||||
[
|
|
||||||
<Loading size="20px" color={type === 'default' ? undefined : ''} />,
|
|
||||||
loadingText && (
|
|
||||||
<span class={bem('loading-text')}>{loadingText}</span>
|
|
||||||
)
|
|
||||||
]
|
|
||||||
) : (
|
|
||||||
<span class={bem('text')}>{context.children || props.text}</span>
|
|
||||||
)}
|
|
||||||
</props.tag>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
@ -2,21 +2,22 @@ import { use } from '../utils';
|
|||||||
|
|
||||||
const [sfc, bem] = use('cell-group');
|
const [sfc, bem] = use('cell-group');
|
||||||
|
|
||||||
export default sfc({
|
function CellGroup(h, props, slots, ctx) {
|
||||||
functional: true,
|
return (
|
||||||
|
<div
|
||||||
|
class={[bem(), { 'van-hairline--top-bottom': props.border }]}
|
||||||
|
{...ctx.data}
|
||||||
|
>
|
||||||
|
{slots.default && slots.default()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
props: {
|
CellGroup.props = {
|
||||||
border: {
|
border: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
render(h, context) {
|
export default sfc(CellGroup);
|
||||||
return (
|
|
||||||
<div class={[bem(), { 'van-hairline--top-bottom': context.props.border }]} {...context.data}>
|
|
||||||
{context.children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
@ -1,25 +1,12 @@
|
|||||||
import { use, isDef } from '../utils';
|
import { use, isDef } from '../utils';
|
||||||
import { cellProps } from './shared';
|
import { cellProps } from './shared';
|
||||||
import { emit, inherit, unifySlots } from '../utils/functional';
|
import { emit, inherit } from '../utils/functional';
|
||||||
import { routeProps, functionalRoute } from '../mixins/router';
|
import { routeProps, functionalRoute } from '../mixins/router';
|
||||||
import Icon from '../icon';
|
import Icon from '../icon';
|
||||||
|
|
||||||
const [sfc, bem] = use('cell');
|
const [sfc, bem] = use('cell');
|
||||||
|
|
||||||
export default sfc({
|
function Cell(h, props, slots, ctx) {
|
||||||
functional: true,
|
|
||||||
|
|
||||||
props: {
|
|
||||||
...cellProps,
|
|
||||||
...routeProps,
|
|
||||||
size: String,
|
|
||||||
clickable: Boolean,
|
|
||||||
arrowDirection: String
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
const slots = unifySlots(context);
|
|
||||||
const { props } = context;
|
|
||||||
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);
|
||||||
@ -57,8 +44,8 @@ export default sfc({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const onClick = event => {
|
const onClick = event => {
|
||||||
emit(context, 'click', event);
|
emit(ctx, 'click', event);
|
||||||
functionalRoute(context);
|
functionalRoute(ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -71,7 +58,7 @@ export default sfc({
|
|||||||
[size]: size
|
[size]: size
|
||||||
})}
|
})}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
{...inherit(context)}
|
{...inherit(ctx)}
|
||||||
>
|
>
|
||||||
{LeftIcon}
|
{LeftIcon}
|
||||||
{Title}
|
{Title}
|
||||||
@ -80,5 +67,14 @@ export default sfc({
|
|||||||
{slots.extra && slots.extra()}
|
{slots.extra && slots.extra()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
Cell.props = {
|
||||||
|
...cellProps,
|
||||||
|
...routeProps,
|
||||||
|
size: String,
|
||||||
|
clickable: Boolean,
|
||||||
|
arrowDirection: String
|
||||||
|
};
|
||||||
|
|
||||||
|
export default sfc(Cell);
|
||||||
|
@ -4,25 +4,7 @@ import Cell from '../cell';
|
|||||||
|
|
||||||
const [sfc, bem, t] = use('contact-card');
|
const [sfc, bem, t] = use('contact-card');
|
||||||
|
|
||||||
export default sfc({
|
function ContactCard(h, props, slots, ctx) {
|
||||||
functional: true,
|
|
||||||
|
|
||||||
props: {
|
|
||||||
tel: String,
|
|
||||||
name: String,
|
|
||||||
addText: String,
|
|
||||||
editable: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: 'add'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
const { props } = context;
|
|
||||||
const { type, editable } = props;
|
const { type, editable } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -35,15 +17,33 @@ export default sfc({
|
|||||||
icon={type === 'edit' ? 'contact' : 'add-square'}
|
icon={type === 'edit' ? 'contact' : 'add-square'}
|
||||||
onClick={event => {
|
onClick={event => {
|
||||||
if (editable) {
|
if (editable) {
|
||||||
emit(context, 'click', event);
|
emit(ctx, 'click', event);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
{...inherit(context)}
|
{...inherit(ctx)}
|
||||||
>
|
>
|
||||||
{type === 'add'
|
{type === 'add'
|
||||||
? props.addText || t('addText')
|
? props.addText || t('addText')
|
||||||
: [<div>{`${t('name')}:${props.name}`}</div>, <div>{`${t('tel')}:${props.tel}`}</div>]}
|
: [
|
||||||
|
<div>{`${t('name')}:${props.name}`}</div>,
|
||||||
|
<div>{`${t('tel')}:${props.tel}`}</div>
|
||||||
|
]}
|
||||||
</Cell>
|
</Cell>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ContactCard.props = {
|
||||||
|
tel: String,
|
||||||
|
name: String,
|
||||||
|
addText: String,
|
||||||
|
editable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'add'
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
export default sfc(ContactCard);
|
||||||
|
@ -8,18 +8,7 @@ import RadioGroup from '../radio-group';
|
|||||||
|
|
||||||
const [sfc, bem, t] = use('contact-list');
|
const [sfc, bem, t] = use('contact-list');
|
||||||
|
|
||||||
export default sfc({
|
function ContactList(h, props, slots, ctx) {
|
||||||
functional: true,
|
|
||||||
|
|
||||||
props: {
|
|
||||||
value: null,
|
|
||||||
list: Array,
|
|
||||||
addText: String
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
const { props, listeners } = context;
|
|
||||||
|
|
||||||
const List = props.list.map((item, index) => (
|
const List = props.list.map((item, index) => (
|
||||||
<Cell
|
<Cell
|
||||||
key={item.id}
|
key={item.id}
|
||||||
@ -38,20 +27,20 @@ export default sfc({
|
|||||||
class={bem('edit')}
|
class={bem('edit')}
|
||||||
onClick={event => {
|
onClick={event => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
emit(context, 'edit', item, index);
|
emit(ctx, 'edit', item, index);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
emit(context, 'input', item.id);
|
emit(ctx, 'input', item.id);
|
||||||
emit(context, 'select', item, index);
|
emit(ctx, 'select', item, index);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={bem()} {...inherit(context)}>
|
<div class={bem()} {...inherit(ctx)}>
|
||||||
<RadioGroup value={props.value} class={bem('group')}>
|
<RadioGroup value={props.value} class={bem('group')}>
|
||||||
{List}
|
{List}
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
@ -61,9 +50,16 @@ export default sfc({
|
|||||||
type="danger"
|
type="danger"
|
||||||
class={bem('add')}
|
class={bem('add')}
|
||||||
text={props.addText || t('addText')}
|
text={props.addText || t('addText')}
|
||||||
onClick={listeners.add || noop}
|
onClick={ctx.listeners.add || noop}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
ContactList.props = {
|
||||||
|
value: null,
|
||||||
|
list: Array,
|
||||||
|
addText: String
|
||||||
|
};
|
||||||
|
|
||||||
|
export default sfc(ContactList);
|
||||||
|
@ -1,28 +1,14 @@
|
|||||||
import { use } from '../utils';
|
import { use } from '../utils';
|
||||||
import Button from '../button';
|
import Button from '../button';
|
||||||
import { emit, inherit, unifySlots } from '../utils/functional';
|
import { emit, inherit } from '../utils/functional';
|
||||||
import { functionalRoute, routeProps } from '../mixins/router';
|
import { functionalRoute, routeProps } from '../mixins/router';
|
||||||
|
|
||||||
const [sfc, bem] = use('goods-action-big-btn');
|
const [sfc, bem] = use('goods-action-big-btn');
|
||||||
|
|
||||||
export default sfc({
|
function GoodsActionBigBtn(h, props, slots, ctx) {
|
||||||
functional: true,
|
|
||||||
|
|
||||||
props: {
|
|
||||||
...routeProps,
|
|
||||||
text: String,
|
|
||||||
primary: Boolean,
|
|
||||||
loading: Boolean,
|
|
||||||
disabled: Boolean
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
const { props } = context;
|
|
||||||
const slots = unifySlots(context);
|
|
||||||
|
|
||||||
const onClick = event => {
|
const onClick = event => {
|
||||||
emit(context, 'click', event);
|
emit(ctx, 'click', event);
|
||||||
functionalRoute(context);
|
functionalRoute(ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -34,10 +20,19 @@ export default sfc({
|
|||||||
disabled={props.disabled}
|
disabled={props.disabled}
|
||||||
type={props.primary ? 'danger' : 'warning'}
|
type={props.primary ? 'danger' : 'warning'}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
{...inherit(context)}
|
{...inherit(ctx)}
|
||||||
>
|
>
|
||||||
{slots.default ? slots.default() : props.text}
|
{slots.default ? slots.default() : props.text}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
GoodsActionBigBtn.props = {
|
||||||
|
...routeProps,
|
||||||
|
text: String,
|
||||||
|
primary: Boolean,
|
||||||
|
loading: Boolean,
|
||||||
|
disabled: Boolean
|
||||||
|
};
|
||||||
|
|
||||||
|
export default sfc(GoodsActionBigBtn);
|
||||||
|
@ -1,35 +1,21 @@
|
|||||||
import { use } from '../utils';
|
import { use } from '../utils';
|
||||||
import Icon from '../icon';
|
import Icon from '../icon';
|
||||||
import { emit, inherit, unifySlots } from '../utils/functional';
|
import { emit, inherit } from '../utils/functional';
|
||||||
import { functionalRoute, routeProps } from '../mixins/router';
|
import { functionalRoute, routeProps } from '../mixins/router';
|
||||||
|
|
||||||
const [sfc, bem] = use('goods-action-mini-btn');
|
const [sfc, bem] = use('goods-action-mini-btn');
|
||||||
|
|
||||||
export default sfc({
|
function GoodsActionMiniBtn(h, props, slots, ctx) {
|
||||||
functional: true,
|
|
||||||
|
|
||||||
props: {
|
|
||||||
...routeProps,
|
|
||||||
text: String,
|
|
||||||
icon: String,
|
|
||||||
info: [String, Number],
|
|
||||||
iconClass: String
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
const { props } = context;
|
|
||||||
const slots = unifySlots(context);
|
|
||||||
|
|
||||||
const onClick = event => {
|
const onClick = event => {
|
||||||
emit(context, 'click', event);
|
emit(ctx, 'click', event);
|
||||||
functionalRoute(context);
|
functionalRoute(ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
class={[bem(), 'van-hairline']}
|
class={[bem(), 'van-hairline']}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
{...inherit(context)}
|
{...inherit(ctx)}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
class={[bem('icon'), props.iconClass]}
|
class={[bem('icon'), props.iconClass]}
|
||||||
@ -39,5 +25,14 @@ export default sfc({
|
|||||||
{slots.default ? slots.default() : props.text}
|
{slots.default ? slots.default() : props.text}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
GoodsActionMiniBtn.props = {
|
||||||
|
...routeProps,
|
||||||
|
text: String,
|
||||||
|
icon: String,
|
||||||
|
info: [String, Number],
|
||||||
|
iconClass: String
|
||||||
|
};
|
||||||
|
|
||||||
|
export default sfc(GoodsActionMiniBtn);
|
||||||
|
@ -2,14 +2,12 @@ import { use } from '../utils';
|
|||||||
|
|
||||||
const [sfc, bem] = use('goods-action');
|
const [sfc, bem] = use('goods-action');
|
||||||
|
|
||||||
export default sfc({
|
function GoodsAction(h, props, slots, ctx) {
|
||||||
functional: true,
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
return (
|
return (
|
||||||
<div class={bem()} {...context.data}>
|
<div class={bem()} {...ctx.data}>
|
||||||
{context.children}
|
{slots.default && slots.default()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
export default sfc(GoodsAction);
|
||||||
|
@ -4,22 +4,7 @@ import isSrc from '../utils/validate/src';
|
|||||||
|
|
||||||
const [sfc] = use('icon');
|
const [sfc] = use('icon');
|
||||||
|
|
||||||
export default sfc({
|
function Icon(h, props, slots, ctx) {
|
||||||
functional: true,
|
|
||||||
|
|
||||||
props: {
|
|
||||||
name: String,
|
|
||||||
size: String,
|
|
||||||
color: String,
|
|
||||||
info: [String, Number],
|
|
||||||
classPrefix: {
|
|
||||||
type: String,
|
|
||||||
default: 'van-icon'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
const { props } = context;
|
|
||||||
const urlIcon = isSrc(props.name);
|
const urlIcon = isSrc(props.name);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -32,12 +17,24 @@ export default sfc({
|
|||||||
color: props.color,
|
color: props.color,
|
||||||
fontSize: props.size
|
fontSize: props.size
|
||||||
}}
|
}}
|
||||||
{...context.data}
|
{...ctx.data}
|
||||||
>
|
>
|
||||||
{context.children}
|
{ctx.default && ctx.default()}
|
||||||
{urlIcon && <img src={props.name} />}
|
{urlIcon && <img src={props.name} />}
|
||||||
<Info info={props.info} />
|
<Info info={props.info} />
|
||||||
</i>
|
</i>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Icon.props = {
|
||||||
|
name: String,
|
||||||
|
size: String,
|
||||||
|
color: String,
|
||||||
|
info: [String, Number],
|
||||||
|
classPrefix: {
|
||||||
|
type: String,
|
||||||
|
default: 'van-icon'
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
export default sfc(Icon);
|
||||||
|
@ -2,20 +2,18 @@ import { use, isDef } from '../utils';
|
|||||||
|
|
||||||
const [sfc, bem] = use('info');
|
const [sfc, bem] = use('info');
|
||||||
|
|
||||||
export default sfc({
|
function Info(h, props, slots, ctx) {
|
||||||
functional: true,
|
|
||||||
|
|
||||||
props: {
|
|
||||||
info: [String, Number]
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, { props, data }) {
|
|
||||||
return (
|
return (
|
||||||
isDef(props.info) && (
|
isDef(props.info) && (
|
||||||
<div class={bem()} {...data}>
|
<div class={bem()} {...ctx.data}>
|
||||||
{props.info}
|
{props.info}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
Info.props = {
|
||||||
|
info: [String, Number]
|
||||||
|
};
|
||||||
|
|
||||||
|
export default sfc(Info);
|
||||||
|
@ -3,23 +3,8 @@ import { use } from '../utils';
|
|||||||
const [sfc, bem] = use('loading');
|
const [sfc, bem] = use('loading');
|
||||||
const DEFAULT_COLOR = '#c9c9c9';
|
const DEFAULT_COLOR = '#c9c9c9';
|
||||||
|
|
||||||
export default sfc({
|
function Loading(h, props, slots, ctx) {
|
||||||
functional: true,
|
const { color, size, type } = props;
|
||||||
|
|
||||||
props: {
|
|
||||||
size: String,
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: 'circular'
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
type: String,
|
|
||||||
default: DEFAULT_COLOR
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
const { color, size, type } = context.props;
|
|
||||||
|
|
||||||
const colorType = color === 'white' || color === 'black' ? color : '';
|
const colorType = color === 'white' || color === 'black' ? color : '';
|
||||||
|
|
||||||
@ -43,12 +28,25 @@ export default sfc({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={bem([type, colorType])} style={style} {...context.data}>
|
<div class={bem([type, colorType])} style={style} {...ctx.data}>
|
||||||
<span class={bem('spinner', type)}>
|
<span class={bem('spinner', type)}>
|
||||||
{Spin}
|
{Spin}
|
||||||
{Circular}
|
{Circular}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading.props = {
|
||||||
|
size: String,
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'circular'
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: DEFAULT_COLOR
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
export default sfc(Loading);
|
||||||
|
@ -4,10 +4,43 @@ import Icon from '../icon';
|
|||||||
|
|
||||||
const [sfc, bem] = use('nav-bar');
|
const [sfc, bem] = use('nav-bar');
|
||||||
|
|
||||||
export default sfc({
|
function NavBar(h, props, slots, ctx) {
|
||||||
functional: true,
|
return (
|
||||||
|
<div
|
||||||
|
class={[
|
||||||
|
bem({ fixed: props.fixed }),
|
||||||
|
{ 'van-hairline--bottom': props.border }
|
||||||
|
]}
|
||||||
|
style={{ zIndex: props.zIndex }}
|
||||||
|
{...inherit(ctx)}
|
||||||
|
>
|
||||||
|
<div class={bem('left')} onClick={ctx.listeners['click-left'] || noop}>
|
||||||
|
{slots.left
|
||||||
|
? slots.left()
|
||||||
|
: [
|
||||||
|
props.leftArrow && (
|
||||||
|
<Icon class={bem('arrow')} name="arrow-left" />
|
||||||
|
),
|
||||||
|
props.leftText && (
|
||||||
|
<span class={bem('text')}>{props.leftText}</span>
|
||||||
|
)
|
||||||
|
]}
|
||||||
|
</div>
|
||||||
|
<div class={[bem('title'), 'van-ellipsis']}>
|
||||||
|
{slots.title ? slots.title() : props.title}
|
||||||
|
</div>
|
||||||
|
<div class={bem('right')} onClick={ctx.listeners['click-right'] || noop}>
|
||||||
|
{slots.right
|
||||||
|
? slots.right()
|
||||||
|
: props.rightText && (
|
||||||
|
<span class={bem('text')}>{props.rightText}</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
props: {
|
NavBar.props = {
|
||||||
title: String,
|
title: String,
|
||||||
fixed: Boolean,
|
fixed: Boolean,
|
||||||
leftText: String,
|
leftText: String,
|
||||||
@ -21,29 +54,6 @@ export default sfc({
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 1
|
default: 1
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
render(h, context) {
|
export default sfc(NavBar);
|
||||||
const { props, listeners } = context;
|
|
||||||
const slots = context.slots();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
class={[bem({ fixed: props.fixed }), { 'van-hairline--bottom': props.border }]}
|
|
||||||
style={{ zIndex: props.zIndex }}
|
|
||||||
{...inherit(context)}
|
|
||||||
>
|
|
||||||
<div class={bem('left')} onClick={listeners['click-left'] || noop}>
|
|
||||||
{slots.left || [
|
|
||||||
props.leftArrow && <Icon class={bem('arrow')} name="arrow-left" />,
|
|
||||||
props.leftText && <span class={bem('text')}>{props.leftText}</span>
|
|
||||||
]}
|
|
||||||
</div>
|
|
||||||
<div class={[bem('title'), 'van-ellipsis']}>{slots.title || props.title}</div>
|
|
||||||
<div class={bem('right')} onClick={listeners['click-right'] || noop}>
|
|
||||||
{slots.right || (props.rightText && <span class={bem('text')}>{props.rightText}</span>)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
@ -4,23 +4,12 @@ import CellGroup from '../cell-group';
|
|||||||
|
|
||||||
const [sfc, bem] = use('panel');
|
const [sfc, bem] = use('panel');
|
||||||
|
|
||||||
export default sfc({
|
function Panel(h, props, slots, ctx) {
|
||||||
functional: true,
|
|
||||||
|
|
||||||
props: {
|
|
||||||
icon: String,
|
|
||||||
desc: String,
|
|
||||||
title: String,
|
|
||||||
status: String
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
const { props } = context;
|
|
||||||
const slots = context.slots();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CellGroup class={bem()} {...context.data}>
|
<CellGroup class={bem()} {...ctx.data}>
|
||||||
{slots.header || (
|
{slots.header ? (
|
||||||
|
slots.header()
|
||||||
|
) : (
|
||||||
<Cell
|
<Cell
|
||||||
icon={props.icon}
|
icon={props.icon}
|
||||||
label={props.desc}
|
label={props.desc}
|
||||||
@ -30,9 +19,19 @@ export default sfc({
|
|||||||
valueClass={bem('header-value')}
|
valueClass={bem('header-value')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div class={bem('content')}>{slots.default}</div>
|
<div class={bem('content')}>{slots.default && slots.default()}</div>
|
||||||
{slots.footer && <div class={[bem('footer'), 'van-hairline--top']}>{slots.footer}</div>}
|
{slots.footer && (
|
||||||
|
<div class={[bem('footer'), 'van-hairline--top']}>{slots.footer()}</div>
|
||||||
|
)}
|
||||||
</CellGroup>
|
</CellGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
Panel.props = {
|
||||||
|
icon: String,
|
||||||
|
desc: String,
|
||||||
|
title: String,
|
||||||
|
status: String
|
||||||
|
};
|
||||||
|
|
||||||
|
export default sfc(Panel);
|
||||||
|
@ -3,24 +3,7 @@ import { emit } from '../utils/functional';
|
|||||||
|
|
||||||
const [sfc, bem] = use('password-input');
|
const [sfc, bem] = use('password-input');
|
||||||
|
|
||||||
export default sfc({
|
function PasswordInput(h, props, slots, ctx) {
|
||||||
functional: true,
|
|
||||||
|
|
||||||
props: {
|
|
||||||
info: String,
|
|
||||||
errorInfo: String,
|
|
||||||
value: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
length: {
|
|
||||||
type: Number,
|
|
||||||
default: 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
const { props } = context;
|
|
||||||
const info = props.errorInfo || props.info;
|
const info = props.errorInfo || props.info;
|
||||||
|
|
||||||
const Points = [];
|
const Points = [];
|
||||||
@ -38,14 +21,30 @@ export default sfc({
|
|||||||
class={[bem('security'), 'van-hairline--surround']}
|
class={[bem('security'), 'van-hairline--surround']}
|
||||||
onTouchstart={event => {
|
onTouchstart={event => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
emit(context, 'focus', event);
|
emit(ctx, 'focus', event);
|
||||||
}}
|
}}
|
||||||
{...context.data}
|
{...ctx.data}
|
||||||
>
|
>
|
||||||
{Points}
|
{Points}
|
||||||
</ul>
|
</ul>
|
||||||
{info && <div class={bem(props.errorInfo ? 'error-info' : 'info')}>{info}</div>}
|
{info && (
|
||||||
|
<div class={bem(props.errorInfo ? 'error-info' : 'info')}>{info}</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PasswordInput.props = {
|
||||||
|
info: String,
|
||||||
|
errorInfo: String,
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
length: {
|
||||||
|
type: Number,
|
||||||
|
default: 6
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
export default sfc(PasswordInput);
|
||||||
|
@ -4,10 +4,44 @@ import Button from '../button';
|
|||||||
|
|
||||||
const [sfc, bem, t] = use('submit-bar');
|
const [sfc, bem, t] = use('submit-bar');
|
||||||
|
|
||||||
export default sfc({
|
function SubmitBar(h, props, slots, ctx) {
|
||||||
functional: true,
|
const { tip, price } = props;
|
||||||
|
const hasPrice = typeof price === 'number';
|
||||||
|
|
||||||
props: {
|
return (
|
||||||
|
<div class={bem()} {...inherit(ctx)}>
|
||||||
|
{slots.top && slots.top()}
|
||||||
|
{(slots.tip || tip) && (
|
||||||
|
<div class={bem('tip')}>
|
||||||
|
{tip}
|
||||||
|
{slots.tip && slots.tip()}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div class={bem('bar')}>
|
||||||
|
{slots.default && slots.default()}
|
||||||
|
<div class={bem('text')}>
|
||||||
|
{hasPrice && [
|
||||||
|
<span>{props.label || t('label')}</span>,
|
||||||
|
<span class={bem('price')}>{`${props.currency} ${(
|
||||||
|
price / 100
|
||||||
|
).toFixed(2)}`}</span>
|
||||||
|
]}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
square
|
||||||
|
size="large"
|
||||||
|
type={props.buttonType}
|
||||||
|
loading={props.loading}
|
||||||
|
disabled={props.disabled}
|
||||||
|
text={props.loading ? '' : props.buttonText}
|
||||||
|
onClick={ctx.listeners.submit || noop}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SubmitBar.props = {
|
||||||
tip: String,
|
tip: String,
|
||||||
label: String,
|
label: String,
|
||||||
loading: Boolean,
|
loading: Boolean,
|
||||||
@ -25,42 +59,6 @@ export default sfc({
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'danger'
|
default: 'danger'
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
render(h, context) {
|
export default sfc(SubmitBar);
|
||||||
const { props, listeners } = context;
|
|
||||||
const { tip, price } = props;
|
|
||||||
const slots = context.slots();
|
|
||||||
const hasPrice = typeof price === 'number';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class={bem()} {...inherit(context)}>
|
|
||||||
{slots.top}
|
|
||||||
{(slots.tip || tip) && (
|
|
||||||
<div class={bem('tip')}>
|
|
||||||
{tip}
|
|
||||||
{slots.tip}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div class={bem('bar')}>
|
|
||||||
{slots.default}
|
|
||||||
<div class={bem('text')}>
|
|
||||||
{hasPrice && [
|
|
||||||
<span>{props.label || t('label')}</span>,
|
|
||||||
<span class={bem('price')}>{`${props.currency} ${(price / 100).toFixed(2)}`}</span>
|
|
||||||
]}
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
square
|
|
||||||
size="large"
|
|
||||||
type={props.buttonType}
|
|
||||||
loading={props.loading}
|
|
||||||
disabled={props.disabled}
|
|
||||||
text={props.loading ? '' : props.buttonText}
|
|
||||||
onClick={listeners.submit || noop}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
@ -2,31 +2,32 @@ import { use } from '../utils';
|
|||||||
import { inherit } from '../utils/functional';
|
import { inherit } from '../utils/functional';
|
||||||
import Cell from '../cell';
|
import Cell from '../cell';
|
||||||
import Switch from '../switch';
|
import Switch from '../switch';
|
||||||
import SwitchMixin from '../mixins/switch';
|
import { switchProps } from '../switch/shared';
|
||||||
|
|
||||||
const [sfc, bem] = use('switch-cell');
|
const [sfc, bem] = use('switch-cell');
|
||||||
|
|
||||||
export default sfc({
|
function SwitchCell(h, props, slots, ctx) {
|
||||||
functional: true,
|
return (
|
||||||
|
<Cell
|
||||||
|
center
|
||||||
|
title={props.title}
|
||||||
|
border={props.border}
|
||||||
|
class={bem()}
|
||||||
|
{...inherit(ctx)}
|
||||||
|
>
|
||||||
|
<Switch {...{ props, on: ctx.listeners }} />
|
||||||
|
</Cell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
mixins: [SwitchMixin],
|
SwitchCell.props = {
|
||||||
|
...switchProps,
|
||||||
props: {
|
|
||||||
title: String,
|
title: String,
|
||||||
border: Boolean,
|
border: Boolean,
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '24px'
|
default: '24px'
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
render(h, context) {
|
export default sfc(SwitchCell);
|
||||||
const { props } = context;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Cell center title={props.title} border={props.border} class={bem()} {...inherit(context)}>
|
|
||||||
<Switch {...{ props, on: context.listeners }} />
|
|
||||||
</Cell>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { use } from '../utils';
|
import { use } from '../utils';
|
||||||
import Loading from '../loading';
|
import Loading from '../loading';
|
||||||
import SwitchMixin from '../mixins/switch';
|
import { switchProps } from './shared';
|
||||||
|
|
||||||
const [sfc, bem] = use('switch');
|
const [sfc, bem] = use('switch');
|
||||||
|
|
||||||
export default sfc({
|
export default sfc({
|
||||||
mixins: [SwitchMixin],
|
props: switchProps,
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
onClick() {
|
onClick() {
|
||||||
|
23
packages/switch/shared.ts
Normal file
23
packages/switch/shared.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Common Switch Props
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const switchProps = {
|
||||||
|
value: null,
|
||||||
|
loading: Boolean,
|
||||||
|
disabled: Boolean,
|
||||||
|
activeColor: String,
|
||||||
|
inactiveColor: String,
|
||||||
|
activeValue: {
|
||||||
|
type: null,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
inactiveValue: {
|
||||||
|
type: null,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: String,
|
||||||
|
default: '30px'
|
||||||
|
}
|
||||||
|
};
|
@ -9,22 +9,8 @@ const COLOR_MAP = {
|
|||||||
success: GREEN
|
success: GREEN
|
||||||
};
|
};
|
||||||
|
|
||||||
export default sfc({
|
function Tag(h, props, slots, ctx) {
|
||||||
functional: true,
|
const { mark, plain, round, size } = ctx.props;
|
||||||
|
|
||||||
props: {
|
|
||||||
size: String,
|
|
||||||
type: String,
|
|
||||||
mark: Boolean,
|
|
||||||
color: String,
|
|
||||||
plain: Boolean,
|
|
||||||
round: Boolean,
|
|
||||||
textColor: String
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h, context) {
|
|
||||||
const { props } = context;
|
|
||||||
const { mark, plain, round, size } = context.props;
|
|
||||||
|
|
||||||
const color = props.color || COLOR_MAP[props.type] || GRAY_DARK;
|
const color = props.color || COLOR_MAP[props.type] || GRAY_DARK;
|
||||||
const key = plain ? 'color' : 'backgroundColor';
|
const key = plain ? 'color' : 'backgroundColor';
|
||||||
@ -43,10 +29,21 @@ export default sfc({
|
|||||||
'van-hairline--surround': plain
|
'van-hairline--surround': plain
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
{...context.data}
|
{...ctx.data}
|
||||||
>
|
>
|
||||||
{context.children}
|
{slots.default && slots.default()}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
Tag.props = {
|
||||||
|
size: String,
|
||||||
|
type: String,
|
||||||
|
mark: Boolean,
|
||||||
|
color: String,
|
||||||
|
plain: Boolean,
|
||||||
|
round: Boolean,
|
||||||
|
textColor: String
|
||||||
|
};
|
||||||
|
|
||||||
|
export default sfc(Tag);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { RenderContext, VNodeData } from 'vue/types';
|
import { RenderContext, VNodeData } from 'vue/types';
|
||||||
import { ScopedSlot } from 'vue/types/vnode';
|
|
||||||
|
|
||||||
type ObjectIndex = {
|
type ObjectIndex = {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
@ -47,17 +46,3 @@ export function emit(context: Context, eventName: string, ...args: any[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unify slots & scopedSlots
|
|
||||||
export function unifySlots(context: Context) {
|
|
||||||
const { scopedSlots } = context;
|
|
||||||
const slots = context.slots();
|
|
||||||
|
|
||||||
Object.keys(slots).forEach(key => {
|
|
||||||
if (!scopedSlots[key]) {
|
|
||||||
scopedSlots[key] = () => slots[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return scopedSlots;
|
|
||||||
}
|
|
||||||
|
@ -4,13 +4,29 @@
|
|||||||
import '../../locale';
|
import '../../locale';
|
||||||
import { camelize } from '..';
|
import { camelize } from '..';
|
||||||
import SlotsMixin from '../../mixins/slots';
|
import SlotsMixin from '../../mixins/slots';
|
||||||
import Vue, { VueConstructor, ComponentOptions } from 'vue';
|
import Vue, {
|
||||||
|
VueConstructor,
|
||||||
|
ComponentOptions,
|
||||||
|
CreateElement,
|
||||||
|
RenderContext
|
||||||
|
} from 'vue/types';
|
||||||
|
import { VNode, ScopedSlot } from 'vue/types/vnode';
|
||||||
|
|
||||||
type VantComponentOptions = ComponentOptions<Vue> & {
|
type VantComponentOptions = ComponentOptions<Vue> & {
|
||||||
functional?: boolean;
|
functional?: boolean;
|
||||||
install?: (Vue: VueConstructor) => void;
|
install?: (Vue: VueConstructor) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type VantPureComponent = {
|
||||||
|
(
|
||||||
|
h: CreateElement,
|
||||||
|
props: { [key: string]: any },
|
||||||
|
slots: { [key: string]: ScopedSlot | undefined },
|
||||||
|
context: RenderContext
|
||||||
|
): VNode;
|
||||||
|
props: any;
|
||||||
|
};
|
||||||
|
|
||||||
const arrayProp = {
|
const arrayProp = {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => []
|
||||||
@ -39,15 +55,46 @@ function install(this: ComponentOptions<Vue>, Vue: VueConstructor) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (name: string) => (sfc: VantComponentOptions) => {
|
// unify slots & scopedSlots
|
||||||
sfc.name = name;
|
export function unifySlots(context: RenderContext) {
|
||||||
sfc.install = install;
|
const { scopedSlots } = context;
|
||||||
|
const slots = context.slots();
|
||||||
|
|
||||||
|
Object.keys(slots).forEach(key => {
|
||||||
|
if (!scopedSlots[key]) {
|
||||||
|
scopedSlots[key] = () => slots[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return scopedSlots;
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformPureComponent(pure: VantPureComponent): VantComponentOptions {
|
||||||
|
return {
|
||||||
|
functional: true,
|
||||||
|
props: pure.props,
|
||||||
|
render: (h, context) => pure(h, context.props, unifySlots(context), context)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (name: string) => (
|
||||||
|
sfc: VantComponentOptions | VantPureComponent
|
||||||
|
) => {
|
||||||
|
if (typeof sfc === 'function') {
|
||||||
|
sfc = transformPureComponent(sfc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sfc.functional) {
|
||||||
sfc.mixins = sfc.mixins || [];
|
sfc.mixins = sfc.mixins || [];
|
||||||
sfc.mixins.push(SlotsMixin);
|
sfc.mixins.push(SlotsMixin);
|
||||||
|
}
|
||||||
|
|
||||||
if (sfc.props) {
|
if (sfc.props) {
|
||||||
defaultProps(sfc.props);
|
defaultProps(sfc.props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sfc.name = name;
|
||||||
|
sfc.install = install;
|
||||||
|
|
||||||
return sfc;
|
return sfc;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user