feat: update time-picker
parent
cd80ce622b
commit
6ab243ffaa
|
@ -1 +1 @@
|
||||||
Subproject commit c2521df74700792b5cd6c353cf9fce91fbd40e19
|
Subproject commit aae9db4ae607a00f4c8482c159bfaf71fe982595
|
|
@ -1,4 +1,5 @@
|
||||||
import omit from 'omit.js';
|
import omit from 'omit.js';
|
||||||
|
import { inject, provide } from 'vue';
|
||||||
import VcTimePicker from '../vc-time-picker';
|
import VcTimePicker from '../vc-time-picker';
|
||||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||||
import BaseMixin from '../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
|
@ -13,11 +14,9 @@ import {
|
||||||
getOptionProps,
|
getOptionProps,
|
||||||
getComponent,
|
getComponent,
|
||||||
isValidElement,
|
isValidElement,
|
||||||
getListeners,
|
|
||||||
} from '../_util/props-util';
|
} from '../_util/props-util';
|
||||||
import { cloneElement } from '../_util/vnode';
|
import { cloneElement } from '../_util/vnode';
|
||||||
import { ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumerProps } from '../config-provider';
|
||||||
import Base from '../base';
|
|
||||||
import {
|
import {
|
||||||
checkValidate,
|
checkValidate,
|
||||||
stringToMoment,
|
stringToMoment,
|
||||||
|
@ -69,10 +68,21 @@ export const TimePickerProps = () => ({
|
||||||
clearIcon: PropTypes.any,
|
clearIcon: PropTypes.any,
|
||||||
locale: PropTypes.object,
|
locale: PropTypes.object,
|
||||||
valueFormat: PropTypes.string,
|
valueFormat: PropTypes.string,
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
onAmPmChange: PropTypes.func,
|
||||||
|
onOpen: PropTypes.func,
|
||||||
|
onClose: PropTypes.func,
|
||||||
|
onFocus: PropTypes.func,
|
||||||
|
onBlur: PropTypes.func,
|
||||||
|
onKeydown: PropTypes.func,
|
||||||
|
onOpenChange: PropTypes.func,
|
||||||
|
'onUpdate:value': PropTypes.func,
|
||||||
|
'onUpdate:open': PropTypes.func,
|
||||||
});
|
});
|
||||||
|
|
||||||
const TimePicker = {
|
const TimePicker = {
|
||||||
name: 'ATimePicker',
|
name: 'ATimePicker',
|
||||||
|
inheritAttrs: false,
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
props: initDefaultProps(TimePickerProps(), {
|
props: initDefaultProps(TimePickerProps(), {
|
||||||
align: {
|
align: {
|
||||||
|
@ -88,18 +98,15 @@ const TimePicker = {
|
||||||
focusOnOpen: true,
|
focusOnOpen: true,
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
}),
|
}),
|
||||||
model: {
|
created() {
|
||||||
prop: 'value',
|
provide('savePopupRef', this.savePopupRef);
|
||||||
event: 'change',
|
|
||||||
},
|
},
|
||||||
provide() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
savePopupRef: this.savePopupRef,
|
configProvider: inject('configProvider', ConfigConsumerProps),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: {
|
|
||||||
configProvider: { default: () => ConfigConsumerProps },
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
const { value, defaultValue, valueFormat } = this;
|
const { value, defaultValue, valueFormat } = this;
|
||||||
|
|
||||||
|
@ -148,16 +155,17 @@ const TimePicker = {
|
||||||
savePopupRef(ref) {
|
savePopupRef(ref) {
|
||||||
this.popupRef = ref;
|
this.popupRef = ref;
|
||||||
},
|
},
|
||||||
|
saveTimePicker(timePickerRef) {
|
||||||
|
this.timePickerRef = timePickerRef;
|
||||||
|
},
|
||||||
handleChange(value) {
|
handleChange(value) {
|
||||||
if (!hasProp(this, 'value')) {
|
if (!hasProp(this, 'value')) {
|
||||||
this.setState({ sValue: value });
|
this.setState({ sValue: value });
|
||||||
}
|
}
|
||||||
const { format = 'HH:mm:ss' } = this;
|
const { format = 'HH:mm:ss' } = this;
|
||||||
this.$emit(
|
const val = this.valueFormat ? momentToString(value, this.valueFormat) : value;
|
||||||
'change',
|
this.$emit('update:value', val);
|
||||||
this.valueFormat ? momentToString(value, this.valueFormat) : value,
|
this.$emit('change', val, (value && value.format(format)) || '');
|
||||||
(value && value.format(format)) || '',
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleOpenClose({ open }) {
|
handleOpenClose({ open }) {
|
||||||
|
@ -166,11 +174,11 @@ const TimePicker = {
|
||||||
},
|
},
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
this.$refs.timePicker.focus();
|
this.timePickerRef.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
blur() {
|
blur() {
|
||||||
this.$refs.timePicker.blur();
|
this.timePickerRef.blur();
|
||||||
},
|
},
|
||||||
|
|
||||||
renderInputIcon(prefixCls) {
|
renderInputIcon(prefixCls) {
|
||||||
|
@ -201,13 +209,14 @@ const TimePicker = {
|
||||||
renderTimePicker(locale) {
|
renderTimePicker(locale) {
|
||||||
let props = getOptionProps(this);
|
let props = getOptionProps(this);
|
||||||
props = omit(props, ['defaultValue', 'suffixIcon', 'allowEmpty', 'allowClear']);
|
props = omit(props, ['defaultValue', 'suffixIcon', 'allowEmpty', 'allowClear']);
|
||||||
|
const { class: className } = this.$attrs;
|
||||||
const { prefixCls: customizePrefixCls, getPopupContainer, placeholder, size } = props;
|
const { prefixCls: customizePrefixCls, getPopupContainer, placeholder, size } = props;
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||||
const prefixCls = getPrefixCls('time-picker', customizePrefixCls);
|
const prefixCls = getPrefixCls('time-picker', customizePrefixCls);
|
||||||
|
|
||||||
const format = this.getDefaultFormat();
|
const format = this.getDefaultFormat();
|
||||||
const pickerClassName = {
|
const pickerClassName = {
|
||||||
|
[className]: className,
|
||||||
[`${prefixCls}-${size}`]: !!size,
|
[`${prefixCls}-${size}`]: !!size,
|
||||||
};
|
};
|
||||||
const tempAddon = getComponent(this, 'addon', {}, false);
|
const tempAddon = getComponent(this, 'addon', {}, false);
|
||||||
|
@ -222,27 +231,23 @@ const TimePicker = {
|
||||||
const clearIcon = this.renderClearIcon(prefixCls);
|
const clearIcon = this.renderClearIcon(prefixCls);
|
||||||
const { getPopupContainer: getContextPopupContainer } = this.configProvider;
|
const { getPopupContainer: getContextPopupContainer } = this.configProvider;
|
||||||
const timeProps = {
|
const timeProps = {
|
||||||
props: {
|
...generateShowHourMinuteSecond(format),
|
||||||
...generateShowHourMinuteSecond(format),
|
...props,
|
||||||
...props,
|
...this.$attrs,
|
||||||
allowEmpty: this.getAllowClear(),
|
allowEmpty: this.getAllowClear(),
|
||||||
prefixCls,
|
prefixCls,
|
||||||
getPopupContainer: getPopupContainer || getContextPopupContainer,
|
getPopupContainer: getPopupContainer || getContextPopupContainer,
|
||||||
format,
|
format,
|
||||||
value: this.sValue,
|
value: this.sValue,
|
||||||
placeholder: placeholder === undefined ? locale.placeholder : placeholder,
|
placeholder: placeholder === undefined ? locale.placeholder : placeholder,
|
||||||
addon: pickerAddon,
|
addon: pickerAddon,
|
||||||
inputIcon,
|
inputIcon,
|
||||||
clearIcon,
|
clearIcon,
|
||||||
},
|
|
||||||
class: pickerClassName,
|
class: pickerClassName,
|
||||||
ref: 'timePicker',
|
ref: this.saveTimePicker,
|
||||||
on: {
|
onChange: this.handleChange,
|
||||||
...getListeners(this),
|
onOpen: this.handleOpenClose,
|
||||||
change: this.handleChange,
|
onClose: this.handleOpenClose,
|
||||||
open: this.handleOpenClose,
|
|
||||||
close: this.handleOpenClose,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
return <VcTimePicker {...timeProps} />;
|
return <VcTimePicker {...timeProps} />;
|
||||||
},
|
},
|
||||||
|
@ -253,16 +258,15 @@ const TimePicker = {
|
||||||
<LocaleReceiver
|
<LocaleReceiver
|
||||||
componentName="TimePicker"
|
componentName="TimePicker"
|
||||||
defaultLocale={this.getDefaultLocale()}
|
defaultLocale={this.getDefaultLocale()}
|
||||||
scopedSlots={{ default: this.renderTimePicker }}
|
children={this.renderTimePicker}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
TimePicker.install = function(Vue) {
|
TimePicker.install = function(app) {
|
||||||
Vue.use(Base);
|
app.component(TimePicker.name, TimePicker);
|
||||||
Vue.component(TimePicker.name, TimePicker);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TimePicker;
|
export default TimePicker;
|
||||||
|
|
|
@ -20,6 +20,7 @@ const formatOption = (option, disabledOptions) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Combobox = {
|
const Combobox = {
|
||||||
|
inheritAttrs: false,
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
name: 'Combobox',
|
name: 'Combobox',
|
||||||
props: {
|
props: {
|
||||||
|
|
|
@ -3,6 +3,8 @@ import BaseMixin from '../_util/BaseMixin';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
const Header = {
|
const Header = {
|
||||||
|
inheritAttrs: false,
|
||||||
|
name: 'Header',
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
props: {
|
props: {
|
||||||
format: PropTypes.string,
|
format: PropTypes.string,
|
||||||
|
@ -41,8 +43,8 @@ const Header = {
|
||||||
// Wait one frame for the panel to be positioned before focusing
|
// Wait one frame for the panel to be positioned before focusing
|
||||||
const requestAnimationFrame = window.requestAnimationFrame || window.setTimeout;
|
const requestAnimationFrame = window.requestAnimationFrame || window.setTimeout;
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
this.$refs.input.focus();
|
this.refInput.focus();
|
||||||
this.$refs.input.select();
|
this.refInput.select();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -160,19 +162,14 @@ const Header = {
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
class={`${prefixCls}-input ${invalidClass}`}
|
class={`${prefixCls}-input ${invalidClass}`}
|
||||||
ref="input"
|
ref={ref => {
|
||||||
|
this.refInput = ref;
|
||||||
|
}}
|
||||||
onKeydown={this.onKeyDown}
|
onKeydown={this.onKeyDown}
|
||||||
value={str}
|
value={str}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
onInput={this.onInputChange}
|
onInput={this.onInputChange}
|
||||||
readonly={!!inputReadOnly}
|
readonly={!!inputReadOnly}
|
||||||
{...{
|
|
||||||
directives: [
|
|
||||||
{
|
|
||||||
name: 'ant-input',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import classNames from 'classnames';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import BaseMixin from '../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
import Combobox from './Combobox';
|
import Combobox from './Combobox';
|
||||||
import { getComponent, getListeners } from '../_util/props-util';
|
import { getComponent } from '../_util/props-util';
|
||||||
|
|
||||||
function noop() {}
|
function noop() {}
|
||||||
|
|
||||||
|
@ -31,6 +32,8 @@ function toNearestValidTime(time, hourOptions, minuteOptions, secondOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Panel = {
|
const Panel = {
|
||||||
|
name: 'Panel',
|
||||||
|
inheritAttrs: false,
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
props: {
|
props: {
|
||||||
clearText: PropTypes.string,
|
clearText: PropTypes.string,
|
||||||
|
@ -144,8 +147,8 @@ const Panel = {
|
||||||
sValue,
|
sValue,
|
||||||
currentSelectPanel,
|
currentSelectPanel,
|
||||||
} = this;
|
} = this;
|
||||||
|
const { class: className, onEsc = noop, onKeydown = noop } = this.$attrs;
|
||||||
const clearIcon = getComponent(this, 'clearIcon');
|
const clearIcon = getComponent(this, 'clearIcon');
|
||||||
const { esc = noop, keydown = noop } = getListeners(this);
|
|
||||||
|
|
||||||
const disabledHourOptions = this.disabledHours2();
|
const disabledHourOptions = this.disabledHours2();
|
||||||
const disabledMinuteOptions = disabledMinutes(sValue ? sValue.hour() : null);
|
const disabledMinuteOptions = disabledMinutes(sValue ? sValue.hour() : null);
|
||||||
|
@ -173,14 +176,14 @@ const Panel = {
|
||||||
secondOptions,
|
secondOptions,
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div class={`${prefixCls}-inner`}>
|
<div className={classNames(className, `${prefixCls}-inner`)}>
|
||||||
<Header
|
<Header
|
||||||
clearText={clearText}
|
clearText={clearText}
|
||||||
prefixCls={prefixCls}
|
prefixCls={prefixCls}
|
||||||
defaultOpenValue={validDefaultOpenValue}
|
defaultOpenValue={validDefaultOpenValue}
|
||||||
value={sValue}
|
value={sValue}
|
||||||
currentSelectPanel={currentSelectPanel}
|
currentSelectPanel={currentSelectPanel}
|
||||||
onEsc={esc}
|
onEsc={onEsc}
|
||||||
format={format}
|
format={format}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
hourOptions={hourOptions}
|
hourOptions={hourOptions}
|
||||||
|
@ -191,7 +194,7 @@ const Panel = {
|
||||||
disabledSeconds={disabledSeconds}
|
disabledSeconds={disabledSeconds}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
focusOnOpen={focusOnOpen}
|
focusOnOpen={focusOnOpen}
|
||||||
onKeydown={keydown}
|
onKeydown={onKeydown}
|
||||||
inputReadOnly={inputReadOnly}
|
inputReadOnly={inputReadOnly}
|
||||||
clearIcon={clearIcon}
|
clearIcon={clearIcon}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -23,7 +23,9 @@ const scrollTo = (element, to, duration) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Select = {
|
const Select = {
|
||||||
|
name: 'Select',
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
options: PropTypes.array,
|
options: PropTypes.array,
|
||||||
|
@ -101,6 +103,10 @@ const Select = {
|
||||||
this.setState({ active: false });
|
this.setState({ active: false });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
saveList(node) {
|
||||||
|
this.list = node;
|
||||||
|
},
|
||||||
|
|
||||||
scrollToSelected(duration) {
|
scrollToSelected(duration) {
|
||||||
// move to selected item
|
// move to selected item
|
||||||
const select = this.$el;
|
const select = this.$el;
|
||||||
|
@ -131,7 +137,7 @@ const Select = {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={cls} onMouseenter={this.handleMouseEnter} onMouseleave={this.handleMouseLeave}>
|
<div class={cls} onMouseenter={this.handleMouseEnter} onMouseleave={this.handleMouseLeave}>
|
||||||
<ul ref="list">{this.getOptions()}</ul>
|
<ul ref={this.saveList}>{this.getOptions()}</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,10 +15,14 @@ import Panel from './Panel';
|
||||||
import placements from './placements';
|
import placements from './placements';
|
||||||
|
|
||||||
function noop() {}
|
function noop() {}
|
||||||
|
function refFn(field, component) {
|
||||||
|
this[field] = component;
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'VcTimePicker',
|
name: 'VcTimePicker',
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
|
inheritAttrs: false,
|
||||||
props: initDefaultProps(
|
props: initDefaultProps(
|
||||||
{
|
{
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
|
@ -93,6 +97,8 @@ export default {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
data() {
|
data() {
|
||||||
|
this.saveInputRef = refFn.bind(this, 'picker');
|
||||||
|
this.savePanelRef = refFn.bind(this, 'panelInstance');
|
||||||
const { defaultOpen, defaultValue, open = defaultOpen, value = defaultValue } = this;
|
const { defaultOpen, defaultValue, open = defaultOpen, value = defaultValue } = this;
|
||||||
return {
|
return {
|
||||||
sOpen: open,
|
sOpen: open,
|
||||||
|
@ -210,7 +216,7 @@ export default {
|
||||||
<Panel
|
<Panel
|
||||||
clearText={clearText}
|
clearText={clearText}
|
||||||
prefixCls={`${prefixCls}-panel`}
|
prefixCls={`${prefixCls}-panel`}
|
||||||
ref="panel"
|
ref={this.savePanelRef}
|
||||||
value={sValue}
|
value={sValue}
|
||||||
inputReadOnly={inputReadOnly}
|
inputReadOnly={inputReadOnly}
|
||||||
onChange={this.onPanelChange}
|
onChange={this.onPanelChange}
|
||||||
|
@ -278,11 +284,11 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
this.$refs.picker.focus();
|
this.picker.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
blur() {
|
blur() {
|
||||||
this.$refs.picker.blur();
|
this.picker.blur();
|
||||||
},
|
},
|
||||||
onFocus(e) {
|
onFocus(e) {
|
||||||
this.__emit('focus', e);
|
this.__emit('focus', e);
|
||||||
|
@ -298,13 +304,11 @@ export default {
|
||||||
}
|
}
|
||||||
const clearIcon = getComponent(this, 'clearIcon');
|
const clearIcon = getComponent(this, 'clearIcon');
|
||||||
if (isValidElement(clearIcon)) {
|
if (isValidElement(clearIcon)) {
|
||||||
const { click } = getEvents(clearIcon) || {};
|
const { onClick } = getEvents(clearIcon) || {};
|
||||||
return cloneElement(clearIcon, {
|
return cloneElement(clearIcon, {
|
||||||
on: {
|
onClick: (...args) => {
|
||||||
click: (...args) => {
|
if (onClick) onClick(...args);
|
||||||
if (click) click(...args);
|
this.onClear(...args);
|
||||||
this.onClear(...args);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -343,6 +347,7 @@ export default {
|
||||||
onBlur,
|
onBlur,
|
||||||
popupStyle,
|
popupStyle,
|
||||||
} = this;
|
} = this;
|
||||||
|
const { class: className, style } = this.$attrs;
|
||||||
const popupClassName = this.getPopupClassName();
|
const popupClassName = this.getPopupClassName();
|
||||||
const inputIcon = getComponent(this, 'inputIcon');
|
const inputIcon = getComponent(this, 'inputIcon');
|
||||||
return (
|
return (
|
||||||
|
@ -359,12 +364,12 @@ export default {
|
||||||
popupTransitionName={transitionName}
|
popupTransitionName={transitionName}
|
||||||
popupVisible={sOpen}
|
popupVisible={sOpen}
|
||||||
onPopupVisibleChange={this.onVisibleChange}
|
onPopupVisibleChange={this.onVisibleChange}
|
||||||
|
popup={this.getPanelElement()}
|
||||||
>
|
>
|
||||||
<template slot="popup">{this.getPanelElement()}</template>
|
<span class={classNames(prefixCls, className)} style={style}>
|
||||||
<span class={`${prefixCls}`}>
|
|
||||||
<input
|
<input
|
||||||
class={`${prefixCls}-input`}
|
class={`${prefixCls}-input`}
|
||||||
ref="picker"
|
ref={this.saveInputRef}
|
||||||
type="text"
|
type="text"
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
name={name}
|
name={name}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import demo from '../antdv-demo/docs/slider/demo/basic';
|
import demo from '../antdv-demo/docs/time-picker/demo/basic';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import {
|
||||||
Transfer,
|
Transfer,
|
||||||
Slider,
|
Slider,
|
||||||
Carousel,
|
Carousel,
|
||||||
|
TimePicker,
|
||||||
notification,
|
notification,
|
||||||
message,
|
message,
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
|
@ -83,4 +84,5 @@ app
|
||||||
.use(Transfer)
|
.use(Transfer)
|
||||||
.use(Slider)
|
.use(Slider)
|
||||||
.use(Carousel)
|
.use(Carousel)
|
||||||
|
.use(TimePicker)
|
||||||
.mount('#app');
|
.mount('#app');
|
||||||
|
|
Loading…
Reference in New Issue