From 90cd764ae5021421ef12cc971dfbe8c0fbd53b73 Mon Sep 17 00:00:00 2001 From: easonruan Date: Tue, 3 Dec 2019 10:36:37 +0800 Subject: [PATCH] feat: mounting-portal component support mount to customized HTMLElement (when the HTMLElement comes form other iframe so that window.document is different) --- docs/api/mounting-portal.md | 4 ++-- src/components/mounting-portal.tsx | 11 ++++++++--- src/utils/index.ts | 7 +++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/api/mounting-portal.md b/docs/api/mounting-portal.md index 36fb15d..735ffe8 100644 --- a/docs/api/mounting-portal.md +++ b/docs/api/mounting-portal.md @@ -62,9 +62,9 @@ That might lead to some unpredictable behaviour, use at your own risk | Type | Required | Default | | -------- | -------- | ------- | -| `String` | yes | `false` | +| `String`/`HTMLElement` | yes | `false` | -A querySelector String defining the DOM element to mount the `` to. +A querySelector String or HTMLElement defining the DOM element to mount the `` to. ## Portal Props diff --git a/src/components/mounting-portal.tsx b/src/components/mounting-portal.tsx index 695e958..e0c89cc 100644 --- a/src/components/mounting-portal.tsx +++ b/src/components/mounting-portal.tsx @@ -3,7 +3,7 @@ import { VNode, VueConstructor, PropOptions } from 'vue' import Portal from './portal' import PortalTarget from './portal-target' import { wormhole } from './wormhole' -import { pick } from '@/utils' +import { pick, isHTMLElement } from '@/utils' import { PropWithComponent } from '../types' @@ -12,6 +12,7 @@ let _id = 0 export type withPortalTarget = VueConstructor< Vue & { portalTarget: any + mountTo: any } > @@ -35,7 +36,9 @@ export default (Vue as withPortalTarget).extend({ bail: { type: Boolean, }, - mountTo: { type: String, required: true }, + mountTo: { + required: true, + }, // Portal disabled: { type: Boolean }, @@ -65,7 +68,9 @@ export default (Vue as withPortalTarget).extend({ }, created() { if (typeof document === 'undefined') return - let el: HTMLElement | null = document.querySelector(this.mountTo) + let el: HTMLElement | null = isHTMLElement(this.mountTo) + ? this.mountTo + : document.querySelector(this.mountTo) if (!el) { console.error( diff --git a/src/utils/index.ts b/src/utils/index.ts index c5116cc..1f0f668 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -52,3 +52,10 @@ export function pick( {} as Pick ) } + +export function isHTMLElement(target: HTMLElement | string) { + if (typeof target === 'string') { + return false + } + return target && target.nodeType && target.nodeType === 1 +}