From 1b4c306376f81a6fa856542769c0645fa53a0bfa Mon Sep 17 00:00:00 2001 From: RicardoErii <‘1974364190@qq.com’> Date: Sat, 11 Mar 2023 21:25:59 +0800 Subject: [PATCH 1/3] fix(runtime-core): fix the loop end judgment of the updateCssVars function --- packages/runtime-core/src/components/Teleport.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/components/Teleport.ts b/packages/runtime-core/src/components/Teleport.ts index f9f845298dc..ca2aab1d49d 100644 --- a/packages/runtime-core/src/components/Teleport.ts +++ b/packages/runtime-core/src/components/Teleport.ts @@ -402,7 +402,7 @@ function updateCssVars(vnode: VNode) { const ctx = vnode.ctx if (ctx && ctx.ut) { let node = (vnode.children as VNode[])[0].el! - while (node !== vnode.targetAnchor) { + while (node && node !== vnode.targetAnchor) { if (node.nodeType === 1) node.setAttribute('data-v-owner', ctx.uid) node = node.nextSibling } From 6cdb77e76a542d1ac29603319df2a56223f8b5e7 Mon Sep 17 00:00:00 2001 From: RicardoErii <‘1974364190@qq.com’> Date: Tue, 28 Mar 2023 21:21:57 +0800 Subject: [PATCH 2/3] feat: Support for DefineCustomComponent passing into shadowRoot --- packages/runtime-core/src/componentOptions.ts | 4 ++- packages/runtime-dom/src/apiCustomElement.ts | 26 +++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index d0009a9f4eb..e696fd2dea3 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -89,7 +89,9 @@ import { LifecycleHooks } from './enums' * } * ``` */ -export interface ComponentCustomOptions {} +export interface ComponentCustomOptions { + shadowRoot?: boolean +} export type RenderFunction = () => VNodeChild diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts index 7710d57216a..4350a1e919a 100644 --- a/packages/runtime-dom/src/apiCustomElement.ts +++ b/packages/runtime-dom/src/apiCustomElement.ts @@ -141,7 +141,7 @@ export function defineCustomElement( class VueCustomElement extends VueElement { static def = Comp constructor(initialProps?: Record) { - super(Comp, initialProps, hydrate) + super(Comp, initialProps, hydrate, options.shadowRoot) } } @@ -169,15 +169,19 @@ export class VueElement extends BaseClass { private _resolved = false private _numberProps: Record | null = null private _styles?: HTMLStyleElement[] + private _root: ShadowRoot | HTMLElement constructor( private _def: InnerComponentDef, private _props: Record = {}, - hydrate?: RootHydrateFunction + hydrate?: RootHydrateFunction, + shadowRoot?: boolean ) { super() + if (this.shadowRoot && hydrate) { - hydrate(this._createVNode(), this.shadowRoot) + this._root = this.shadowRoot! + hydrate(this._createVNode(), this._root) } else { if (__DEV__ && this.shadowRoot) { warn( @@ -185,7 +189,13 @@ export class VueElement extends BaseClass { `defined as hydratable. Use \`defineSSRCustomElement\`.` ) } - this.attachShadow({ mode: 'open' }) + if (shadowRoot === false) { + this._root = this + } else { + this.attachShadow({ mode: 'open' }) + this._root = this.shadowRoot! + } + if (!(this._def as ComponentOptions).__asyncLoader) { // for sync component defs we can immediately resolve props this._resolveProps(this._def) @@ -208,7 +218,7 @@ export class VueElement extends BaseClass { this._connected = false nextTick(() => { if (!this._connected) { - render(null, this.shadowRoot!) + render(null, this._root) this._instance = null } }) @@ -341,7 +351,7 @@ export class VueElement extends BaseClass { } private _update() { - render(this._createVNode(), this.shadowRoot!) + render(this._createVNode(), this._root) } private _createVNode(): VNode { @@ -355,7 +365,7 @@ export class VueElement extends BaseClass { instance.ceReload = newStyles => { // always reset styles if (this._styles) { - this._styles.forEach(s => this.shadowRoot!.removeChild(s)) + this._styles.forEach(s => this._root.removeChild(s)) this._styles.length = 0 } this._applyStyles(newStyles) @@ -404,7 +414,7 @@ export class VueElement extends BaseClass { styles.forEach(css => { const s = document.createElement('style') s.textContent = css - this.shadowRoot!.appendChild(s) + this._root.appendChild(s) // record for HMR if (__DEV__) { ;(this._styles || (this._styles = [])).push(s) From c3414851222d76a1905e015a53ba7acc547d3d13 Mon Sep 17 00:00:00 2001 From: RicardoErii <‘1974364190@qq.com’> Date: Tue, 28 Mar 2023 21:25:01 +0800 Subject: [PATCH 3/3] feat(runtime-core): Support for DefineCustomComponent passing into shadowRoot --- packages/runtime-core/src/componentOptions.ts | 4 ++- packages/runtime-dom/src/apiCustomElement.ts | 26 +++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/runtime-core/src/componentOptions.ts b/packages/runtime-core/src/componentOptions.ts index d0009a9f4eb..e696fd2dea3 100644 --- a/packages/runtime-core/src/componentOptions.ts +++ b/packages/runtime-core/src/componentOptions.ts @@ -89,7 +89,9 @@ import { LifecycleHooks } from './enums' * } * ``` */ -export interface ComponentCustomOptions {} +export interface ComponentCustomOptions { + shadowRoot?: boolean +} export type RenderFunction = () => VNodeChild diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts index 7710d57216a..4350a1e919a 100644 --- a/packages/runtime-dom/src/apiCustomElement.ts +++ b/packages/runtime-dom/src/apiCustomElement.ts @@ -141,7 +141,7 @@ export function defineCustomElement( class VueCustomElement extends VueElement { static def = Comp constructor(initialProps?: Record) { - super(Comp, initialProps, hydrate) + super(Comp, initialProps, hydrate, options.shadowRoot) } } @@ -169,15 +169,19 @@ export class VueElement extends BaseClass { private _resolved = false private _numberProps: Record | null = null private _styles?: HTMLStyleElement[] + private _root: ShadowRoot | HTMLElement constructor( private _def: InnerComponentDef, private _props: Record = {}, - hydrate?: RootHydrateFunction + hydrate?: RootHydrateFunction, + shadowRoot?: boolean ) { super() + if (this.shadowRoot && hydrate) { - hydrate(this._createVNode(), this.shadowRoot) + this._root = this.shadowRoot! + hydrate(this._createVNode(), this._root) } else { if (__DEV__ && this.shadowRoot) { warn( @@ -185,7 +189,13 @@ export class VueElement extends BaseClass { `defined as hydratable. Use \`defineSSRCustomElement\`.` ) } - this.attachShadow({ mode: 'open' }) + if (shadowRoot === false) { + this._root = this + } else { + this.attachShadow({ mode: 'open' }) + this._root = this.shadowRoot! + } + if (!(this._def as ComponentOptions).__asyncLoader) { // for sync component defs we can immediately resolve props this._resolveProps(this._def) @@ -208,7 +218,7 @@ export class VueElement extends BaseClass { this._connected = false nextTick(() => { if (!this._connected) { - render(null, this.shadowRoot!) + render(null, this._root) this._instance = null } }) @@ -341,7 +351,7 @@ export class VueElement extends BaseClass { } private _update() { - render(this._createVNode(), this.shadowRoot!) + render(this._createVNode(), this._root) } private _createVNode(): VNode { @@ -355,7 +365,7 @@ export class VueElement extends BaseClass { instance.ceReload = newStyles => { // always reset styles if (this._styles) { - this._styles.forEach(s => this.shadowRoot!.removeChild(s)) + this._styles.forEach(s => this._root.removeChild(s)) this._styles.length = 0 } this._applyStyles(newStyles) @@ -404,7 +414,7 @@ export class VueElement extends BaseClass { styles.forEach(css => { const s = document.createElement('style') s.textContent = css - this.shadowRoot!.appendChild(s) + this._root.appendChild(s) // record for HMR if (__DEV__) { ;(this._styles || (this._styles = [])).push(s)