[improvement] make props less magic (#3775)

This commit is contained in:
neverland 2019-07-08 16:18:19 +08:00 committed by GitHub
parent 642639da6e
commit be96fa2233
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 283 additions and 206 deletions

View File

@ -21,7 +21,7 @@ export type ActionSheetItem = {
export type ActionSheetProps = PopupMixinProps & {
title?: string;
actions: ActionSheetItem[];
actions?: ActionSheetItem[];
duration: number;
cancelText?: string;
closeOnClickAction?: boolean;
@ -126,7 +126,7 @@ function ActionSheet(
{...inherit(ctx, true)}
>
{Header()}
{props.actions.map(Option)}
{props.actions && props.actions.map(Option)}
{Content()}
{CancelText()}
</Popup>
@ -137,14 +137,11 @@ ActionSheet.props = {
...PopupMixin.props,
title: String,
actions: Array,
duration: Number,
cancelText: String,
getContainer: [String, Function],
closeOnClickAction: Boolean,
safeAreaInsetBottom: Boolean,
duration: {
type: Number,
default: null
},
overlay: {
type: Boolean,
default: true

View File

@ -226,11 +226,11 @@ export default createComponent({
},
render(h) {
const { data, errorInfo } = this;
const { data, errorInfo, searchResult } = this;
const onFocus = name => () => this.onFocus(name);
// hide bottom field when use search && detail get focused
const hideBottomFields = this.searchResult.length && this.detailFocused;
const hideBottomFields = searchResult && searchResult.length && this.detailFocused;
return (
<div class={bem()}>

View File

@ -13,8 +13,8 @@ export type AddressListProps = {
switchable: boolean;
disabledText?: string;
addButtonText?: string;
list: AddressItemData[];
disabledList: AddressItemData[];
list?: AddressItemData[];
disabledList?: AddressItemData[];
};
export type AddressListSlots = DefaultSlots & {
@ -29,8 +29,12 @@ function AddressList(
slots: AddressListSlots,
ctx: RenderContext<AddressListProps>
) {
const getList = (list: AddressItemData[], disabled?: boolean) =>
list.map((item, index) => (
function renderList(list?: AddressItemData[], disabled?: boolean) {
if (!list) {
return;
}
return list.map((item, index) => (
<AddressItem
data={item}
key={item.id}
@ -44,9 +48,10 @@ function AddressList(
}}
/>
));
}
const List = getList(props.list);
const DisabledList = getList(props.disabledList, true);
const List = renderList(props.list);
const DisabledList = renderList(props.disabledList, true);
return (
<div class={bem()} {...inherit(ctx)}>
@ -59,9 +64,7 @@ function AddressList(
>
{List}
</RadioGroup>
{props.disabledText && (
<div class={bem('disabled-text')}>{props.disabledText}</div>
)}
{props.disabledText && <div class={bem('disabled-text')}>{props.disabledText}</div>}
{DisabledList}
{slots.default && slots.default()}
<Button
@ -83,7 +86,7 @@ AddressList.props = {
disabledList: Array,
disabledText: String,
addButtonText: String,
value: [String, Number],
value: [Number, String],
switchable: {
type: Boolean,
default: true

View File

@ -13,7 +13,7 @@ export default createComponent({
default: () => ({})
},
columnsNum: {
type: [String, Number],
type: [Number, String],
default: 3
}
},

View File

@ -27,9 +27,9 @@ export const cellProps = {
titleClass: null as any,
valueClass: null as any,
labelClass: null as any,
title: [String, Number],
value: [String, Number],
label: [String, Number],
title: [Number, String],
value: [Number, String],
label: [Number, String],
arrowDirection: String,
border: {
type: Boolean,

View File

@ -8,8 +8,11 @@ export default createComponent({
props: {
max: Number,
value: Array,
disabled: Boolean
disabled: Boolean,
value: {
type: Array,
default: () => []
}
},
watch: {

View File

@ -13,8 +13,14 @@ function format(rate) {
export default createComponent({
props: {
text: String,
value: Number,
speed: Number,
value: {
type: Number,
default: 0
},
speed: {
type: Number,
default: 0
},
size: {
type: String,
default: '100px'

View File

@ -12,7 +12,7 @@ export default createComponent({
props: {
...cellProps,
name: [String, Number],
name: [Number, String],
disabled: Boolean,
isLink: {
type: Boolean,

View File

@ -19,7 +19,7 @@ export type ContactListItem = {
export type ContactListProps = {
value?: any;
list: ContactListItem[];
list?: ContactListItem[];
addText?: string;
};
@ -31,39 +31,49 @@ function ContactList(
slots: DefaultSlots,
ctx: RenderContext<ContactListProps>
) {
const List = props.list.map((item, index) => {
const onClick = () => {
emit(ctx, 'input', item.id);
emit(ctx, 'select', item, index);
};
const List =
props.list &&
props.list.map((item, index) => {
function onClick() {
emit(ctx, 'input', item.id);
emit(ctx, 'select', item, index);
}
return (
<Cell
key={item.id}
isLink
class={bem('item')}
valueClass={bem('item-value')}
scopedSlots={{
default: () => (
<Radio name={item.id} iconSize={16} checkedColor={RED} onClick={onClick}>
<div class={bem('name')}>{`${item.name}${item.tel}`}</div>
</Radio>
),
'right-icon': () => (
<Icon
name="edit"
class={bem('edit')}
onClick={event => {
event.stopPropagation();
emit(ctx, 'edit', item, index);
}}
/>
)
}}
onClick={onClick}
/>
);
});
function Content() {
return (
<Radio name={item.id} iconSize={16} checkedColor={RED} onClick={onClick}>
<div class={bem('name')}>{`${item.name}${item.tel}`}</div>
</Radio>
);
}
function RightIcon() {
return (
<Icon
name="edit"
class={bem('edit')}
onClick={event => {
event.stopPropagation();
emit(ctx, 'edit', item, index);
}}
/>
);
}
return (
<Cell
key={item.id}
isLink
class={bem('item')}
valueClass={bem('item-value')}
scopedSlots={{
default: Content,
'right-icon': RightIcon
}}
onClick={onClick}
/>
);
});
return (
<div class={bem()} {...inherit(ctx)}>

View File

@ -60,7 +60,10 @@ CouponCell.model = {
CouponCell.props = {
title: String,
coupons: Array,
coupons: {
type: Array,
default: () => []
},
currency: {
type: String,
default: '¥'

View File

@ -15,8 +15,6 @@ export default createComponent({
props: {
code: String,
coupons: Array,
disabledCoupons: Array,
closeButtonText: String,
inputPlaceholder: String,
enabledTitle: String,
@ -32,6 +30,14 @@ export default createComponent({
type: Number,
default: -1
},
coupons: {
type: Array,
default: () => []
},
disabledCoupons: {
type: Array,
default: () => []
},
displayedCouponIndex: {
type: Number,
default: -1

View File

@ -18,8 +18,14 @@ export default createComponent({
...pickerProps,
value: null,
filter: Function,
minHour: Number,
minMinute: Number,
minHour: {
type: Number,
default: 0
},
minMinute: {
type: Number,
default: 0
},
type: {
type: String,
default: 'datetime'

View File

@ -12,9 +12,12 @@ export default createComponent({
props: {
value: null,
title: String,
options: Array,
disabled: Boolean,
titleClass: String
titleClass: String,
options: {
type: Array,
default: () => []
}
},
data() {

View File

@ -14,15 +14,15 @@ export default createComponent({
props: {
...cellProps,
error: Boolean,
readonly: Boolean,
autosize: [Boolean, Object],
leftIcon: String,
rightIcon: String,
readonly: Boolean,
clearable: Boolean,
labelWidth: [String, Number],
labelClass: null,
labelWidth: [Number, String],
labelAlign: String,
inputAlign: String,
autosize: [Boolean, Object],
errorMessage: String,
errorMessageAlign: String,
type: {

View File

@ -58,7 +58,7 @@ GoodsActionIcon.props = {
...routeProps,
text: String,
icon: String,
info: [String, Number],
info: [Number, String],
iconClass: null as any
};

View File

@ -7,8 +7,8 @@ export default createComponent({
mixins: [ParentMixin('vanGrid')],
props: {
gutter: [Number, String],
square: Boolean,
gutter: [Number, String],
clickable: Boolean,
columnNum: {
type: Number,

View File

@ -52,9 +52,9 @@ function Icon(
Icon.props = {
name: String,
size: [String, Number],
size: [Number, String],
color: String,
info: [String, Number],
info: [Number, String],
tag: {
type: String,
default: 'i'

View File

@ -26,12 +26,14 @@ export default createComponent({
],
props: {
images: Array,
className: null,
lazyLoad: Boolean,
asyncClose: Boolean,
startPosition: Number,
showIndicators: Boolean,
images: {
type: Array,
default: () => []
},
loop: {
type: Boolean,
default: true
@ -44,6 +46,10 @@ export default createComponent({
type: Boolean,
default: true
},
startPosition: {
type: Number,
default: 0
},
minZoom: {
type: Number,
default: 1 / 3
@ -54,7 +60,7 @@ export default createComponent({
},
overlayClass: {
type: String,
default: 'van-image-preview__overlay'
default: bem('overlay')
},
closeOnClickOverlay: {
type: Boolean,

View File

@ -9,8 +9,8 @@ export default createComponent({
fit: String,
alt: String,
lazyLoad: Boolean,
width: [String, Number],
height: [String, Number]
width: [Number, String],
height: [Number, String]
},
data() {

View File

@ -7,7 +7,7 @@ export default createComponent({
mixins: [ChildrenMixin('vanIndexBar', { indexKey: 'childrenIndex' })],
props: {
index: [String, Number]
index: [Number, String]
},
data() {

View File

@ -29,7 +29,7 @@ function Info(
}
Info.props = {
info: [String, Number]
info: [Number, String]
};
export default createComponent<InfoProps>(Info);

View File

@ -74,9 +74,9 @@ function Loading(
}
Loading.props = {
size: [String, Number],
textSize: [String, Number],
size: [Number, String],
vertical: Boolean,
textSize: [Number, String],
type: {
type: String,
default: 'circular'

View File

@ -11,8 +11,8 @@ export const CheckboxMixin = ({ parent, bem, role }) => ({
props: {
name: null,
value: null,
iconSize: [String, Number],
disabled: Boolean,
iconSize: [Number, String],
checkedColor: String,
labelPosition: String,
labelDisabled: Boolean,

View File

@ -29,7 +29,7 @@ export const PopupMixin = {
// whether to close popup when click overlay
closeOnClickOverlay: Boolean,
// z-index
zIndex: [String, Number],
zIndex: [Number, String],
// prevent body scroll
lockScroll: {
type: Boolean,

View File

@ -12,7 +12,7 @@ export default createComponent({
wrapable: Boolean,
background: String,
delay: {
type: [String, Number],
type: [Number, String],
default: 1
},
scrollable: {

View File

@ -48,7 +48,7 @@ function Notify(
Notify.props = {
...PopupMixin.props,
className: null as any,
message: [String, Number],
message: [Number, String],
getContainer: [String, Function],
color: {
type: String,

View File

@ -5,8 +5,11 @@ const [createComponent, bem] = createNamespace('key');
export default createComponent({
props: {
type: String,
theme: Array,
text: [String, Number]
text: [Number, String],
theme: {
type: Array,
default: () => []
}
},
data() {

View File

@ -54,16 +54,13 @@ function Overlay(
Overlay.props = {
show: Boolean,
duration: [Number, String],
className: null as any,
customStyle: null as any,
zIndex: {
type: [Number, String],
default: 1
},
duration: {
type: [Number, String],
default: null
}
};
export default createComponent<OverlayProps, OverlayEvents>(Overlay);

View File

@ -8,12 +8,21 @@ function makePage(number, text, active) {
export default createComponent({
props: {
value: Number,
prevText: String,
nextText: String,
pageCount: Number,
totalItems: Number,
forceEllipses: Boolean,
value: {
type: Number,
default: 0
},
pageCount: {
type: Number,
default: 0
},
totalItems: {
type: Number,
default: 0
},
mode: {
type: String,
default: 'multi'

View File

@ -60,8 +60,8 @@ function PasswordInput(
PasswordInput.props = {
info: String,
gutter: [Number, String],
errorInfo: String,
gutter: [String, Number],
mask: {
type: Boolean,
default: true

View File

@ -35,8 +35,11 @@ export default createComponent({
className: String,
itemHeight: Number,
defaultIndex: Number,
initialOptions: Array,
visibleItemCount: Number
visibleItemCount: Number,
initialOptions: {
type: Array,
default: () => []
}
},
data() {

View File

@ -11,8 +11,14 @@ const [createComponent, bem, t] = createNamespace('picker');
export default createComponent({
props: {
...pickerProps,
columns: Array,
defaultIndex: Number,
defaultIndex: {
type: Number,
default: 0
},
columns: {
type: Array,
default: () => []
},
toolbarPosition: {
type: String,
default: 'top'

View File

@ -2,7 +2,7 @@
exports[`column watch default index 1`] = `
<div class="van-picker-column">
<ul class="van-picker-column__wrapper" style="transform: translate3d(0, -75px, 0); transition-duration: 0ms; transition-property: none; line-height: 50px;">
<ul class="van-picker-column__wrapper" style="transform: translate3d(0, 100px, 0); transition-duration: 0ms; transition-property: none; line-height: 50px;">
<li class="van-ellipsis van-picker-column__item van-picker-column__item--disabled" style="height: 50px;">1</li>
<li class="van-ellipsis van-picker-column__item" style="height: 50px;">1990</li>
<li class="van-ellipsis van-picker-column__item" style="height: 50px;">1991</li>
@ -16,7 +16,7 @@ exports[`column watch default index 1`] = `
exports[`column watch default index 2`] = `
<div class="van-picker-column">
<ul class="van-picker-column__wrapper" style="transform: translate3d(0, -125px, 0); transition-duration: 0ms; transition-property: none; line-height: 50px;">
<ul class="van-picker-column__wrapper" style="transform: translate3d(0, 0px, 0); transition-duration: 0ms; transition-property: none; line-height: 50px;">
<li class="van-ellipsis van-picker-column__item van-picker-column__item--disabled" style="height: 50px;">1</li>
<li class="van-ellipsis van-picker-column__item" style="height: 50px;">1990</li>
<li class="van-ellipsis van-picker-column__item" style="height: 50px;">1991</li>

View File

@ -114,7 +114,8 @@ test('column watch default index', async () => {
propsData: {
initialOptions: [disabled, ...simpleColumn],
valueKey: 'text',
itemHeight: 50
itemHeight: 50,
visibleItemCount: 5
}
});

View File

@ -7,11 +7,8 @@ export default createComponent({
mixins: [PopupMixin],
props: {
duration: Number,
transition: String,
duration: {
type: Number,
default: null
},
position: {
type: String,
default: 'center'

View File

@ -154,12 +154,15 @@ function Rate(
}
Rate.props = {
value: Number,
size: [String, Number],
gutter: [String, Number],
size: [Number, String],
gutter: [Number, String],
readonly: Boolean,
disabled: Boolean,
allowHalf: Boolean,
value: {
type: Number,
default: 0
},
icon: {
type: String,
default: 'star'

View File

@ -10,7 +10,7 @@ export default createComponent({
props: {
...routeProps,
info: [String, Number],
info: [Number, String],
title: String
},

View File

@ -84,9 +84,12 @@ function Skeleton(
}
Skeleton.props = {
row: Number,
title: Boolean,
avatar: Boolean,
row: {
type: Number,
default: 0
},
loading: {
type: Boolean,
default: true

View File

@ -20,21 +20,27 @@ export default createComponent({
props: {
sku: Object,
goods: Object,
quota: Number,
value: Boolean,
buyText: String,
addCartText: String,
quotaUsed: Number,
goodsId: [Number, String],
hideStock: Boolean,
hideQuotaText: Boolean,
addCartText: String,
stepperTitle: String,
getContainer: Function,
hideQuotaText: Boolean,
resetStepperOnHide: Boolean,
customSkuValidator: Function,
closeOnClickOverlay: Boolean,
disableStepperInput: Boolean,
resetStepperOnHide: Boolean,
resetSelectedSkuOnHide: Boolean,
quota: {
type: Number,
default: 0
},
quotaUsed: {
type: Number,
default: 0
},
initialSku: {
type: Object,
default: () => ({})

View File

@ -5,11 +5,14 @@ const [createComponent] = createNamespace('sku-row-item');
export default createComponent({
props: {
skuList: Array,
skuValue: Object,
skuKeyStr: String,
skuEventBus: Object,
selectedSku: Object
selectedSku: Object,
skuList: {
type: Array,
default: () => []
}
},
computed: {

View File

@ -7,18 +7,24 @@ const { QUOTA_LIMIT, STOCK_LIMIT } = LIMIT_TYPE;
export default createComponent({
props: {
quota: Number,
quotaUsed: Number,
hideStock: Boolean,
selectedSku: Object,
skuEventBus: Object,
skuStockNum: Number,
selectedSku: Object,
selectedNum: Number,
stepperTitle: String,
hideQuotaText: Boolean,
selectedSkuComb: Object,
disableStepperInput: Boolean,
customStepperConfig: Object
customStepperConfig: Object,
quota: {
type: Number,
default: 0
},
quotaUsed: {
type: Number,
default: 0
}
},
data() {

View File

@ -8,12 +8,14 @@ export default createComponent({
mixins: [TouchMixin],
props: {
min: Number,
value: Number,
disabled: Boolean,
vertical: Boolean,
activeColor: String,
inactiveColor: String,
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 100
@ -22,6 +24,10 @@ export default createComponent({
type: Number,
default: 1
},
value: {
type: Number,
default: 0
},
barHeight: {
type: String,
default: '2px'

View File

@ -10,24 +10,24 @@ export default createComponent({
value: null,
integer: Boolean,
disabled: Boolean,
inputWidth: [String, Number],
buttonSize: [String, Number],
inputWidth: [Number, String],
buttonSize: [Number, String],
asyncChange: Boolean,
disableInput: Boolean,
min: {
type: [String, Number],
type: [Number, String],
default: 1
},
max: {
type: [String, Number],
type: [Number, String],
default: Infinity
},
step: {
type: [String, Number],
type: [Number, String],
default: 1
},
defaultValue: {
type: [String, Number],
type: [Number, String],
default: 1
}
},

View File

@ -5,8 +5,11 @@ const [createComponent, bem] = createNamespace('steps');
export default createComponent({
props: {
active: Number,
inactiveIcon: String,
active: {
type: Number,
default: 0
},
direction: {
type: String,
default: 'horizontal'

View File

@ -94,17 +94,14 @@ function SubmitBar(
SubmitBar.props = {
tip: String,
tipIcon: String,
label: String,
price: Number,
tipIcon: String,
loading: Boolean,
disabled: Boolean,
buttonText: String,
suffixLabel: String,
safeAreaInsetBottom: Boolean,
price: {
type: Number,
default: null
},
decimalLength: {
type: Number,
default: 2

View File

@ -22,7 +22,7 @@ export default createComponent({
leftWidth: Number,
rightWidth: Number,
name: {
type: [String, Number],
type: [Number, String],
default: ''
}
},

View File

@ -25,23 +25,26 @@ export default createComponent({
height: Number,
autoplay: Number,
vertical: Boolean,
initialSwipe: Number,
indicatorColor: String,
loop: {
type: Boolean,
default: true
},
touchable: {
type: Boolean,
default: true
},
showIndicators: {
type: Boolean,
default: true
},
duration: {
type: Number,
default: 500
},
touchable: {
type: Boolean,
default: true
},
initialSwipe: {
type: Number,
default: 0
},
showIndicators: {
type: Boolean,
default: true
}
},

View File

@ -8,7 +8,7 @@ export default createComponent({
mixins: [ChildrenMixin('vanTabs')],
props: {
name: [String, Number],
name: [Number, String],
title: String,
disabled: Boolean
},

View File

@ -11,10 +11,10 @@ export default createComponent({
props: {
...routeProps,
icon: String,
dot: Boolean,
name: [String, Number],
info: [String, Number]
icon: String,
name: [Number, String],
info: [Number, String]
},
data() {

View File

@ -12,7 +12,7 @@ export default createComponent({
inactiveColor: String,
safeAreaInsetBottom: Boolean,
value: {
type: [String, Number],
type: [Number, String],
default: 0
},
border: {

View File

@ -31,13 +31,20 @@ export default createComponent({
color: String,
sticky: Boolean,
animated: Boolean,
offsetTop: Number,
swipeable: Boolean,
background: String,
lineWidth: [Number, String],
lineHeight: [Number, String],
titleActiveColor: String,
titleInactiveColor: String,
type: {
type: String,
default: 'line'
},
active: {
type: [Number, String],
default: 0
},
border: {
type: Boolean,
default: true
@ -46,22 +53,18 @@ export default createComponent({
type: Boolean,
default: true
},
lazyRender: {
type: Boolean,
default: true
},
active: {
type: [Number, String],
default: 0
},
type: {
type: String,
default: 'line'
},
duration: {
type: Number,
default: 0.3
},
offsetTop: {
type: Number,
default: 0
},
lazyRender: {
type: Boolean,
default: true
},
swipeThreshold: {
type: Number,
default: 4

View File

@ -13,7 +13,7 @@ export default createComponent({
className: null,
loadingType: String,
forbidClick: Boolean,
message: [String, Number],
message: [Number, String],
type: {
type: String,
default: 'text'

View File

@ -35,7 +35,7 @@ function TreeSelect(
) {
const { height, items, mainActiveIndex, activeId } = props;
const selectedItem = items[mainActiveIndex] || {};
const selectedItem: Partial<TreeSelectItem> = items[mainActiveIndex] || {};
const subItems = selectedItem.children || [];
return (
@ -90,15 +90,21 @@ function TreeSelect(
}
TreeSelect.props = {
items: Array,
mainActiveIndex: Number,
activeId: {
type: [Number, String],
default: 0
items: {
type: Array,
default: () => []
},
height: {
type: Number,
default: 300
},
activeId: {
type: [Number, String],
default: 0
},
mainActiveIndex: {
type: Number,
default: 0
}
};

View File

@ -18,27 +18,22 @@ export default createComponent({
},
props: {
fileList: Array,
disabled: Boolean,
uploadText: String,
afterRead: Function,
beforeRead: Function,
previewSize: [Number, String],
name: {
type: [String, Number],
type: [Number, String],
default: ''
},
previewImage: {
type: Boolean,
default: true
},
accept: {
type: String,
default: 'image/*'
},
resultType: {
type: String,
default: 'dataUrl'
fileList: {
type: Array,
default: () => []
},
maxSize: {
type: Number,
@ -47,6 +42,14 @@ export default createComponent({
maxCount: {
type: Number,
default: Number.MAX_VALUE
},
previewImage: {
type: Boolean,
default: true
},
resultType: {
type: String,
default: 'dataUrl'
}
},

View File

@ -25,26 +25,6 @@ export type TsxComponent<Props, Events, Slots> = (
props: Partial<Props & Events & TsxBaseProps<Slots>>
) => VNode;
const arrayProp = {
type: Array,
default: () => []
};
const numberProp = {
type: Number,
default: 0
};
function defaultProps(props: any) {
Object.keys(props).forEach(key => {
if (props[key] === Array) {
props[key] = arrayProp;
} else if (props[key] === Number) {
props[key] = numberProp;
}
});
}
function install(this: ComponentOptions<Vue>, Vue: VueConstructor) {
const { name } = this;
Vue.component(name as string, this);
@ -89,10 +69,6 @@ export function createComponent(name: string) {
sfc.mixins.push(SlotsMixin);
}
if (sfc.props) {
defaultProps(sfc.props);
}
sfc.name = name;
sfc.install = install;