perf: portal

refactor-trigger
tangjinzhou 2021-08-15 09:46:32 +08:00
parent 448e912571
commit 44acf6139d
4 changed files with 33 additions and 42 deletions

View File

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

View File

@ -20,7 +20,6 @@ export default defineComponent({
wrapperClassName: PropTypes.string,
forceRender: PropTypes.looseBool,
getContainer: PropTypes.any,
children: PropTypes.func,
visible: PropTypes.looseBool,
},
data() {
@ -130,7 +129,7 @@ export default defineComponent({
},
render() {
const { children, forceRender, visible } = this.$props;
const { forceRender, visible } = this.$props;
let portal = null;
const childProps = {
getOpenCount: () => openCount,
@ -141,8 +140,8 @@ export default defineComponent({
portal = (
<Portal
getContainer={this.getDomContainer}
children={children(childProps)}
ref={this.savePortal}
v-slots={{ default: () => this.$slots.default?.(childProps) }}
></Portal>
);
}

View File

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

View File

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