perf: trigger

refactor-date
tangjinzhou 2021-08-15 21:58:42 +08:00
parent 64f07a0e7b
commit fc487c6b6f
10 changed files with 88 additions and 67 deletions

View File

@ -1,4 +1,5 @@
import { nextTick, PropType } from 'vue'; import type { PropType } from 'vue';
import { nextTick } from 'vue';
import { defineComponent, ref, computed, onMounted, onUpdated, watch, onUnmounted } from 'vue'; import { defineComponent, ref, computed, onMounted, onUpdated, watch, onUnmounted } from 'vue';
import { alignElement, alignPoint } from 'dom-align'; import { alignElement, alignPoint } from 'dom-align';
import addEventListener from '../vc-util/Dom/addEventListener'; import addEventListener from '../vc-util/Dom/addEventListener';

View File

@ -527,7 +527,6 @@ function Picker<DateType>() {
return ( return (
<PickerTrigger <PickerTrigger
visible={mergedOpen.value} visible={mergedOpen.value}
popupElement={panel}
popupStyle={popupStyle} popupStyle={popupStyle}
prefixCls={prefixCls} prefixCls={prefixCls}
dropdownClassName={dropdownClassName} dropdownClassName={dropdownClassName}
@ -536,6 +535,9 @@ function Picker<DateType>() {
transitionName={transitionName} transitionName={transitionName}
popupPlacement={popupPlacement} popupPlacement={popupPlacement}
direction={direction} direction={direction}
v-slots={{
popupElement: () => panel,
}}
> >
<div <div
class={classNames(prefixCls, attrs.class, { class={classNames(prefixCls, attrs.class, {

View File

@ -2,7 +2,6 @@ import type { CSSProperties } from '@vue/runtime-dom';
import type { AlignType } from '../vc-align/interface'; import type { AlignType } from '../vc-align/interface';
import Trigger from '../vc-trigger'; import Trigger from '../vc-trigger';
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import type { VueNode } from '../_util/type';
import useMergeProps from './hooks/useMergeProps'; import useMergeProps from './hooks/useMergeProps';
const BUILT_IN_PLACEMENTS = { const BUILT_IN_PLACEMENTS = {
@ -45,7 +44,6 @@ type Placement = 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';
export type PickerTriggerProps = { export type PickerTriggerProps = {
prefixCls: string; prefixCls: string;
visible: boolean; visible: boolean;
popupElement: VueNode;
popupStyle?: CSSProperties; popupStyle?: CSSProperties;
dropdownClassName?: string; dropdownClassName?: string;
transitionName?: string; transitionName?: string;
@ -59,7 +57,6 @@ export type PickerTriggerProps = {
function PickerTrigger(props: PickerTriggerProps, { slots }) { function PickerTrigger(props: PickerTriggerProps, { slots }) {
const { const {
prefixCls, prefixCls,
popupElement,
popupStyle, popupStyle,
visible, visible,
dropdownClassName, dropdownClassName,
@ -87,7 +84,6 @@ function PickerTrigger(props: PickerTriggerProps, { slots }) {
builtinPlacements={BUILT_IN_PLACEMENTS} builtinPlacements={BUILT_IN_PLACEMENTS}
prefixCls={dropdownPrefixCls} prefixCls={dropdownPrefixCls}
popupTransitionName={transitionName} popupTransitionName={transitionName}
popup={popupElement}
popupAlign={dropdownAlign} popupAlign={dropdownAlign}
popupVisible={visible} popupVisible={visible}
popupClassName={classNames(dropdownClassName, { popupClassName={classNames(dropdownClassName, {
@ -96,9 +92,11 @@ function PickerTrigger(props: PickerTriggerProps, { slots }) {
})} })}
popupStyle={popupStyle} popupStyle={popupStyle}
getPopupContainer={getPopupContainer} getPopupContainer={getPopupContainer}
> v-slots={{
{slots.default?.()} default: slots.default,
</Trigger> popup: slots.popupElement,
}}
></Trigger>
); );
} }

View File

@ -1062,7 +1062,6 @@ function RangerPicker<DateType>() {
style={{ minWidth: `${popupMinWidth.value}px` }} style={{ minWidth: `${popupMinWidth.value}px` }}
> >
<div class={`${prefixCls}-range-arrow`} style={arrowPositionStyle} /> <div class={`${prefixCls}-range-arrow`} style={arrowPositionStyle} />
{renderPanels()} {renderPanels()}
</div> </div>
); );
@ -1128,7 +1127,6 @@ function RangerPicker<DateType>() {
return ( return (
<PickerTrigger <PickerTrigger
visible={mergedOpen.value} visible={mergedOpen.value}
popupElement={rangePanel}
popupStyle={popupStyle} popupStyle={popupStyle}
prefixCls={prefixCls} prefixCls={prefixCls}
dropdownClassName={dropdownClassName} dropdownClassName={dropdownClassName}
@ -1137,6 +1135,9 @@ function RangerPicker<DateType>() {
transitionName={transitionName} transitionName={transitionName}
range range
direction={direction} direction={direction}
v-slots={{
popupElement: () => rangePanel,
}}
> >
<div <div
ref={containerRef} ref={containerRef}

View File

@ -13,7 +13,7 @@ export default defineComponent({
defaultVisible: PropTypes.looseBool, defaultVisible: PropTypes.looseBool,
visible: PropTypes.looseBool, visible: PropTypes.looseBool,
placement: PropTypes.string.def('right'), placement: PropTypes.string.def('right'),
transitionName: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), transitionName: PropTypes.string,
animation: PropTypes.any, animation: PropTypes.any,
afterVisibleChange: PropTypes.func.def(() => {}), afterVisibleChange: PropTypes.func.def(() => {}),
overlay: PropTypes.any, overlay: PropTypes.any,

View File

@ -1,13 +1,15 @@
import { CSSProperties, defineComponent, ref, Transition } from 'vue'; import type { CSSProperties } from 'vue';
import { flattenChildren } from 'ant-design-vue/es/_util/props-util'; import { defineComponent, ref, Transition } from 'vue';
import classNames from 'ant-design-vue/es/_util/classNames'; import { flattenChildren } from '../../_util/props-util';
import { MobilePopupProps, mobileProps } from './interface'; import classNames from '../../_util/classNames';
import type { MobilePopupProps } from './interface';
import { mobileProps } from './interface';
export default defineComponent({ export default defineComponent({
name: 'MobilePopupInner',
inheritAttrs: false,
props: mobileProps, props: mobileProps,
emits: ['mouseenter', 'mouseleave', 'mousedown', 'touchstart', 'align'], emits: ['mouseenter', 'mouseleave', 'mousedown', 'touchstart', 'align'],
inheritAttrs: false,
name: 'MobilePopupInner',
setup(props, { expose, slots }) { setup(props, { expose, slots }) {
const elementRef = ref<HTMLDivElement>(); const elementRef = ref<HTMLDivElement>();

View File

@ -1,9 +1,9 @@
import type { AlignType } from '../interface'; import type { AlignType } from '../interface';
import useVisibleStatus from './useVisibleStatus'; import useVisibleStatus from './useVisibleStatus';
import useStretchStyle from './useStretchStyle'; import useStretchStyle from './useStretchStyle';
import type { CSSProperties } from 'vue';
import { import {
computed, computed,
CSSProperties,
defineComponent, defineComponent,
nextTick, nextTick,
ref, ref,
@ -12,19 +12,21 @@ import {
watch, watch,
withModifiers, withModifiers,
} from 'vue'; } from 'vue';
import Align, { RefAlign } from 'ant-design-vue/es/vc-align/Align'; import type { RefAlign } from '../../vc-align/Align';
import Align from '../../vc-align/Align';
import { getMotion } from '../utils/motionUtil'; import { getMotion } from '../utils/motionUtil';
import { flattenChildren } from 'ant-design-vue/es/_util/props-util'; import { flattenChildren } from '../../_util/props-util';
import classNames from 'ant-design-vue/es/_util/classNames'; import classNames from '../../_util/classNames';
import { innerProps, PopupInnerProps } from './interface'; import type { PopupInnerProps } from './interface';
import { getTransitionProps } from 'ant-design-vue/es/_util/transition'; import { innerProps } from './interface';
import supportsPassive from 'ant-design-vue/es/_util/supportsPassive'; import { getTransitionProps } from '../../_util/transition';
import supportsPassive from '../../_util/supportsPassive';
export default defineComponent({ export default defineComponent({
props: innerProps,
name: 'PopupInner', name: 'PopupInner',
emits: ['mouseenter', 'mouseleave', 'mousedown', 'touchstart', 'align'],
inheritAttrs: false, inheritAttrs: false,
props: innerProps,
emits: ['mouseenter', 'mouseleave', 'mousedown', 'touchstart', 'align'],
setup(props, { expose, attrs, slots }) { setup(props, { expose, attrs, slots }) {
const alignRef = ref<RefAlign>(); const alignRef = ref<RefAlign>();
const elementRef = ref<HTMLDivElement>(); const elementRef = ref<HTMLDivElement>();
@ -147,36 +149,46 @@ export default defineComponent({
const mergedClassName = classNames(prefixCls, attrs.class, alignedClassName.value); const mergedClassName = classNames(prefixCls, attrs.class, alignedClassName.value);
const transitionProps = getTransitionProps(motion.value.name, motion.value); const transitionProps = getTransitionProps(motion.value.name, motion.value);
return ( return (
<Transition ref={elementRef} {...transitionProps} onBeforeEnter={onShowPrepare}> <Transition
{!destroyPopupOnHide || visible ? ( ref={elementRef}
<Align {...transitionProps}
v-show={visible} onBeforeEnter={onShowPrepare}
target={getAlignTarget()} v-slots={{
key="popup" default: () => {
ref={alignRef} return !destroyPopupOnHide || visible ? (
monitorWindowResize <Align
disabled={alignDisabled} v-show={visible}
align={align} target={getAlignTarget()}
onAlign={onInternalAlign} key="popup"
> ref={alignRef}
<div monitorWindowResize
class={mergedClassName} disabled={alignDisabled}
onMouseenter={onMouseenter} align={align}
onMouseleave={onMouseleave} onAlign={onInternalAlign}
onMousedown={withModifiers(onMousedown, ['capture'])} v-slots={{
{...{ default: () => (
[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart']: withModifiers( <div
onTouchstart, class={mergedClassName}
['capture'], onMouseenter={onMouseenter}
), onMouseleave={onMouseleave}
}} onMousedown={withModifiers(onMousedown, ['capture'])}
style={mergedStyle} {...{
> [supportsPassive ? 'onTouchstartPassive' : 'onTouchstart']: withModifiers(
{childNode} onTouchstart,
</div> ['capture'],
</Align> ),
) : null} }}
</Transition> style={mergedStyle}
>
{childNode}
</div>
),
}}
></Align>
) : null;
},
}}
></Transition>
); );
}; };
}, },

View File

@ -5,9 +5,9 @@ import MobilePopupInner from './MobilePopupInner';
import PopupInner from './PopupInner'; import PopupInner from './PopupInner';
export default defineComponent({ export default defineComponent({
props: popupProps,
inheritAttrs: false,
name: 'Popup', name: 'Popup',
inheritAttrs: false,
props: popupProps,
setup(props, { attrs, slots, expose }) { setup(props, { attrs, slots, expose }) {
const innerVisible = ref(false); const innerVisible = ref(false);
const inMobile = ref(false); const inMobile = ref(false);

View File

@ -1,4 +1,5 @@
import { computed, defineComponent, HTMLAttributes, inject, provide, ref } from 'vue'; import type { HTMLAttributes } from 'vue';
import { computed, defineComponent, inject, provide, ref } from 'vue';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import contains from '../vc-util/Dom/contains'; import contains from '../vc-util/Dom/contains';
import raf from '../_util/raf'; import raf from '../_util/raf';
@ -411,17 +412,16 @@ export default defineComponent({
return popupAlign; return popupAlign;
}, },
getComponent() { getComponent() {
const self = this;
const mouseProps: HTMLAttributes = {}; const mouseProps: HTMLAttributes = {};
if (this.isMouseEnterToShow()) { if (this.isMouseEnterToShow()) {
mouseProps.onMouseenter = self.onPopupMouseenter; mouseProps.onMouseenter = this.onPopupMouseenter;
} }
if (this.isMouseLeaveToHide()) { if (this.isMouseLeaveToHide()) {
mouseProps.onMouseleave = self.onPopupMouseleave; mouseProps.onMouseleave = this.onPopupMouseleave;
} }
mouseProps.onMousedown = this.onPopupMouseDown; mouseProps.onMousedown = this.onPopupMouseDown;
mouseProps[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart'] = this.onPopupMouseDown; mouseProps[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart'] = this.onPopupMouseDown;
const { handleGetPopupClassFromAlign, getRootDomNode, getContainer, $attrs } = self; const { handleGetPopupClassFromAlign, getRootDomNode, getContainer, $attrs } = this;
const { const {
prefixCls, prefixCls,
destroyPopupOnHide, destroyPopupOnHide,
@ -437,7 +437,7 @@ export default defineComponent({
alignPoint, alignPoint,
mobile, mobile,
forceRender, forceRender,
} = self.$props; } = this.$props;
const { sPopupVisible, point } = this.$data; const { sPopupVisible, point } = this.$data;
const popupProps = { const popupProps = {
prefixCls, prefixCls,
@ -463,7 +463,12 @@ export default defineComponent({
mobile, mobile,
forceRender, forceRender,
} as any; } as any;
return <Popup {...popupProps}>{getComponent(self, 'popup')}</Popup>; return (
<Popup
{...popupProps}
v-slots={{ default: this.$slots.popup || (() => getComponent(this, 'popup')) }}
></Popup>
);
}, },
attachParent(popupContainer) { attachParent(popupContainer) {

2
v2-doc

@ -1 +1 @@
Subproject commit 7a7b52df8b3b69d8b1a8b8dcd96e1b0f7bb3f8c9 Subproject commit 2aa53d9c7aae3b172d8837a0ba9118c3fd8c2038