perf: portal

refactor-date
tangjinzhou 2021-08-12 09:54:46 +08:00
parent 70f9b02f51
commit f32cbaf306
7 changed files with 46 additions and 55 deletions

View File

@ -1,48 +1,38 @@
import PropTypes from './vue-types'; import PropTypes from './vue-types';
import { defineComponent, nextTick, Teleport } from 'vue'; import {
defineComponent,
nextTick,
onBeforeUnmount,
onMounted,
onUpdated,
ref,
Teleport,
} from 'vue';
export default defineComponent({ export default defineComponent({
name: 'Portal', name: 'Portal',
props: { props: {
getContainer: PropTypes.func.isRequired, getContainer: PropTypes.func.isRequired,
children: PropTypes.any.isRequired,
didUpdate: PropTypes.func, didUpdate: PropTypes.func,
}, },
data() { setup(props, { slots }) {
this._container = null; const container = ref();
return {};
}, onMounted(() => {
mounted() { container.value = props.getContainer();
this.createContainer(); });
}, onUpdated(() => {
updated() {
const { didUpdate } = this.$props;
if (didUpdate) {
nextTick(() => { nextTick(() => {
didUpdate(this.$props); props.didUpdate?.(props);
}); });
} });
}, onBeforeUnmount(() => {
container.value &&
beforeUnmount() { container.value.parentNode &&
this.removeContainer(); container.value.parentNode.removeChild(container.value);
}, });
methods: { return () => {
createContainer() { return container.value ? <Teleport to={container.value}>{slots.default?.()}</Teleport> : null;
this._container = this.$props.getContainer(); };
this.$forceUpdate();
},
removeContainer() {
if (this._container && this._container.parentNode) {
this._container.parentNode.removeChild(this._container);
}
},
},
render() {
if (this._container) {
return <Teleport to={this._container}>{this.$props.children}</Teleport>;
}
return null;
}, },
}); });

View File

@ -141,8 +141,8 @@ export default defineComponent({
portal = ( portal = (
<Portal <Portal
getContainer={this.getDomContainer} getContainer={this.getDomContainer}
children={children(childProps)}
ref={this.savePortal} ref={this.savePortal}
v-slots={{ default: () => children(childProps) }}
></Portal> ></Portal>
); );
} }

View File

@ -35,9 +35,11 @@ const DialogWrap = defineComponent({
visible={visible} visible={visible}
forceRender={forceRender} forceRender={forceRender}
getContainer={getContainer} getContainer={getContainer}
children={childProps => { v-slots={{
dialogProps = { ...dialogProps, ...childProps }; default: childProps => {
return <Dialog {...dialogProps}>{getSlot(this)}</Dialog>; dialogProps = { ...dialogProps, ...childProps };
return <Dialog {...dialogProps}>{getSlot(this)}</Dialog>;
},
}} }}
/> />
); );

View File

@ -147,22 +147,20 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
watch( watch(
() => props.open, () => props.open,
() => { () => {
if (!props.multiple && props.open && props.values.size === 1) { nextTick(() => {
const value = Array.from(props.values)[0]; if (!props.multiple && props.open && props.values.size === 1) {
const index = memoFlattenOptions.value.findIndex(({ data }) => data.value === value); const value = Array.from(props.values)[0];
setActive(index); const index = memoFlattenOptions.value.findIndex(({ data }) => data.value === value);
nextTick(() => { setActive(index);
scrollIntoView(index); scrollIntoView(index);
}); }
} // Force trigger scrollbar visible when open
// Force trigger scrollbar visible when open if (props.open) {
if (props.open) {
nextTick(() => {
listRef.current?.scrollTo(undefined); listRef.current?.scrollTo(undefined);
}); }
} });
}, },
{ immediate: true, flush: 'post' }, { immediate: true },
); );
// ========================== Values ========================== // ========================== Values ==========================

View File

@ -131,6 +131,7 @@ const SelectTrigger = defineComponent<SelectTriggerProps, { popupRef: any }>({
[`${dropdownPrefixCls}-empty`]: empty, [`${dropdownPrefixCls}-empty`]: empty,
})} })}
popupStyle={popupStyle} popupStyle={popupStyle}
// destroyPopupOnHide
// getTriggerDOMNode={getTriggerDOMNode} // getTriggerDOMNode={getTriggerDOMNode}
> >
{getSlot(this)[0]} {getSlot(this)[0]}

View File

@ -648,7 +648,7 @@ export default defineComponent({
portal = ( portal = (
<Portal <Portal
key="portal" key="portal"
children={this.getComponent()} v-slots={{ default: this.getComponent }}
getContainer={this.getContainer} getContainer={this.getContainer}
didUpdate={this.handlePortalUpdate} didUpdate={this.handlePortalUpdate}
></Portal> ></Portal>

2
v2-doc

@ -1 +1 @@
Subproject commit 2924233b60d3645d3df5e86e8bec912d3a13496d Subproject commit 6b53258cc2b3709e070d340714e992760e660e67