mirror of https://github.com/vuejs/core.git
parent
e181bff6dc
commit
5a1a89bd61
|
@ -417,7 +417,7 @@ export interface ComponentInternalInstance {
|
|||
* is custom element?
|
||||
* @internal
|
||||
*/
|
||||
isCE?: boolean
|
||||
isCE?: Element
|
||||
/**
|
||||
* custom element specific HMR method
|
||||
* @internal
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
ref,
|
||||
render,
|
||||
renderSlot,
|
||||
useShadowRoot,
|
||||
} from '../src'
|
||||
|
||||
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,
|
||||
createVNode,
|
||||
defineComponent,
|
||||
getCurrentInstance,
|
||||
nextTick,
|
||||
warn,
|
||||
} from '@vue/runtime-core'
|
||||
|
@ -191,7 +192,10 @@ export class VueElement extends BaseClass {
|
|||
private _numberProps: Record<string, true> | null = null
|
||||
private _styles?: HTMLStyleElement[]
|
||||
private _ob?: MutationObserver | null = null
|
||||
private _root: Element | ShadowRoot
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public _root: Element | ShadowRoot
|
||||
private _slots?: Record<string, Node[]>
|
||||
|
||||
constructor(
|
||||
|
@ -247,6 +251,7 @@ export class VueElement extends BaseClass {
|
|||
this._ob = null
|
||||
}
|
||||
render(null, this._root)
|
||||
this._instance!.isCE = undefined
|
||||
this._instance = null
|
||||
}
|
||||
})
|
||||
|
@ -395,7 +400,7 @@ export class VueElement extends BaseClass {
|
|||
if (!this._instance) {
|
||||
vnode.ce = instance => {
|
||||
this._instance = instance
|
||||
instance.isCE = true
|
||||
instance.isCE = this
|
||||
// HMR
|
||||
if (__DEV__) {
|
||||
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 {
|
||||
defineCustomElement,
|
||||
defineSSRCustomElement,
|
||||
useShadowRoot,
|
||||
VueElement,
|
||||
type VueElementConstructor,
|
||||
} from './apiCustomElement'
|
||||
|
|
Loading…
Reference in New Issue