parent
e181bff6dc
commit
5a1a89bd61
|
@ -417,7 +417,7 @@ export interface ComponentInternalInstance {
|
||||||
* is custom element?
|
* is custom element?
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
isCE?: boolean
|
isCE?: Element
|
||||||
/**
|
/**
|
||||||
* custom element specific HMR method
|
* custom element specific HMR method
|
||||||
* @internal
|
* @internal
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
ref,
|
ref,
|
||||||
render,
|
render,
|
||||||
renderSlot,
|
renderSlot,
|
||||||
|
useShadowRoot,
|
||||||
} from '../src'
|
} from '../src'
|
||||||
|
|
||||||
describe('defineCustomElement', () => {
|
describe('defineCustomElement', () => {
|
||||||
|
@ -861,4 +862,23 @@ describe('defineCustomElement', () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('useCustomElementRoot', () => {
|
||||||
|
test('should work for style injection', () => {
|
||||||
|
const Foo = defineCustomElement({
|
||||||
|
setup() {
|
||||||
|
const root = useShadowRoot()!
|
||||||
|
const style = document.createElement('style')
|
||||||
|
style.innerHTML = `div { color: red; }`
|
||||||
|
root.appendChild(style)
|
||||||
|
return () => h('div', 'hello')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
customElements.define('my-el', Foo)
|
||||||
|
container.innerHTML = `<my-el></my-el>`
|
||||||
|
const el = container.childNodes[0] as VueElement
|
||||||
|
const style = el.shadowRoot?.querySelector('style')!
|
||||||
|
expect(style.textContent).toBe(`div { color: red; }`)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,6 +24,7 @@ import {
|
||||||
type VNodeProps,
|
type VNodeProps,
|
||||||
createVNode,
|
createVNode,
|
||||||
defineComponent,
|
defineComponent,
|
||||||
|
getCurrentInstance,
|
||||||
nextTick,
|
nextTick,
|
||||||
warn,
|
warn,
|
||||||
} from '@vue/runtime-core'
|
} from '@vue/runtime-core'
|
||||||
|
@ -191,7 +192,10 @@ export class VueElement extends BaseClass {
|
||||||
private _numberProps: Record<string, true> | null = null
|
private _numberProps: Record<string, true> | null = null
|
||||||
private _styles?: HTMLStyleElement[]
|
private _styles?: HTMLStyleElement[]
|
||||||
private _ob?: MutationObserver | null = null
|
private _ob?: MutationObserver | null = null
|
||||||
private _root: Element | ShadowRoot
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public _root: Element | ShadowRoot
|
||||||
private _slots?: Record<string, Node[]>
|
private _slots?: Record<string, Node[]>
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -247,6 +251,7 @@ export class VueElement extends BaseClass {
|
||||||
this._ob = null
|
this._ob = null
|
||||||
}
|
}
|
||||||
render(null, this._root)
|
render(null, this._root)
|
||||||
|
this._instance!.isCE = undefined
|
||||||
this._instance = null
|
this._instance = null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -395,7 +400,7 @@ export class VueElement extends BaseClass {
|
||||||
if (!this._instance) {
|
if (!this._instance) {
|
||||||
vnode.ce = instance => {
|
vnode.ce = instance => {
|
||||||
this._instance = instance
|
this._instance = instance
|
||||||
instance.isCE = true
|
instance.isCE = this
|
||||||
// HMR
|
// HMR
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
instance.ceReload = newStyles => {
|
instance.ceReload = newStyles => {
|
||||||
|
@ -508,3 +513,25 @@ export class VueElement extends BaseClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the shadowRoot of the current custom element. Only usable in setup()
|
||||||
|
* of a `defineCustomElement` component.
|
||||||
|
*/
|
||||||
|
export function useShadowRoot(): ShadowRoot | null {
|
||||||
|
const instance = getCurrentInstance()
|
||||||
|
const el = instance && instance.isCE
|
||||||
|
if (el) {
|
||||||
|
return el.shadowRoot
|
||||||
|
} else if (__DEV__) {
|
||||||
|
if (!instance) {
|
||||||
|
warn(`useCustomElementRoot called without an active component instance.`)
|
||||||
|
} else {
|
||||||
|
warn(
|
||||||
|
`useCustomElementRoot can only be used in components defined via ` +
|
||||||
|
`defineCustomElement.`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
|
@ -242,6 +242,7 @@ function normalizeContainer(
|
||||||
export {
|
export {
|
||||||
defineCustomElement,
|
defineCustomElement,
|
||||||
defineSSRCustomElement,
|
defineSSRCustomElement,
|
||||||
|
useShadowRoot,
|
||||||
VueElement,
|
VueElement,
|
||||||
type VueElementConstructor,
|
type VueElementConstructor,
|
||||||
} from './apiCustomElement'
|
} from './apiCustomElement'
|
||||||
|
|
Loading…
Reference in New Issue