refactor: row slider spin by ts

This commit is contained in:
Amour1688 2020-10-13 22:59:24 +08:00
parent 88d3b6010b
commit c959476265
7 changed files with 62 additions and 42 deletions

View File

@ -1,7 +1,8 @@
import { App } from 'vue';
import { Row } from '../grid'; import { Row } from '../grid';
/* istanbul ignore next */ /* istanbul ignore next */
Row.install = function(app) { Row.install = function(app: App) {
app.component(Row.name, Row); app.component(Row.name, Row);
return app; return app;
}; };

View File

@ -1,4 +1,4 @@
import { inject } from 'vue'; import { App, defineComponent, inject, VNodeTypes } from 'vue';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import BaseMixin from '../_util/BaseMixin'; import BaseMixin from '../_util/BaseMixin';
import { getOptionProps } from '../_util/props-util'; import { getOptionProps } from '../_util/props-util';
@ -9,6 +9,21 @@ import Tooltip from '../tooltip';
import { defaultConfigProvider } from '../config-provider'; import { defaultConfigProvider } from '../config-provider';
import abstractTooltipProps from '../tooltip/abstractTooltipProps'; import abstractTooltipProps from '../tooltip/abstractTooltipProps';
export type SliderValue = number | [number, number];
interface HandleGeneratorInfo {
value: number;
dragging: boolean;
index: number;
rest: any[];
}
export type HandleGeneratorFn = (config: {
tooltipPrefixCls?: string;
prefixCls?: string;
info: HandleGeneratorInfo;
}) => VNodeTypes;
const tooltipProps = abstractTooltipProps(); const tooltipProps = abstractTooltipProps();
export const SliderProps = () => ({ export const SliderProps = () => ({
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
@ -30,22 +45,19 @@ export const SliderProps = () => ({
tooltipPlacement: tooltipProps.placement, tooltipPlacement: tooltipProps.placement,
getTooltipPopupContainer: PropTypes.func, getTooltipPopupContainer: PropTypes.func,
onChange: PropTypes.func, onChange: PropTypes.func,
'onUpdate:value': PropTypes.func,
onAfterChange: PropTypes.func, onAfterChange: PropTypes.func,
}); });
const defaultTipFormatter = value => value.toString(); const defaultTipFormatter = (value: number) => value.toString();
const Slider = { const Slider = defineComponent({
name: 'ASlider', name: 'ASlider',
inheritAttrs: false, inheritAttrs: false,
// model: { emits: ['update:value', 'change'],
// prop: 'value',
// event: 'change',
// },
mixins: [BaseMixin], mixins: [BaseMixin],
setup() { setup() {
return { return {
vcSlider: null,
configProvider: inject('configProvider', defaultConfigProvider), configProvider: inject('configProvider', defaultConfigProvider),
}; };
}, },
@ -58,7 +70,7 @@ const Slider = {
}; };
}, },
methods: { methods: {
toggleTooltipVisible(index, visible) { toggleTooltipVisible(index: number, visible: boolean) {
this.setState(({ visibles }) => ({ this.setState(({ visibles }) => ({
visibles: { visibles: {
...visibles, ...visibles,
@ -66,7 +78,11 @@ const Slider = {
}, },
})); }));
}, },
handleWithTooltip(tooltipPrefixCls, prefixCls, { value, dragging, index, ...restProps }) { handleWithTooltip(
tooltipPrefixCls: string,
prefixCls: string,
{ value, dragging, index, ...restProps }: HandleGeneratorInfo,
): VNodeTypes {
const { const {
tipFormatter = defaultTipFormatter, tipFormatter = defaultTipFormatter,
tooltipVisible, tooltipVisible,
@ -98,7 +114,7 @@ const Slider = {
</Tooltip> </Tooltip>
); );
}, },
saveSlider(node) { saveSlider(node: any) {
this.vcSlider = node; this.vcSlider = node;
}, },
focus() { focus() {
@ -107,7 +123,7 @@ const Slider = {
blur() { blur() {
this.vcSlider.blur(); this.vcSlider.blur();
}, },
handleChange(val) { handleChange(val: SliderValue) {
this.$emit('update:value', val); this.$emit('update:value', val);
this.$emit('change', val); this.$emit('change', val);
}, },
@ -118,8 +134,8 @@ const Slider = {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
tooltipPrefixCls: customizeTooltipPrefixCls, tooltipPrefixCls: customizeTooltipPrefixCls,
...restProps ...restProps
} = { ...getOptionProps(this), ...this.$attrs }; } = { ...getOptionProps(this), ...this.$attrs } as any;
const getPrefixCls = this.configProvider.getPrefixCls; const { getPrefixCls } = this.configProvider;
const prefixCls = getPrefixCls('slider', customizePrefixCls); const prefixCls = getPrefixCls('slider', customizePrefixCls);
const tooltipPrefixCls = getPrefixCls('tooltip', customizeTooltipPrefixCls); const tooltipPrefixCls = getPrefixCls('tooltip', customizeTooltipPrefixCls);
if (range) { if (range) {
@ -127,7 +143,8 @@ const Slider = {
...restProps, ...restProps,
prefixCls, prefixCls,
tooltipPrefixCls, tooltipPrefixCls,
handle: info => this.handleWithTooltip(tooltipPrefixCls, prefixCls, info), handle: (info: HandleGeneratorInfo) =>
this.handleWithTooltip(tooltipPrefixCls, prefixCls, info),
ref: this.saveSlider, ref: this.saveSlider,
onChange: this.handleChange, onChange: this.handleChange,
}; };
@ -137,16 +154,17 @@ const Slider = {
...restProps, ...restProps,
prefixCls, prefixCls,
tooltipPrefixCls, tooltipPrefixCls,
handle: info => this.handleWithTooltip(tooltipPrefixCls, prefixCls, info), handle: (info: HandleGeneratorInfo) =>
this.handleWithTooltip(tooltipPrefixCls, prefixCls, info),
ref: this.saveSlider, ref: this.saveSlider,
onChange: this.handleChange, onChange: this.handleChange,
}; };
return <VcSlider {...vcSliderProps} />; return <VcSlider {...vcSliderProps} />;
}, },
}; });
/* istanbul ignore next */ /* istanbul ignore next */
Slider.install = function(app) { Slider.install = function(app: App) {
app.component(Slider.name, Slider); app.component(Slider.name, Slider);
return app; return app;
}; };

View File

@ -1,11 +1,13 @@
import { inject, cloneVNode, isVNode } from 'vue'; import { inject, cloneVNode, isVNode, defineComponent, VNode } from 'vue';
import debounce from 'lodash-es/debounce'; import debounce from 'lodash-es/debounce';
import { tuple } from '../_util/type';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import BaseMixin from '../_util/BaseMixin'; import BaseMixin from '../_util/BaseMixin';
import { initDefaultProps, getComponent, getSlot } from '../_util/props-util'; import { getComponent, getSlot } from '../_util/props-util';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import { defaultConfigProvider } from '../config-provider'; import { defaultConfigProvider } from '../config-provider';
export const SpinSize = PropTypes.oneOf(['small', 'default', 'large']); export const SpinSize = PropTypes.oneOf(tuple('small', 'default', 'large'));
export const SpinProps = () => ({ export const SpinProps = () => ({
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
@ -18,23 +20,18 @@ export const SpinProps = () => ({
}); });
// Render indicator // Render indicator
let defaultIndicator; let defaultIndicator: () => VNode = null;
function shouldDelay(spinning, delay) { function shouldDelay(spinning?: boolean, delay?: number): boolean {
return !!spinning && !!delay && !isNaN(Number(delay)); return !!spinning && !!delay && !isNaN(Number(delay));
} }
export function setDefaultIndicator(Content) { export function setDefaultIndicator(Content: any) {
const Indicator = Content.indicator; const Indicator = Content.indicator;
defaultIndicator = defaultIndicator = typeof Indicator === 'function' ? Indicator : () => <Indicator />;
typeof Indicator === 'function'
? Indicator
: () => {
return <Indicator />;
};
} }
export default { export default defineComponent({
name: 'ASpin', name: 'ASpin',
mixins: [BaseMixin], mixins: [BaseMixin],
inheritAttrs: false, inheritAttrs: false,
@ -45,14 +42,17 @@ export default {
}), }),
setup() { setup() {
return { return {
originalUpdateSpinning: null,
configProvider: inject('configProvider', defaultConfigProvider), configProvider: inject('configProvider', defaultConfigProvider),
}; };
}, },
created() {
this.originalUpdateSpinning = this.updateSpinning;
this.debouncifyUpdateSpinning(this.$props);
},
data() { data() {
const { spinning, delay } = this; const { spinning, delay } = this;
const shouldBeDelayed = shouldDelay(spinning, delay); const shouldBeDelayed = shouldDelay(spinning, delay);
this.originalUpdateSpinning = this.updateSpinning;
this.debouncifyUpdateSpinning(this.$props);
return { return {
sSpinning: spinning && !shouldBeDelayed, sSpinning: spinning && !shouldBeDelayed,
}; };
@ -70,7 +70,7 @@ export default {
this.cancelExistingSpin(); this.cancelExistingSpin();
}, },
methods: { methods: {
debouncifyUpdateSpinning(props) { debouncifyUpdateSpinning(props?: any) {
const { delay } = props || this.$props; const { delay } = props || this.$props;
if (delay) { if (delay) {
this.cancelExistingSpin(); this.cancelExistingSpin();
@ -85,11 +85,11 @@ export default {
}, },
cancelExistingSpin() { cancelExistingSpin() {
const { updateSpinning } = this; const { updateSpinning } = this;
if (updateSpinning && updateSpinning.cancel) { if (updateSpinning && (updateSpinning as any).cancel) {
updateSpinning.cancel(); (updateSpinning as any).cancel();
} }
}, },
renderIndicator(prefixCls) { renderIndicator(prefixCls: string) {
const dotClassName = `${prefixCls}-dot`; const dotClassName = `${prefixCls}-dot`;
let indicator = getComponent(this, 'indicator'); let indicator = getComponent(this, 'indicator');
// should not be render default indicator when indicator value is null // should not be render default indicator when indicator value is null
@ -120,7 +120,7 @@ export default {
render() { render() {
const { size, prefixCls: customizePrefixCls, tip, wrapperClassName } = this.$props; const { size, prefixCls: customizePrefixCls, tip, wrapperClassName } = this.$props;
const { class: cls, style, ...divProps } = this.$attrs; const { class: cls, style, ...divProps } = this.$attrs;
const getPrefixCls = this.configProvider.getPrefixCls; const { getPrefixCls } = this.configProvider;
const prefixCls = getPrefixCls('spin', customizePrefixCls); const prefixCls = getPrefixCls('spin', customizePrefixCls);
const { sSpinning } = this; const { sSpinning } = this;
@ -130,7 +130,7 @@ export default {
[`${prefixCls}-lg`]: size === 'large', [`${prefixCls}-lg`]: size === 'large',
[`${prefixCls}-spinning`]: sSpinning, [`${prefixCls}-spinning`]: sSpinning,
[`${prefixCls}-show-text`]: !!tip, [`${prefixCls}-show-text`]: !!tip,
[cls]: !!cls, [cls as string]: !!cls,
}; };
const spinElement = ( const spinElement = (
@ -157,4 +157,4 @@ export default {
} }
return spinElement; return spinElement;
}, },
}; });

View File

@ -1,3 +1,4 @@
import { App } from 'vue';
import Spin, { setDefaultIndicator } from './Spin'; import Spin, { setDefaultIndicator } from './Spin';
export { SpinProps } from './Spin'; export { SpinProps } from './Spin';
@ -5,7 +6,7 @@ export { SpinProps } from './Spin';
Spin.setDefaultIndicator = setDefaultIndicator; Spin.setDefaultIndicator = setDefaultIndicator;
/* istanbul ignore next */ /* istanbul ignore next */
Spin.install = function(app) { Spin.install = function(app: App) {
app.component(Spin.name, Spin); app.component(Spin.name, Spin);
return app; return app;
}; };