feat(runtime-dom): support specifying shadow dom styles in defineCustomElement

This commit is contained in:
Evan You 2021-07-22 16:33:32 -04:00
parent f0ca233d8b
commit a7fa4ac28a
2 changed files with 29 additions and 6 deletions

View File

@ -274,4 +274,20 @@ describe('defineCustomElement', () => {
expect(consumer.shadowRoot!.innerHTML).toBe(`<div>changed!</div>`)
})
})
describe('styles', () => {
test('should attach styles to shadow dom', () => {
const Foo = defineCustomElement({
styles: [`div { color: red; }`],
render() {
return h('div', 'hello')
}
})
customElements.define('my-el-with-styles', Foo)
container.innerHTML = `<my-el-with-styles></my-el-with-styles>`
const el = container.childNodes[0] as VueElement
const style = el.shadowRoot?.querySelector('style')!
expect(style.textContent).toBe(`div { color: red; }`)
})
})
})

View File

@ -1,5 +1,4 @@
import {
Component,
ComponentOptionsMixin,
ComponentOptionsWithArrayProps,
ComponentOptionsWithObjectProps,
@ -18,7 +17,8 @@ import {
createVNode,
defineComponent,
nextTick,
warn
warn,
ComponentOptions
} from '@vue/runtime-core'
import { camelize, extend, hyphenate, isArray, toNumber } from '@vue/shared'
import { hydrate, render } from '.'
@ -60,7 +60,7 @@ export function defineCustomElement<
Extends,
E,
EE
>
> & { styles?: string[] }
): VueElementConstructor<Props>
// overload 3: object format with array props declaration
@ -85,7 +85,7 @@ export function defineCustomElement<
Extends,
E,
EE
>
> & { styles?: string[] }
): VueElementConstructor<{ [K in PropNames]: any }>
// overload 4: object format with object props declaration
@ -110,7 +110,7 @@ export function defineCustomElement<
Extends,
E,
EE
>
> & { styles?: string[] }
): VueElementConstructor<ExtractPropTypes<PropsOptions>>
// overload 5: defining a custom element from the returned value of
@ -176,7 +176,7 @@ export class VueElement extends BaseClass {
_connected = false
constructor(
private _def: Component,
private _def: ComponentOptions & { styles?: string[] },
private _attrKeys: string[],
private _propKeys: string[],
hydrate?: RootHydrateFunction
@ -192,6 +192,13 @@ export class VueElement extends BaseClass {
)
}
this.attachShadow({ mode: 'open' })
if (_def.styles) {
_def.styles.forEach(css => {
const s = document.createElement('style')
s.textContent = css
this.shadowRoot!.appendChild(s)
})
}
}
}