chore: remove object spead (#8514)

This commit is contained in:
neverland 2021-04-12 20:57:24 +08:00 committed by GitHub
parent 0b764b6347
commit 9deca34d1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 204 additions and 241 deletions

View File

@ -1,5 +1,5 @@
import { computed, PropType, defineComponent } from 'vue'; import { computed, PropType, defineComponent } from 'vue';
import { createNamespace } from '../utils'; import { extend, createNamespace } from '../utils';
import { ACTION_BAR_KEY } from '../action-bar/ActionBar'; import { ACTION_BAR_KEY } from '../action-bar/ActionBar';
// Composables // Composables
@ -15,15 +15,14 @@ const [name, bem] = createNamespace('action-bar-button');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, routeProps, {
...routeProps,
type: String as PropType<ButtonType>, type: String as PropType<ButtonType>,
text: String, text: String,
icon: String, icon: String,
color: String, color: String,
loading: Boolean, loading: Boolean,
disabled: Boolean, disabled: Boolean,
}, }),
setup(props, { slots }) { setup(props, { slots }) {
const route = useRoute(); const route = useRoute();

View File

@ -1,5 +1,5 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { createNamespace, UnknownProp } from '../utils'; import { extend, createNamespace, UnknownProp } from '../utils';
import { ACTION_BAR_KEY } from '../action-bar/ActionBar'; import { ACTION_BAR_KEY } from '../action-bar/ActionBar';
// Composables // Composables
@ -15,15 +15,14 @@ const [name, bem] = createNamespace('action-bar-icon');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, routeProps, {
...routeProps,
dot: Boolean, dot: Boolean,
text: String, text: String,
icon: String, icon: String,
color: String, color: String,
badge: [Number, String], badge: [Number, String],
iconClass: UnknownProp, iconClass: UnknownProp,
}, }),
setup(props, { slots }) { setup(props, { slots }) {
const route = useRoute(); const route = useRoute();

View File

@ -1,7 +1,7 @@
import { nextTick, PropType, defineComponent } from 'vue'; import { nextTick, PropType, defineComponent } from 'vue';
// Utils // Utils
import { createNamespace, pick } from '../utils'; import { pick, extend, createNamespace } from '../utils';
// Components // Components
import { Icon } from '../icon'; import { Icon } from '../icon';
@ -24,8 +24,7 @@ export type ActionSheetAction = {
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, popupSharedProps, {
...popupSharedProps,
title: String, title: String,
actions: Array as PropType<ActionSheetAction[]>, actions: Array as PropType<ActionSheetAction[]>,
cancelText: String, cancelText: String,
@ -48,7 +47,7 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
}, }),
emits: ['select', 'cancel', 'update:show'], emits: ['select', 'cancel', 'update:show'],
@ -157,10 +156,8 @@ export default defineComponent({
round={props.round} round={props.round}
position="bottom" position="bottom"
safeAreaInsetBottom={props.safeAreaInsetBottom} safeAreaInsetBottom={props.safeAreaInsetBottom}
{...{ {...pick(props, popupSharedPropKeys)}
...pick(props, popupSharedPropKeys), {...{ 'onUpdate:show': updateShow }}
'onUpdate:show': updateShow,
}}
> >
{renderHeader()} {renderHeader()}
{renderDescription()} {renderDescription()}

View File

@ -10,6 +10,7 @@ import {
// Utils // Utils
import { import {
extend,
isObject, isObject,
isMobile, isMobile,
createNamespace, createNamespace,
@ -100,7 +101,7 @@ export default defineComponent({
}, },
addressInfo: { addressInfo: {
type: Object as PropType<Partial<AddressEditInfo>>, type: Object as PropType<Partial<AddressEditInfo>>,
default: () => ({ ...defaultData }), default: () => extend({}, defaultData),
}, },
telValidator: { telValidator: {
type: Function as PropType<(val: string) => boolean>, type: Function as PropType<(val: string) => boolean>,
@ -321,10 +322,7 @@ export default defineComponent({
watch( watch(
() => props.addressInfo, () => props.addressInfo,
(value) => { (value) => {
state.data = { state.data = extend({}, defaultData, value);
...defaultData,
...value,
};
setAreaCode(value.areaCode); setAreaCode(value.areaCode);
}, },
{ {

View File

@ -1,7 +1,7 @@
import { PropType, defineComponent } from 'vue'; import { PropType, defineComponent } from 'vue';
// Utils // Utils
import { createNamespace } from '../utils'; import { createNamespace, extend } from '../utils';
// Components // Components
import { Tag } from '../tag'; import { Tag } from '../tag';
@ -102,7 +102,7 @@ export default defineComponent({
border={false} border={false}
valueClass={bem('value')} valueClass={bem('value')}
/> />
{slots.bottom?.({ ...props.address, disabled })} {slots.bottom?.(extend({}, props.address, { disabled }))}
</div> </div>
); );
}; };

View File

@ -12,7 +12,7 @@ import {
// Utils // Utils
import { deepClone } from '../utils/deep-clone'; import { deepClone } from '../utils/deep-clone';
import { pick, createNamespace, ComponentInstance } from '../utils'; import { pick, createNamespace, ComponentInstance, extend } from '../utils';
import { pickerProps } from '../picker/Picker'; import { pickerProps } from '../picker/Picker';
// Composables // Composables
@ -45,8 +45,7 @@ type ColumnType = 'province' | 'county' | 'city';
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, pickerProps, {
...pickerProps,
value: String, value: String,
areaList: { areaList: {
type: Object as PropType<AreaList>, type: Object as PropType<AreaList>,
@ -64,7 +63,7 @@ export default defineComponent({
type: Array as PropType<string[]>, type: Array as PropType<string[]>,
default: () => [], default: () => [],
}, },
}, }),
emits: ['change', 'confirm'], emits: ['change', 'confirm'],

View File

@ -6,7 +6,7 @@ import {
} from 'vue'; } from 'vue';
// Utils // Utils
import { createNamespace } from '../utils'; import { createNamespace, extend } from '../utils';
import { BORDER_SURROUND } from '../utils/constant'; import { BORDER_SURROUND } from '../utils/constant';
import { useRoute, routeProps } from '../composables/use-route'; import { useRoute, routeProps } from '../composables/use-route';
@ -28,8 +28,7 @@ export type ButtonSize = 'large' | 'normal' | 'small' | 'mini';
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, routeProps, {
...routeProps,
text: String, text: String,
icon: String, icon: String,
color: String, color: String,
@ -64,7 +63,7 @@ export default defineComponent({
type: String as PropType<'left' | 'right'>, type: String as PropType<'left' | 'right'>,
default: 'left', default: 'left',
}, },
}, }),
emits: ['click'], emits: ['click'],

View File

@ -1,5 +1,5 @@
import { nextTick, PropType, reactive, watch, defineComponent } from 'vue'; import { nextTick, PropType, reactive, watch, defineComponent } from 'vue';
import { createNamespace } from '../utils'; import { createNamespace, extend } from '../utils';
// Components // Components
import { Tab } from '../tab'; import { Tab } from '../tab';
@ -62,12 +62,14 @@ export default defineComponent({
activeTab: 0, activeTab: 0,
}); });
const { text: textKey, value: valueKey, children: childrenKey } = { const { text: textKey, value: valueKey, children: childrenKey } = extend(
text: 'text', {
value: 'value', text: 'text',
children: 'children', value: 'value',
...props.fieldNames, children: 'children',
}; },
props.fieldNames
);
const getSelectedOptionsByValue = ( const getSelectedOptionsByValue = (
options: CascaderOption[], options: CascaderOption[],

View File

@ -1,7 +1,7 @@
import { PropType, CSSProperties, defineComponent } from 'vue'; import { PropType, CSSProperties, defineComponent } from 'vue';
// Utils // Utils
import { createNamespace, isDef, UnknownProp } from '../utils'; import { createNamespace, extend, isDef, UnknownProp } from '../utils';
// Composables // Composables
import { useRoute, routeProps } from '../composables/use-route'; import { useRoute, routeProps } from '../composables/use-route';
@ -41,10 +41,7 @@ export const cellProps = {
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, cellProps, routeProps),
...cellProps,
...routeProps,
},
setup(props, { slots }) { setup(props, { slots }) {
const route = useRoute(); const route = useRoute();

View File

@ -1,7 +1,7 @@
import { computed, watch, defineComponent } from 'vue'; import { computed, watch, defineComponent } from 'vue';
// Utils // Utils
import { createNamespace, pick } from '../utils'; import { createNamespace, extend, pick } from '../utils';
import { import {
CHECKBOX_GROUP_KEY, CHECKBOX_GROUP_KEY,
CheckboxGroupProvide, CheckboxGroupProvide,
@ -20,13 +20,12 @@ const [name, bem] = createNamespace('checkbox');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, checkerProps, {
...checkerProps,
bindGroup: { bindGroup: {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
}, }),
emits: ['change', 'update:modelValue'], emits: ['change', 'update:modelValue'],

View File

@ -1,5 +1,5 @@
import { ref, computed, PropType, defineComponent } from 'vue'; import { ref, computed, PropType, defineComponent } from 'vue';
import { addUnit, UnknownProp } from '../utils'; import { addUnit, extend, UnknownProp } from '../utils';
import { Icon } from '../icon'; import { Icon } from '../icon';
export type CheckerShape = 'square' | 'round'; export type CheckerShape = 'square' | 'round';
@ -29,8 +29,7 @@ export const checkerProps = {
}; };
export default defineComponent({ export default defineComponent({
props: { props: extend({}, checkerProps, {
...checkerProps,
role: String, role: String,
parent: Object as PropType<CheckerParent | null>, parent: Object as PropType<CheckerParent | null>,
checked: Boolean, checked: Boolean,
@ -40,9 +39,9 @@ export default defineComponent({
}, },
bem: { bem: {
type: Function, type: Function,
required: true, required: true as const,
}, },
}, }),
emits: ['click', 'toggle'], emits: ['click', 'toggle'],

View File

@ -2,7 +2,7 @@ import { ref, watch, computed, nextTick, defineComponent } from 'vue';
// Utils // Utils
import { cellProps } from '../cell/Cell'; import { cellProps } from '../cell/Cell';
import { createNamespace, pick } from '../utils'; import { createNamespace, extend, pick } from '../utils';
import { COLLAPSE_KEY, CollapseProvide } from '../collapse/Collapse'; import { COLLAPSE_KEY, CollapseProvide } from '../collapse/Collapse';
// Composables // Composables
@ -18,8 +18,7 @@ const [name, bem] = createNamespace('collapse-item');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, cellProps, {
...cellProps,
name: [Number, String], name: [Number, String],
disabled: Boolean, disabled: Boolean,
readonly: Boolean, readonly: Boolean,
@ -27,7 +26,7 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
}, }),
setup(props, { slots }) { setup(props, { slots }) {
const wrapperRef = ref<HTMLElement>(); const wrapperRef = ref<HTMLElement>();

View File

@ -1,7 +1,7 @@
import { watch, reactive, PropType, defineComponent } from 'vue'; import { watch, reactive, PropType, defineComponent } from 'vue';
// Utils // Utils
import { isMobile, createNamespace } from '../utils'; import { isMobile, createNamespace, extend } from '../utils';
// Components // Components
import { Cell } from '../cell'; import { Cell } from '../cell';
@ -35,7 +35,7 @@ export default defineComponent({
setDefaultLabel: String, setDefaultLabel: String,
contactInfo: { contactInfo: {
type: Object as PropType<ContactEditInfo>, type: Object as PropType<ContactEditInfo>,
default: () => ({ ...DEFAULT_CONTACT }), default: () => extend({}, DEFAULT_CONTACT),
}, },
telValidator: { telValidator: {
type: Function as PropType<(val: string) => boolean>, type: Function as PropType<(val: string) => boolean>,
@ -46,10 +46,7 @@ export default defineComponent({
emits: ['save', 'delete', 'change-default'], emits: ['save', 'delete', 'change-default'],
setup(props, { emit }) { setup(props, { emit }) {
const contact = reactive({ const contact = reactive(extend({}, DEFAULT_CONTACT, props.contactInfo));
...DEFAULT_CONTACT,
...props.contactInfo,
});
const onSave = () => { const onSave = () => {
if (!props.isSaving) { if (!props.isSaving) {

View File

@ -12,6 +12,7 @@ import {
import { import {
pick, pick,
range, range,
extend,
isDate, isDate,
padZero, padZero,
createNamespace, createNamespace,
@ -39,8 +40,7 @@ const [name] = createNamespace('date-picker');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, sharedProps, {
...sharedProps,
modelValue: Date, modelValue: Date,
type: { type: {
type: String as PropType<DatetimePickerType>, type: String as PropType<DatetimePickerType>,
@ -56,7 +56,7 @@ export default defineComponent({
default: () => new Date(currentYear + 10, 11, 31), default: () => new Date(currentYear + 10, 11, 31),
validator: isDate, validator: isDate,
}, },
}, }),
emits: ['confirm', 'cancel', 'change', 'update:modelValue'], emits: ['confirm', 'cancel', 'change', 'update:modelValue'],

View File

@ -1,5 +1,5 @@
import { ref, defineComponent } from 'vue'; import { ref, defineComponent } from 'vue';
import { pick, createNamespace, ComponentInstance } from '../utils'; import { pick, createNamespace, ComponentInstance, extend } from '../utils';
import { useExpose } from '../composables/use-expose'; import { useExpose } from '../composables/use-expose';
import TimePicker from './TimePicker'; import TimePicker from './TimePicker';
import DatePicker from './DatePicker'; import DatePicker from './DatePicker';
@ -12,11 +12,9 @@ const datePickerProps = Object.keys(DatePicker.props);
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, TimePicker.props, DatePicker.props, {
...TimePicker.props,
...DatePicker.props,
modelValue: [String, Date], modelValue: [String, Date],
}, }),
setup(props, { attrs, slots }) { setup(props, { attrs, slots }) {
const root = ref<ComponentInstance>(); const root = ref<ComponentInstance>();
@ -38,7 +36,8 @@ export default defineComponent({
v-slots={slots} v-slots={slots}
ref={root} ref={root}
class={bem()} class={bem()}
{...{ ...inheritProps, ...attrs }} {...inheritProps}
{...attrs}
/> />
); );
}; };

View File

@ -11,6 +11,7 @@ import {
import { import {
pick, pick,
range, range,
extend,
padZero, padZero,
createNamespace, createNamespace,
ComponentInstance, ComponentInstance,
@ -28,8 +29,7 @@ const [name] = createNamespace('time-picker');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, sharedProps, {
...sharedProps,
modelValue: String, modelValue: String,
minHour: { minHour: {
type: [Number, String], type: [Number, String],
@ -47,7 +47,7 @@ export default defineComponent({
type: [Number, String], type: [Number, String],
default: 59, default: 59,
}, },
}, }),
emits: ['confirm', 'cancel', 'change', 'update:modelValue'], emits: ['confirm', 'cancel', 'change', 'update:modelValue'],

View File

@ -1,4 +1,5 @@
import { PropType } from 'vue'; import { PropType } from 'vue';
import { extend } from '../utils';
import { pickerProps } from '../picker/Picker'; import { pickerProps } from '../picker/Picker';
export type ColumnType = 'year' | 'month' | 'day' | 'hour' | 'minute'; export type ColumnType = 'year' | 'month' | 'day' | 'hour' | 'minute';
@ -11,15 +12,14 @@ export type DatetimePickerType =
| 'month-day' | 'month-day'
| 'year-month'; | 'year-month';
export const sharedProps = { export const sharedProps = extend({}, pickerProps, {
...pickerProps,
filter: Function as PropType<(type: string, values: string[]) => string[]>, filter: Function as PropType<(type: string, values: string[]) => string[]>,
columnsOrder: Array as PropType<ColumnType[]>, columnsOrder: Array as PropType<ColumnType[]>,
formatter: { formatter: {
type: Function as PropType<(type: string, value: string) => string>, type: Function as PropType<(type: string, value: string) => string>,
default: (type: string, value: string) => value, default: (type: string, value: string) => value,
}, },
}; });
export const pickerKeys = Object.keys(pickerProps) as Array< export const pickerKeys = Object.keys(pickerProps) as Array<
keyof typeof pickerProps keyof typeof pickerProps

View File

@ -4,6 +4,7 @@ import { PropType, reactive, defineComponent } from 'vue';
import { callInterceptor, Interceptor } from '../utils/interceptor'; import { callInterceptor, Interceptor } from '../utils/interceptor';
import { import {
pick, pick,
extend,
addUnit, addUnit,
isFunction, isFunction,
UnknownProp, UnknownProp,
@ -34,8 +35,7 @@ const popupKeys = [
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, popupSharedProps, {
...popupSharedProps,
title: String, title: String,
theme: String as PropType<DialogTheme>, theme: String as PropType<DialogTheme>,
width: [Number, String], width: [Number, String],
@ -63,7 +63,7 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
}, }),
emits: ['confirm', 'cancel', 'update:show'], emits: ['confirm', 'cancel', 'update:show'],
@ -231,10 +231,8 @@ export default defineComponent({
class={[bem([theme]), className]} class={[bem([theme]), className]}
style={{ width: addUnit(width) }} style={{ width: addUnit(width) }}
aria-labelledby={title || message} aria-labelledby={title || message}
{...{ {...pick(props, popupKeys)}
...pick(props, popupKeys), {...{ 'onUpdate:show': updateShow }}
'onUpdate:show': updateShow,
}}
> >
{renderTitle()} {renderTitle()}
{renderContent()} {renderContent()}

View File

@ -1,5 +1,5 @@
import { App, CSSProperties, TeleportProps } from 'vue'; import { App, CSSProperties, TeleportProps } from 'vue';
import { inBrowser, ComponentInstance, withInstall } from '../utils'; import { inBrowser, ComponentInstance, withInstall, extend } from '../utils';
import { Interceptor } from '../utils/interceptor'; import { Interceptor } from '../utils/interceptor';
import { mountComponent, usePopupState } from '../utils/mount-component'; import { mountComponent, usePopupState } from '../utils/mount-component';
import VanDialog, { import VanDialog, {
@ -40,7 +40,7 @@ function initInstance() {
const Wrapper = { const Wrapper = {
setup() { setup() {
const { state, toggle } = usePopupState(); const { state, toggle } = usePopupState();
return () => <VanDialog {...{ ...state, 'onUpdate:show': toggle }} />; return () => <VanDialog {...state} {...{ 'onUpdate:show': toggle }} />;
}, },
}; };
@ -58,13 +58,13 @@ function Dialog(options: DialogOptions) {
initInstance(); initInstance();
} }
instance.open({ instance.open(
...Dialog.currentOptions, extend({}, Dialog.currentOptions, options, {
...options, callback: (action: DialogAction) => {
callback: (action: DialogAction) => { (action === 'confirm' ? resolve : reject)(action);
(action === 'confirm' ? resolve : reject)(action); },
}, })
}); );
}); });
} }
@ -94,17 +94,12 @@ Dialog.defaultOptions = {
closeOnClickOverlay: false, closeOnClickOverlay: false,
}; };
Dialog.currentOptions = { Dialog.currentOptions = extend({}, Dialog.defaultOptions);
...Dialog.defaultOptions,
};
Dialog.alert = Dialog; Dialog.alert = Dialog;
Dialog.confirm = (options: DialogOptions) => Dialog.confirm = (options: DialogOptions) =>
Dialog({ Dialog(extend({ showCancelButton: true }, options));
showCancelButton: true,
...options,
});
Dialog.close = () => { Dialog.close = () => {
if (instance) { if (instance) {
@ -117,7 +112,7 @@ Dialog.setDefaultOptions = (options: DialogOptions) => {
}; };
Dialog.resetDefaultOptions = () => { Dialog.resetDefaultOptions = () => {
Dialog.currentOptions = { ...Dialog.defaultOptions }; Dialog.currentOptions = extend({}, Dialog.defaultOptions);
}; };
Dialog.install = (app: App) => { Dialog.install = (app: App) => {

View File

@ -13,6 +13,7 @@ import {
// Utils // Utils
import { import {
isDef, isDef,
extend,
addUnit, addUnit,
UnknownProp, UnknownProp,
resetScroll, resetScroll,
@ -98,9 +99,7 @@ export const fieldProps = {
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, cellProps, fieldProps, {
...cellProps,
...fieldProps,
rows: [Number, String], rows: [Number, String],
name: String, name: String,
rules: Array as PropType<FieldRule[]>, rules: Array as PropType<FieldRule[]>,
@ -119,7 +118,7 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: null, default: null,
}, },
}, }),
emits: [ emits: [
'blur', 'blur',
@ -415,14 +414,7 @@ export default defineComponent({
return <textarea {...inputAttrs} />; return <textarea {...inputAttrs} />;
} }
return ( return <input {...mapInputType(props.type)} {...inputAttrs} />;
<input
{...{
...mapInputType(props.type),
...inputAttrs,
}}
/>
);
}; };
const renderLeftIcon = () => { const renderLeftIcon = () => {

View File

@ -1,7 +1,7 @@
import { computed, CSSProperties, defineComponent } from 'vue'; import { computed, CSSProperties, defineComponent } from 'vue';
// Utils // Utils
import { createNamespace, addUnit } from '../utils'; import { createNamespace, addUnit, extend } from '../utils';
import { BORDER } from '../utils/constant'; import { BORDER } from '../utils/constant';
import { GRID_KEY, GridProvide } from '../grid/Grid'; import { GRID_KEY, GridProvide } from '../grid/Grid';
@ -18,14 +18,13 @@ const [name, bem] = createNamespace('grid-item');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, routeProps, {
...routeProps,
dot: Boolean, dot: Boolean,
text: String, text: String,
icon: String, icon: String,
badge: [Number, String], badge: [Number, String],
iconPrefix: String, iconPrefix: String,
}, }),
setup(props, { slots }) { setup(props, { slots }) {
const { parent, index } = useParent<GridProvide>(GRID_KEY); const { parent, index } = useParent<GridProvide>(GRID_KEY);

View File

@ -231,15 +231,13 @@ export default defineComponent({
class={[bem(), props.className]} class={[bem(), props.className]}
overlayClass={bem('overlay')} overlayClass={bem('overlay')}
onClosed={onClosed} onClosed={onClosed}
{...{ {...pick(props, [
...pick(props, [ 'show',
'show', 'transition',
'transition', 'overlayStyle',
'overlayStyle', 'closeOnPopstate',
'closeOnPopstate', ])}
]), {...{ 'onUpdate:show': updateShow }}
'onUpdate:show': updateShow,
}}
> >
{renderClose()} {renderClose()}
{renderImages()} {renderImages()}

View File

@ -1,5 +1,5 @@
import { App, CSSProperties, TeleportProps } from 'vue'; import { App, CSSProperties, TeleportProps } from 'vue';
import { ComponentInstance, inBrowser, withInstall } from '../utils'; import { ComponentInstance, extend, inBrowser, withInstall } from '../utils';
import { mountComponent, usePopupState } from '../utils/mount-component'; import { mountComponent, usePopupState } from '../utils/mount-component';
import { Interceptor } from '../utils/interceptor'; import { Interceptor } from '../utils/interceptor';
import { PopupCloseIconPosition } from '../popup'; import { PopupCloseIconPosition } from '../popup';
@ -63,8 +63,8 @@ function initInstance() {
return () => ( return () => (
<VanImagePreview <VanImagePreview
{...state}
{...{ {...{
...state,
onClosed, onClosed,
'onUpdate:show': toggle, 'onUpdate:show': toggle,
}} }}
@ -89,10 +89,7 @@ const ImagePreview = (
const options = Array.isArray(images) ? { images, startPosition } : images; const options = Array.isArray(images) ? { images, startPosition } : images;
instance.open({ instance.open(extend({}, defaultConfig, options));
...defaultConfig,
...options,
});
return instance; return instance;
}; };

View File

@ -1,7 +1,7 @@
import { ref, reactive, computed, CSSProperties, defineComponent } from 'vue'; import { ref, reactive, computed, CSSProperties, defineComponent } from 'vue';
// Utils // Utils
import { createNamespace, getZIndexStyle } from '../utils'; import { createNamespace, extend, getZIndexStyle } from '../utils';
import { BORDER_BOTTOM } from '../utils/constant'; import { BORDER_BOTTOM } from '../utils/constant';
import { INDEX_BAR_KEY, IndexBarProvide } from '../index-bar/IndexBar'; import { INDEX_BAR_KEY, IndexBarProvide } from '../index-bar/IndexBar';
import { getScrollTop, getRootScrollTop } from '../utils/dom/scroll'; import { getScrollTop, getRootScrollTop } from '../utils/dom/scroll';
@ -46,15 +46,14 @@ export default defineComponent({
const { zIndex, highlightColor } = parent.props; const { zIndex, highlightColor } = parent.props;
if (isSticky()) { if (isSticky()) {
return { return extend(getZIndexStyle(zIndex), {
...getZIndexStyle(zIndex),
left: state.left ? `${state.left}px` : undefined, left: state.left ? `${state.left}px` : undefined,
width: state.width ? `${state.width}px` : undefined, width: state.width ? `${state.width}px` : undefined,
transform: state.top transform: state.top
? `translate3d(0, ${state.top}px, 0)` ? `translate3d(0, ${state.top}px, 0)`
: undefined, : undefined,
color: highlightColor, color: highlightColor,
}; });
} }
}); });

View File

@ -1,5 +1,5 @@
import { computed, PropType, defineComponent } from 'vue'; import { computed, PropType, defineComponent } from 'vue';
import { createNamespace, addUnit, getSizeStyle } from '../utils'; import { createNamespace, addUnit, getSizeStyle, extend } from '../utils';
const [name, bem] = createNamespace('loading'); const [name, bem] = createNamespace('loading');
@ -29,10 +29,9 @@ export default defineComponent({
}, },
setup(props, { slots }) { setup(props, { slots }) {
const spinnerStyle = computed(() => ({ const spinnerStyle = computed(() =>
color: props.color, extend({ color: props.color }, getSizeStyle(props.size))
...getSizeStyle(props.size), );
}));
const renderText = () => { const renderText = () => {
if (slots.default) { if (slots.default) {

View File

@ -1,5 +1,5 @@
import { PropType, defineComponent } from 'vue'; import { PropType, defineComponent } from 'vue';
import { createNamespace, UnknownProp } from '../utils'; import { createNamespace, extend, UnknownProp } from '../utils';
import { Popup } from '../popup'; import { Popup } from '../popup';
import { popupSharedProps } from '../popup/shared'; import { popupSharedProps } from '../popup/shared';
@ -10,8 +10,7 @@ export type NotifyType = 'primary' | 'success' | 'danger' | 'warning';
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, popupSharedProps, {
...popupSharedProps,
color: String, color: String,
message: [Number, String], message: [Number, String],
className: UnknownProp, className: UnknownProp,
@ -21,7 +20,7 @@ export default defineComponent({
type: String as PropType<NotifyType>, type: String as PropType<NotifyType>,
default: 'danger', default: 'danger',
}, },
}, }),
setup(props, { slots }) { setup(props, { slots }) {
return () => { return () => {

View File

@ -1,5 +1,11 @@
import { App } from 'vue'; import { App } from 'vue';
import { isObject, inBrowser, ComponentInstance, withInstall } from '../utils'; import {
extend,
isObject,
inBrowser,
withInstall,
ComponentInstance,
} from '../utils';
import { mountComponent, usePopupState } from '../utils/mount-component'; import { mountComponent, usePopupState } from '../utils/mount-component';
import VanNotify, { NotifyType } from './Notify'; import VanNotify, { NotifyType } from './Notify';
@ -29,14 +35,7 @@ function initInstance() {
({ instance } = mountComponent({ ({ instance } = mountComponent({
setup() { setup() {
const { state, toggle } = usePopupState(); const { state, toggle } = usePopupState();
return () => ( return () => <VanNotify {...state} {...{ 'onUpdate:show': toggle }} />;
<VanNotify
{...{
...state,
'onUpdate:show': toggle,
}}
/>
);
}, },
})); }));
} }
@ -50,10 +49,7 @@ function Notify(options: NotifyMessage | NotifyOptions) {
initInstance(); initInstance();
} }
options = { options = extend(Notify.currentOptions, parseOptions(options));
...Notify.currentOptions,
...parseOptions(options),
};
instance.open(options); instance.open(options);
clearTimeout(timer); clearTimeout(timer);

View File

@ -2,6 +2,7 @@ import { PropType, Transition, CSSProperties, defineComponent } from 'vue';
import { import {
noop, noop,
isDef, isDef,
extend,
UnknownProp, UnknownProp,
preventDefault, preventDefault,
createNamespace, createNamespace,
@ -34,10 +35,10 @@ export default defineComponent({
}; };
const renderOverlay = lazyRender(() => { const renderOverlay = lazyRender(() => {
const style: CSSProperties = { const style: CSSProperties = extend(
...getZIndexStyle(props.zIndex), getZIndexStyle(props.zIndex),
...props.customStyle, props.customStyle
}; );
if (isDef(props.duration)) { if (isDef(props.duration)) {
style.animationDuration = `${props.duration}s`; style.animationDuration = `${props.duration}s`;

View File

@ -2,6 +2,7 @@ import { ref, watch, computed, PropType, defineComponent } from 'vue';
// Utils // Utils
import { import {
extend,
unitToPx, unitToPx,
preventDefault, preventDefault,
createNamespace, createNamespace,
@ -68,8 +69,7 @@ export const pickerProps = {
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, pickerProps, {
...pickerProps,
columnsFieldNames: Object as PropType<PickerFieldNames>, columnsFieldNames: Object as PropType<PickerFieldNames>,
columns: { columns: {
type: Array as PropType<PickerOption[] | PickerColumn[]>, type: Array as PropType<PickerOption[] | PickerColumn[]>,
@ -89,20 +89,22 @@ export default defineComponent({
type: String, type: String,
default: 'text', default: 'text',
}, },
}, }),
emits: ['confirm', 'cancel', 'change'], emits: ['confirm', 'cancel', 'change'],
setup(props, { emit, slots }) { setup(props, { emit, slots }) {
const formattedColumns = ref<PickerObjectColumn[]>([]); const formattedColumns = ref<PickerObjectColumn[]>([]);
const { text: textKey, values: valuesKey, children: childrenKey } = { const { text: textKey, values: valuesKey, children: childrenKey } = extend(
// compatible with valueKey prop {
text: props.valueKey, // compatible with valueKey prop
values: 'values', text: props.valueKey,
children: 'children', values: 'values',
...props.columnsFieldNames, children: 'children',
}; },
props.columnsFieldNames
);
const { children, linkChildren } = useChildren<ComponentInstance>( const { children, linkChildren } = useChildren<ComponentInstance>(
PICKER_KEY PICKER_KEY

View File

@ -14,6 +14,7 @@ import { Instance, createPopper, offsetModifier } from '@vant/popperjs';
// Utils // Utils
import { import {
pick, pick,
extend,
UnknownProp, UnknownProp,
createNamespace, createNamespace,
ComponentInstance, ComponentInstance,
@ -129,12 +130,11 @@ export default defineComponent({
gpuAcceleration: false, gpuAcceleration: false,
}, },
}, },
{ extend({}, offsetModifier, {
...offsetModifier,
options: { options: {
offset: props.offset, offset: props.offset,
}, },
}, }),
], ],
}); });
}; };
@ -228,11 +228,9 @@ export default defineComponent({
transition="van-popover-zoom" transition="van-popover-zoom"
lockScroll={false} lockScroll={false}
onTouchstart={onTouchstart} onTouchstart={onTouchstart}
{...{ {...attrs}
...attrs, {...pick(props, popupProps)}
...pick(props, popupProps), {...{ 'onUpdate:show': updateShow }}
'onUpdate:show': updateShow,
}}
> >
<div class={bem('arrow')} /> <div class={bem('arrow')} />
<div role="menu" class={bem('content')}> <div role="menu" class={bem('content')}>

View File

@ -14,7 +14,7 @@ import {
// Utils // Utils
import { popupSharedProps } from './shared'; import { popupSharedProps } from './shared';
import { createNamespace, isDef } from '../utils'; import { createNamespace, extend, isDef } from '../utils';
// Composables // Composables
import { useEventListener } from '@vant/use'; import { useEventListener } from '@vant/use';
@ -43,8 +43,7 @@ export default defineComponent({
inheritAttrs: false, inheritAttrs: false,
props: { props: extend({}, popupSharedProps, {
...popupSharedProps,
round: Boolean, round: Boolean,
closeable: Boolean, closeable: Boolean,
transition: String, transition: String,
@ -62,7 +61,7 @@ export default defineComponent({
type: String as PropType<PopupCloseIconPosition>, type: String as PropType<PopupCloseIconPosition>,
default: 'top-right', default: 'top-right',
}, },
}, }),
emits: [ emits: [
'open', 'open',

View File

@ -3,6 +3,7 @@ import { ref, PropType, defineComponent } from 'vue';
// Utils // Utils
import { import {
pick, pick,
extend,
createNamespace, createNamespace,
preventDefault, preventDefault,
ComponentInstance, ComponentInstance,
@ -22,8 +23,7 @@ export type SearchShape = 'square' | 'round';
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, fieldProps, {
...fieldProps,
label: String, label: String,
actionText: String, actionText: String,
background: String, background: String,
@ -40,7 +40,7 @@ export default defineComponent({
type: String, type: String,
default: 'search', default: 'search',
}, },
}, }),
emits: ['search', 'cancel', 'update:modelValue'], emits: ['search', 'cancel', 'update:modelValue'],
@ -96,10 +96,7 @@ export default defineComponent({
>; >;
const renderField = () => { const renderField = () => {
const fieldAttrs = { const fieldAttrs = extend({}, attrs, pick(props, fieldPropNames));
...attrs,
...pick(props, fieldPropNames),
};
const onInput = (value: string) => emit('update:modelValue', value); const onInput = (value: string) => emit('update:modelValue', value);

View File

@ -1,7 +1,7 @@
import { PropType, defineComponent } from 'vue'; import { PropType, defineComponent } from 'vue';
// Utils // Utils
import { createNamespace, pick } from '../utils'; import { createNamespace, extend, pick } from '../utils';
import { popupSharedProps, popupSharedPropKeys } from '../popup/shared'; import { popupSharedProps, popupSharedPropKeys } from '../popup/shared';
// Components // Components
@ -45,8 +45,7 @@ const [name, bem, t] = createNamespace('share-sheet');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, popupSharedProps, {
...popupSharedProps,
title: String, title: String,
cancelText: String, cancelText: String,
description: String, description: String,
@ -62,7 +61,7 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
}, }),
emits: ['cancel', 'select', 'update:show'], emits: ['cancel', 'select', 'update:show'],
@ -143,10 +142,8 @@ export default defineComponent({
round round
class={bem()} class={bem()}
position="bottom" position="bottom"
{...{ {...pick(props, popupKeys)}
...pick(props, popupKeys), {...{ 'onUpdate:show': updateShow }}
'onUpdate:show': updateShow,
}}
> >
{renderHeader()} {renderHeader()}
{renderRows()} {renderRows()}

View File

@ -1,7 +1,7 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
// Utils // Utils
import { createNamespace } from '../utils'; import { createNamespace, extend } from '../utils';
import { SIDEBAR_KEY, SidebarProvide } from '../sidebar/Sidebar'; import { SIDEBAR_KEY, SidebarProvide } from '../sidebar/Sidebar';
// Composables // Composables
@ -16,13 +16,12 @@ const [name, bem] = createNamespace('sidebar-item');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, routeProps, {
...routeProps,
dot: Boolean, dot: Boolean,
title: String, title: String,
badge: [Number, String], badge: [Number, String],
disabled: Boolean, disabled: Boolean,
}, }),
emits: ['click'], emits: ['click'],

View File

@ -10,6 +10,7 @@ import {
// Utils // Utils
import { import {
extend,
isHidden, isHidden,
unitToPx, unitToPx,
getScrollTop, getScrollTop,
@ -76,12 +77,11 @@ export default defineComponent({
return; return;
} }
const style: CSSProperties = { const style: CSSProperties = extend(getZIndexStyle(props.zIndex), {
...getZIndexStyle(props.zIndex),
width: `${state.width}px`, width: `${state.width}px`,
height: `${state.height}px`, height: `${state.height}px`,
[props.position]: `${offset.value}px`, [props.position]: `${offset.value}px`,
}; });
if (state.transform) { if (state.transform) {
style.transform = `translate3d(0, ${state.transform}px, 0)`; style.transform = `translate3d(0, ${state.transform}px, 0)`;

View File

@ -8,7 +8,7 @@ import {
} from 'vue'; } from 'vue';
// Utils // Utils
import { createNamespace, UnknownProp } from '../utils'; import { createNamespace, extend, UnknownProp } from '../utils';
import { TABS_KEY, TabsProvide } from '../tabs/Tabs'; import { TABS_KEY, TabsProvide } from '../tabs/Tabs';
// Composables // Composables
@ -23,8 +23,7 @@ const [name, bem] = createNamespace('tab');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, routeProps, {
...routeProps,
dot: Boolean, dot: Boolean,
name: [Number, String], name: [Number, String],
badge: [Number, String], badge: [Number, String],
@ -32,7 +31,7 @@ export default defineComponent({
disabled: Boolean, disabled: Boolean,
titleClass: UnknownProp, titleClass: UnknownProp,
titleStyle: [String, Object] as PropType<string | CSSProperties>, titleStyle: [String, Object] as PropType<string | CSSProperties>,
}, }),
setup(props, { slots }) { setup(props, { slots }) {
const inited = ref(false); const inited = ref(false);

View File

@ -1,7 +1,7 @@
import { computed, getCurrentInstance, defineComponent } from 'vue'; import { computed, getCurrentInstance, defineComponent } from 'vue';
// Utils // Utils
import { createNamespace, isObject } from '../utils'; import { createNamespace, extend, isObject } from '../utils';
import { TABBAR_KEY, TabbarProvide } from '../tabbar/Tabbar'; import { TABBAR_KEY, TabbarProvide } from '../tabbar/Tabbar';
// Composables // Composables
@ -17,14 +17,13 @@ const [name, bem] = createNamespace('tabbar-item');
export default defineComponent({ export default defineComponent({
name, name,
props: { props: extend({}, routeProps, {
...routeProps,
dot: Boolean, dot: Boolean,
icon: String, icon: String,
name: [Number, String], name: [Number, String],
badge: [Number, String], badge: [Number, String],
iconPrefix: String, iconPrefix: String,
}, }),
emits: ['click'], emits: ['click'],

View File

@ -1,5 +1,11 @@
import { ref, App, TeleportProps, getCurrentInstance } from 'vue'; import { ref, App, TeleportProps, getCurrentInstance } from 'vue';
import { isObject, inBrowser, withInstall, ComponentInstance } from '../utils'; import {
extend,
isObject,
inBrowser,
withInstall,
ComponentInstance,
} from '../utils';
import { mountComponent, usePopupState } from '../utils/mount-component'; import { mountComponent, usePopupState } from '../utils/mount-component';
import VanToast, { ToastType, ToastPosition } from './Toast'; import VanToast, { ToastType, ToastPosition } from './Toast';
import type { LoadingType } from '../loading'; import type { LoadingType } from '../loading';
@ -51,7 +57,7 @@ const defaultOptions: ToastOptions = {
let queue: ComponentInstance[] = []; let queue: ComponentInstance[] = [];
let allowMultiple = false; let allowMultiple = false;
let currentOptions = { ...defaultOptions }; let currentOptions = extend({}, defaultOptions);
// default options of specific type // default options of specific type
let defaultOptionsMap: Record<string, ToastOptions | null> = {}; let defaultOptionsMap: Record<string, ToastOptions | null> = {};
@ -78,7 +84,6 @@ function createInstance() {
const render = () => { const render = () => {
const attrs: Record<string, unknown> = { const attrs: Record<string, unknown> = {
...state,
onClosed, onClosed,
'onUpdate:show': toggle, 'onUpdate:show': toggle,
}; };
@ -87,7 +92,7 @@ function createInstance() {
attrs.message = message.value; attrs.message = message.value;
} }
return <VanToast {...attrs} />; return <VanToast {...state} {...attrs} />;
}; };
// rewrite render function // rewrite render function
@ -121,20 +126,20 @@ function Toast(options: string | ToastOptions = {}) {
const toast = getInstance(); const toast = getInstance();
const parsedOptions = parseOptions(options); const parsedOptions = parseOptions(options);
toast.open({ toast.open(
...currentOptions, extend(
...defaultOptionsMap[parsedOptions.type || currentOptions.type!], {},
...parsedOptions, currentOptions,
}); defaultOptionsMap[parsedOptions.type || currentOptions.type!],
parsedOptions
)
);
return toast; return toast;
} }
const createMethod = (type: ToastType) => (options: string | ToastOptions) => const createMethod = (type: ToastType) => (options: string | ToastOptions) =>
Toast({ Toast(extend({ type }, parseOptions(options)));
type,
...parseOptions(options),
});
Toast.loading = createMethod('loading'); Toast.loading = createMethod('loading');
Toast.success = createMethod('success'); Toast.success = createMethod('success');
@ -171,7 +176,7 @@ Toast.resetDefaultOptions = (type?: ToastType) => {
if (typeof type === 'string') { if (typeof type === 'string') {
defaultOptionsMap[type] = null; defaultOptionsMap[type] = null;
} else { } else {
currentOptions = { ...defaultOptions }; currentOptions = extend({}, defaultOptions);
defaultOptionsMap = {}; defaultOptionsMap = {};
} }
}; };

View File

@ -1,7 +1,13 @@
import { ref, reactive, PropType, defineComponent } from 'vue'; import { ref, reactive, PropType, defineComponent } from 'vue';
// Utils // Utils
import { pick, isPromise, getSizeStyle, ComponentInstance } from '../utils'; import {
pick,
extend,
isPromise,
getSizeStyle,
ComponentInstance,
} from '../utils';
import { import {
bem, bem,
name, name,
@ -250,12 +256,16 @@ export default defineComponent({
.map((item) => item.content || item.url) .map((item) => item.content || item.url)
.filter(Boolean) as string[]; .filter(Boolean) as string[];
imagePreview = ImagePreview({ imagePreview = ImagePreview(
images, extend(
startPosition: imageFiles.indexOf(item), {
onClose: onClosePreview, images,
...props.previewOptions, startPosition: imageFiles.indexOf(item),
}); onClose: onClosePreview,
},
props.previewOptions
)
);
} }
}; };
@ -281,10 +291,10 @@ export default defineComponent({
'beforeDelete', 'beforeDelete',
] as const; ] as const;
const previewData = { const previewData = extend(
...pick(props, needPickData), pick(props, needPickData),
...pick(item, needPickData, true), pick(item, needPickData, true)
}; );
return ( return (
<UploaderPreviewItem <UploaderPreviewItem

View File

@ -2,7 +2,7 @@ import { PropType, defineComponent } from 'vue';
// Utils // Utils
import { bem, isImageFile, UploaderFileListItem } from './utils'; import { bem, isImageFile, UploaderFileListItem } from './utils';
import { isDef, getSizeStyle } from '../utils'; import { isDef, getSizeStyle, extend } from '../utils';
import { callInterceptor, Interceptor } from '../utils/interceptor'; import { callInterceptor, Interceptor } from '../utils/interceptor';
// Components // Components
@ -77,7 +77,7 @@ export default defineComponent({
const { index, item } = props; const { index, item } = props;
return ( return (
<div class={bem('preview-cover')}> <div class={bem('preview-cover')}>
{slots['preview-cover']({ index, ...item })} {slots['preview-cover'](extend({ index }, item))}
</div> </div>
); );
} }

View File

@ -2,6 +2,8 @@ import { PropType, ComponentPublicInstance } from 'vue';
export function noop() {} export function noop() {}
export const extend = Object.assign;
export const inBrowser = typeof window !== 'undefined'; export const inBrowser = typeof window !== 'undefined';
// unknown type for Vue prop // unknown type for Vue prop