diff --git a/src/action-bar-button/ActionBarButton.tsx b/src/action-bar-button/ActionBarButton.tsx index ffa3edbcf..f5bcdf920 100644 --- a/src/action-bar-button/ActionBarButton.tsx +++ b/src/action-bar-button/ActionBarButton.tsx @@ -1,5 +1,5 @@ import { computed, PropType, defineComponent } from 'vue'; -import { createNamespace } from '../utils'; +import { extend, createNamespace } from '../utils'; import { ACTION_BAR_KEY } from '../action-bar/ActionBar'; // Composables @@ -15,15 +15,14 @@ const [name, bem] = createNamespace('action-bar-button'); export default defineComponent({ name, - props: { - ...routeProps, + props: extend({}, routeProps, { type: String as PropType, text: String, icon: String, color: String, loading: Boolean, disabled: Boolean, - }, + }), setup(props, { slots }) { const route = useRoute(); diff --git a/src/action-bar-icon/ActionBarIcon.tsx b/src/action-bar-icon/ActionBarIcon.tsx index 17f3cef19..b36603564 100644 --- a/src/action-bar-icon/ActionBarIcon.tsx +++ b/src/action-bar-icon/ActionBarIcon.tsx @@ -1,5 +1,5 @@ import { defineComponent } from 'vue'; -import { createNamespace, UnknownProp } from '../utils'; +import { extend, createNamespace, UnknownProp } from '../utils'; import { ACTION_BAR_KEY } from '../action-bar/ActionBar'; // Composables @@ -15,15 +15,14 @@ const [name, bem] = createNamespace('action-bar-icon'); export default defineComponent({ name, - props: { - ...routeProps, + props: extend({}, routeProps, { dot: Boolean, text: String, icon: String, color: String, badge: [Number, String], iconClass: UnknownProp, - }, + }), setup(props, { slots }) { const route = useRoute(); diff --git a/src/action-sheet/ActionSheet.tsx b/src/action-sheet/ActionSheet.tsx index d22b0ec17..b98d0ac84 100644 --- a/src/action-sheet/ActionSheet.tsx +++ b/src/action-sheet/ActionSheet.tsx @@ -1,7 +1,7 @@ import { nextTick, PropType, defineComponent } from 'vue'; // Utils -import { createNamespace, pick } from '../utils'; +import { pick, extend, createNamespace } from '../utils'; // Components import { Icon } from '../icon'; @@ -24,8 +24,7 @@ export type ActionSheetAction = { export default defineComponent({ name, - props: { - ...popupSharedProps, + props: extend({}, popupSharedProps, { title: String, actions: Array as PropType, cancelText: String, @@ -48,7 +47,7 @@ export default defineComponent({ type: Boolean, default: true, }, - }, + }), emits: ['select', 'cancel', 'update:show'], @@ -157,10 +156,8 @@ export default defineComponent({ round={props.round} position="bottom" safeAreaInsetBottom={props.safeAreaInsetBottom} - {...{ - ...pick(props, popupSharedPropKeys), - 'onUpdate:show': updateShow, - }} + {...pick(props, popupSharedPropKeys)} + {...{ 'onUpdate:show': updateShow }} > {renderHeader()} {renderDescription()} diff --git a/src/address-edit/AddressEdit.tsx b/src/address-edit/AddressEdit.tsx index 3a45dcfba..bccf86645 100644 --- a/src/address-edit/AddressEdit.tsx +++ b/src/address-edit/AddressEdit.tsx @@ -10,6 +10,7 @@ import { // Utils import { + extend, isObject, isMobile, createNamespace, @@ -100,7 +101,7 @@ export default defineComponent({ }, addressInfo: { type: Object as PropType>, - default: () => ({ ...defaultData }), + default: () => extend({}, defaultData), }, telValidator: { type: Function as PropType<(val: string) => boolean>, @@ -321,10 +322,7 @@ export default defineComponent({ watch( () => props.addressInfo, (value) => { - state.data = { - ...defaultData, - ...value, - }; + state.data = extend({}, defaultData, value); setAreaCode(value.areaCode); }, { diff --git a/src/address-list/AddressListItem.tsx b/src/address-list/AddressListItem.tsx index 6d00fcb5c..02195bde6 100644 --- a/src/address-list/AddressListItem.tsx +++ b/src/address-list/AddressListItem.tsx @@ -1,7 +1,7 @@ import { PropType, defineComponent } from 'vue'; // Utils -import { createNamespace } from '../utils'; +import { createNamespace, extend } from '../utils'; // Components import { Tag } from '../tag'; @@ -102,7 +102,7 @@ export default defineComponent({ border={false} valueClass={bem('value')} /> - {slots.bottom?.({ ...props.address, disabled })} + {slots.bottom?.(extend({}, props.address, { disabled }))} ); }; diff --git a/src/area/Area.tsx b/src/area/Area.tsx index 0be1b61e8..43243d25e 100644 --- a/src/area/Area.tsx +++ b/src/area/Area.tsx @@ -12,7 +12,7 @@ import { // Utils import { deepClone } from '../utils/deep-clone'; -import { pick, createNamespace, ComponentInstance } from '../utils'; +import { pick, createNamespace, ComponentInstance, extend } from '../utils'; import { pickerProps } from '../picker/Picker'; // Composables @@ -45,8 +45,7 @@ type ColumnType = 'province' | 'county' | 'city'; export default defineComponent({ name, - props: { - ...pickerProps, + props: extend({}, pickerProps, { value: String, areaList: { type: Object as PropType, @@ -64,7 +63,7 @@ export default defineComponent({ type: Array as PropType, default: () => [], }, - }, + }), emits: ['change', 'confirm'], diff --git a/src/button/Button.tsx b/src/button/Button.tsx index f47d7e077..8c4e1800a 100644 --- a/src/button/Button.tsx +++ b/src/button/Button.tsx @@ -6,7 +6,7 @@ import { } from 'vue'; // Utils -import { createNamespace } from '../utils'; +import { createNamespace, extend } from '../utils'; import { BORDER_SURROUND } from '../utils/constant'; import { useRoute, routeProps } from '../composables/use-route'; @@ -28,8 +28,7 @@ export type ButtonSize = 'large' | 'normal' | 'small' | 'mini'; export default defineComponent({ name, - props: { - ...routeProps, + props: extend({}, routeProps, { text: String, icon: String, color: String, @@ -64,7 +63,7 @@ export default defineComponent({ type: String as PropType<'left' | 'right'>, default: 'left', }, - }, + }), emits: ['click'], diff --git a/src/cascader/Cascader.tsx b/src/cascader/Cascader.tsx index 28dc16c8e..c5e2226ac 100644 --- a/src/cascader/Cascader.tsx +++ b/src/cascader/Cascader.tsx @@ -1,5 +1,5 @@ import { nextTick, PropType, reactive, watch, defineComponent } from 'vue'; -import { createNamespace } from '../utils'; +import { createNamespace, extend } from '../utils'; // Components import { Tab } from '../tab'; @@ -62,12 +62,14 @@ export default defineComponent({ activeTab: 0, }); - const { text: textKey, value: valueKey, children: childrenKey } = { - text: 'text', - value: 'value', - children: 'children', - ...props.fieldNames, - }; + const { text: textKey, value: valueKey, children: childrenKey } = extend( + { + text: 'text', + value: 'value', + children: 'children', + }, + props.fieldNames + ); const getSelectedOptionsByValue = ( options: CascaderOption[], diff --git a/src/cell/Cell.tsx b/src/cell/Cell.tsx index 8da2f6d28..f312b72ca 100644 --- a/src/cell/Cell.tsx +++ b/src/cell/Cell.tsx @@ -1,7 +1,7 @@ import { PropType, CSSProperties, defineComponent } from 'vue'; // Utils -import { createNamespace, isDef, UnknownProp } from '../utils'; +import { createNamespace, extend, isDef, UnknownProp } from '../utils'; // Composables import { useRoute, routeProps } from '../composables/use-route'; @@ -41,10 +41,7 @@ export const cellProps = { export default defineComponent({ name, - props: { - ...cellProps, - ...routeProps, - }, + props: extend({}, cellProps, routeProps), setup(props, { slots }) { const route = useRoute(); diff --git a/src/checkbox/Checkbox.tsx b/src/checkbox/Checkbox.tsx index fa96224b8..4b3a1c43a 100644 --- a/src/checkbox/Checkbox.tsx +++ b/src/checkbox/Checkbox.tsx @@ -1,7 +1,7 @@ import { computed, watch, defineComponent } from 'vue'; // Utils -import { createNamespace, pick } from '../utils'; +import { createNamespace, extend, pick } from '../utils'; import { CHECKBOX_GROUP_KEY, CheckboxGroupProvide, @@ -20,13 +20,12 @@ const [name, bem] = createNamespace('checkbox'); export default defineComponent({ name, - props: { - ...checkerProps, + props: extend({}, checkerProps, { bindGroup: { type: Boolean, default: true, }, - }, + }), emits: ['change', 'update:modelValue'], diff --git a/src/checkbox/Checker.tsx b/src/checkbox/Checker.tsx index b30b55996..52b8f52b4 100644 --- a/src/checkbox/Checker.tsx +++ b/src/checkbox/Checker.tsx @@ -1,5 +1,5 @@ import { ref, computed, PropType, defineComponent } from 'vue'; -import { addUnit, UnknownProp } from '../utils'; +import { addUnit, extend, UnknownProp } from '../utils'; import { Icon } from '../icon'; export type CheckerShape = 'square' | 'round'; @@ -29,8 +29,7 @@ export const checkerProps = { }; export default defineComponent({ - props: { - ...checkerProps, + props: extend({}, checkerProps, { role: String, parent: Object as PropType, checked: Boolean, @@ -40,9 +39,9 @@ export default defineComponent({ }, bem: { type: Function, - required: true, + required: true as const, }, - }, + }), emits: ['click', 'toggle'], diff --git a/src/collapse-item/CollapseItem.tsx b/src/collapse-item/CollapseItem.tsx index 5dbc71831..a72e7488e 100644 --- a/src/collapse-item/CollapseItem.tsx +++ b/src/collapse-item/CollapseItem.tsx @@ -2,7 +2,7 @@ import { ref, watch, computed, nextTick, defineComponent } from 'vue'; // Utils import { cellProps } from '../cell/Cell'; -import { createNamespace, pick } from '../utils'; +import { createNamespace, extend, pick } from '../utils'; import { COLLAPSE_KEY, CollapseProvide } from '../collapse/Collapse'; // Composables @@ -18,8 +18,7 @@ const [name, bem] = createNamespace('collapse-item'); export default defineComponent({ name, - props: { - ...cellProps, + props: extend({}, cellProps, { name: [Number, String], disabled: Boolean, readonly: Boolean, @@ -27,7 +26,7 @@ export default defineComponent({ type: Boolean, default: true, }, - }, + }), setup(props, { slots }) { const wrapperRef = ref(); diff --git a/src/contact-edit/ContactEdit.tsx b/src/contact-edit/ContactEdit.tsx index 1cb4e953f..85b146374 100644 --- a/src/contact-edit/ContactEdit.tsx +++ b/src/contact-edit/ContactEdit.tsx @@ -1,7 +1,7 @@ import { watch, reactive, PropType, defineComponent } from 'vue'; // Utils -import { isMobile, createNamespace } from '../utils'; +import { isMobile, createNamespace, extend } from '../utils'; // Components import { Cell } from '../cell'; @@ -35,7 +35,7 @@ export default defineComponent({ setDefaultLabel: String, contactInfo: { type: Object as PropType, - default: () => ({ ...DEFAULT_CONTACT }), + default: () => extend({}, DEFAULT_CONTACT), }, telValidator: { type: Function as PropType<(val: string) => boolean>, @@ -46,10 +46,7 @@ export default defineComponent({ emits: ['save', 'delete', 'change-default'], setup(props, { emit }) { - const contact = reactive({ - ...DEFAULT_CONTACT, - ...props.contactInfo, - }); + const contact = reactive(extend({}, DEFAULT_CONTACT, props.contactInfo)); const onSave = () => { if (!props.isSaving) { diff --git a/src/datetime-picker/DatePicker.tsx b/src/datetime-picker/DatePicker.tsx index 6bbc89e61..817f71ccd 100644 --- a/src/datetime-picker/DatePicker.tsx +++ b/src/datetime-picker/DatePicker.tsx @@ -12,6 +12,7 @@ import { import { pick, range, + extend, isDate, padZero, createNamespace, @@ -39,8 +40,7 @@ const [name] = createNamespace('date-picker'); export default defineComponent({ name, - props: { - ...sharedProps, + props: extend({}, sharedProps, { modelValue: Date, type: { type: String as PropType, @@ -56,7 +56,7 @@ export default defineComponent({ default: () => new Date(currentYear + 10, 11, 31), validator: isDate, }, - }, + }), emits: ['confirm', 'cancel', 'change', 'update:modelValue'], diff --git a/src/datetime-picker/DatetimePicker.tsx b/src/datetime-picker/DatetimePicker.tsx index 52b00f0ca..b1e3e4d55 100644 --- a/src/datetime-picker/DatetimePicker.tsx +++ b/src/datetime-picker/DatetimePicker.tsx @@ -1,5 +1,5 @@ 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 TimePicker from './TimePicker'; import DatePicker from './DatePicker'; @@ -12,11 +12,9 @@ const datePickerProps = Object.keys(DatePicker.props); export default defineComponent({ name, - props: { - ...TimePicker.props, - ...DatePicker.props, + props: extend({}, TimePicker.props, DatePicker.props, { modelValue: [String, Date], - }, + }), setup(props, { attrs, slots }) { const root = ref(); @@ -38,7 +36,8 @@ export default defineComponent({ v-slots={slots} ref={root} class={bem()} - {...{ ...inheritProps, ...attrs }} + {...inheritProps} + {...attrs} /> ); }; diff --git a/src/datetime-picker/TimePicker.tsx b/src/datetime-picker/TimePicker.tsx index 895c12073..f11aa60a5 100644 --- a/src/datetime-picker/TimePicker.tsx +++ b/src/datetime-picker/TimePicker.tsx @@ -11,6 +11,7 @@ import { import { pick, range, + extend, padZero, createNamespace, ComponentInstance, @@ -28,8 +29,7 @@ const [name] = createNamespace('time-picker'); export default defineComponent({ name, - props: { - ...sharedProps, + props: extend({}, sharedProps, { modelValue: String, minHour: { type: [Number, String], @@ -47,7 +47,7 @@ export default defineComponent({ type: [Number, String], default: 59, }, - }, + }), emits: ['confirm', 'cancel', 'change', 'update:modelValue'], diff --git a/src/datetime-picker/utils.ts b/src/datetime-picker/utils.ts index 4f5408da9..408e11003 100644 --- a/src/datetime-picker/utils.ts +++ b/src/datetime-picker/utils.ts @@ -1,4 +1,5 @@ import { PropType } from 'vue'; +import { extend } from '../utils'; import { pickerProps } from '../picker/Picker'; export type ColumnType = 'year' | 'month' | 'day' | 'hour' | 'minute'; @@ -11,15 +12,14 @@ export type DatetimePickerType = | 'month-day' | 'year-month'; -export const sharedProps = { - ...pickerProps, +export const sharedProps = extend({}, pickerProps, { filter: Function as PropType<(type: string, values: string[]) => string[]>, columnsOrder: Array as PropType, formatter: { type: Function as PropType<(type: string, value: string) => string>, default: (type: string, value: string) => value, }, -}; +}); export const pickerKeys = Object.keys(pickerProps) as Array< keyof typeof pickerProps diff --git a/src/dialog/Dialog.tsx b/src/dialog/Dialog.tsx index 20a6332e9..23f2a3dfd 100644 --- a/src/dialog/Dialog.tsx +++ b/src/dialog/Dialog.tsx @@ -4,6 +4,7 @@ import { PropType, reactive, defineComponent } from 'vue'; import { callInterceptor, Interceptor } from '../utils/interceptor'; import { pick, + extend, addUnit, isFunction, UnknownProp, @@ -34,8 +35,7 @@ const popupKeys = [ export default defineComponent({ name, - props: { - ...popupSharedProps, + props: extend({}, popupSharedProps, { title: String, theme: String as PropType, width: [Number, String], @@ -63,7 +63,7 @@ export default defineComponent({ type: Boolean, default: true, }, - }, + }), emits: ['confirm', 'cancel', 'update:show'], @@ -231,10 +231,8 @@ export default defineComponent({ class={[bem([theme]), className]} style={{ width: addUnit(width) }} aria-labelledby={title || message} - {...{ - ...pick(props, popupKeys), - 'onUpdate:show': updateShow, - }} + {...pick(props, popupKeys)} + {...{ 'onUpdate:show': updateShow }} > {renderTitle()} {renderContent()} diff --git a/src/dialog/function-call.tsx b/src/dialog/function-call.tsx index 55a2d46ed..13342175e 100644 --- a/src/dialog/function-call.tsx +++ b/src/dialog/function-call.tsx @@ -1,5 +1,5 @@ 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 { mountComponent, usePopupState } from '../utils/mount-component'; import VanDialog, { @@ -40,7 +40,7 @@ function initInstance() { const Wrapper = { setup() { const { state, toggle } = usePopupState(); - return () => ; + return () => ; }, }; @@ -58,13 +58,13 @@ function Dialog(options: DialogOptions) { initInstance(); } - instance.open({ - ...Dialog.currentOptions, - ...options, - callback: (action: DialogAction) => { - (action === 'confirm' ? resolve : reject)(action); - }, - }); + instance.open( + extend({}, Dialog.currentOptions, options, { + callback: (action: DialogAction) => { + (action === 'confirm' ? resolve : reject)(action); + }, + }) + ); }); } @@ -94,17 +94,12 @@ Dialog.defaultOptions = { closeOnClickOverlay: false, }; -Dialog.currentOptions = { - ...Dialog.defaultOptions, -}; +Dialog.currentOptions = extend({}, Dialog.defaultOptions); Dialog.alert = Dialog; Dialog.confirm = (options: DialogOptions) => - Dialog({ - showCancelButton: true, - ...options, - }); + Dialog(extend({ showCancelButton: true }, options)); Dialog.close = () => { if (instance) { @@ -117,7 +112,7 @@ Dialog.setDefaultOptions = (options: DialogOptions) => { }; Dialog.resetDefaultOptions = () => { - Dialog.currentOptions = { ...Dialog.defaultOptions }; + Dialog.currentOptions = extend({}, Dialog.defaultOptions); }; Dialog.install = (app: App) => { diff --git a/src/field/Field.tsx b/src/field/Field.tsx index 86bf8fb20..7ba15c4f4 100644 --- a/src/field/Field.tsx +++ b/src/field/Field.tsx @@ -13,6 +13,7 @@ import { // Utils import { isDef, + extend, addUnit, UnknownProp, resetScroll, @@ -98,9 +99,7 @@ export const fieldProps = { export default defineComponent({ name, - props: { - ...cellProps, - ...fieldProps, + props: extend({}, cellProps, fieldProps, { rows: [Number, String], name: String, rules: Array as PropType, @@ -119,7 +118,7 @@ export default defineComponent({ type: Boolean, default: null, }, - }, + }), emits: [ 'blur', @@ -415,14 +414,7 @@ export default defineComponent({ return