2020-05-13 10:36:53 +00:00
|
|
|
import PropTypes from './vue-types';
|
2020-10-12 05:27:16 +00:00
|
|
|
import { defineComponent, Teleport } from 'vue';
|
2020-05-13 10:36:53 +00:00
|
|
|
|
2020-10-12 05:27:16 +00:00
|
|
|
export default defineComponent({
|
2020-05-13 10:36:53 +00:00
|
|
|
name: 'Portal',
|
|
|
|
props: {
|
2020-10-02 07:44:10 +00:00
|
|
|
getContainer: PropTypes.func.isRequired,
|
2020-05-13 10:36:53 +00:00
|
|
|
children: PropTypes.any.isRequired,
|
|
|
|
didUpdate: PropTypes.func,
|
|
|
|
},
|
2020-10-02 07:44:10 +00:00
|
|
|
data() {
|
2020-06-10 10:21:16 +00:00
|
|
|
this._container = null;
|
2020-10-02 07:44:10 +00:00
|
|
|
return {};
|
2020-06-10 10:21:16 +00:00
|
|
|
},
|
2020-05-13 10:36:53 +00:00
|
|
|
mounted() {
|
|
|
|
this.createContainer();
|
|
|
|
},
|
|
|
|
updated() {
|
|
|
|
const { didUpdate } = this.$props;
|
|
|
|
if (didUpdate) {
|
|
|
|
this.$nextTick(() => {
|
|
|
|
didUpdate(this.$props);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2020-06-11 08:13:09 +00:00
|
|
|
beforeUnmount() {
|
2020-05-13 10:36:53 +00:00
|
|
|
this.removeContainer();
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
createContainer() {
|
|
|
|
this._container = this.$props.getContainer();
|
|
|
|
this.$forceUpdate();
|
|
|
|
},
|
|
|
|
removeContainer() {
|
2020-05-17 14:30:16 +00:00
|
|
|
if (this._container && this._container.parentNode) {
|
2020-05-13 10:36:53 +00:00
|
|
|
this._container.parentNode.removeChild(this._container);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
render() {
|
|
|
|
if (this._container) {
|
2020-06-10 10:21:16 +00:00
|
|
|
return <Teleport to={this._container}>{this.$props.children}</Teleport>;
|
2020-05-13 10:36:53 +00:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
2020-10-12 05:27:16 +00:00
|
|
|
});
|