Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(custom-elemen): ce support child component style tags and attribute settings #7942

Closed
wants to merge 94 commits into from
Closed
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
6d1d290
feat(custom-element): Custom elements support child component style tags
baiwusanyu-c Mar 22, 2023
b249bbb
feat(custom-element): added code comments
baiwusanyu-c Mar 22, 2023
ce361ee
feat(custom-element): update code
baiwusanyu-c Mar 22, 2023
c097498
feat(custom-element): updated unit test
baiwusanyu-c Mar 22, 2023
5b41420
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Mar 23, 2023
2a66522
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Mar 24, 2023
a303bce
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Mar 24, 2023
610f31b
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Mar 24, 2023
d8c83c4
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Mar 26, 2023
6ddb15a
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Mar 27, 2023
4979893
Merge remote-tracking branch 'origin/main' into bwsy/fix/vOnceAndvIf
baiwusanyu-c Apr 5, 2023
cf7de4b
Merge remote-tracking branch 'origin/main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 5, 2023
30a7438
Merge remote-tracking branch 'origin/main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 5, 2023
00a683e
Merge branch 'vuejs:main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 5, 2023
9dbf8fc
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 6, 2023
642c048
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 6, 2023
51924bf
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 10, 2023
7abb1b8
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 10, 2023
5546d04
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 11, 2023
b1e2f8b
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 14, 2023
4f6ac8b
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 17, 2023
f84b699
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 19, 2023
f5c6692
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 20, 2023
bf12ded
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 24, 2023
3935fa1
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Apr 25, 2023
d0fe5e7
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c May 4, 2023
7917650
feat(runtime-dom): updated code
baiwusanyu-c May 5, 2023
b3704bf
fix(runtime-dom): temp commit
baiwusanyu-c May 5, 2023
ffa6167
feat(runtime-dom): properly handle v-if
baiwusanyu-c May 6, 2023
1864521
feat(runtime-dom): updated unit test
baiwusanyu-c May 6, 2023
eedf48f
feat(runtime-dom): remove hash sum
baiwusanyu-c May 6, 2023
996a762
feat(runtime-dom): rollback pnpm lock
baiwusanyu-c May 6, 2023
53ccce1
feat(custom-element): fix style order problem
baiwusanyu-c May 8, 2023
35c20af
feat(runtime-dom): use uid as cecStyleId
baiwusanyu-c May 11, 2023
8f91b4a
feat(runtime-dom): fix childStylesAnchor error
baiwusanyu-c May 11, 2023
794a446
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c May 12, 2023
1630c38
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c May 12, 2023
88f2f05
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c May 16, 2023
ee5030f
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c May 17, 2023
a879ab9
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c May 22, 2023
21f69af
feat(runtime-dom): Components are used multiple times without adding …
baiwusanyu-c May 31, 2023
0c5c475
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Jun 16, 2023
6f371a4
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Jul 6, 2023
379776a
chore: updated code
baiwusanyu-c Jul 23, 2023
cd68776
feat(custom-element): updated code to handle edge case
baiwusanyu-c Aug 9, 2023
d5a518a
feat(custom-element): Async component styles are lost for descendants
baiwusanyu-c Aug 10, 2023
75abdb8
feat(custom-element): Async component styles are lost for nested
baiwusanyu-c Aug 11, 2023
9e551c8
Merge branch 'main' into bwsy/feat/CEChildStyle
sxzz Aug 11, 2023
02b31c1
Merge branch 'vuejs:main' into bwsy/feat/CEChildStyle
baiwusanyu-c Aug 16, 2023
77acae7
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Aug 27, 2023
7ac6041
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Sep 12, 2023
651281a
Merge remote-tracking branch 'origin/main' into bwsy/feat/CEChildStyle
baiwusanyu-c Sep 27, 2023
bd2db96
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Oct 18, 2023
82ed3b5
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Oct 20, 2023
5743819
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Oct 21, 2023
be90bd0
chore: The order of style tags remains consistent with the playground
baiwusanyu-c Oct 23, 2023
abf0eec
chore: Remove code about style tag removal
baiwusanyu-c Oct 24, 2023
6928811
[autofix.ci] apply automated fixes
autofix-ci[bot] Oct 24, 2023
ea819a8
refactor: refactor code
baiwusanyu-c Oct 24, 2023
cbca305
Merge remote-tracking branch 'origin/bwsy/feat/CEChildStyle' into bws…
baiwusanyu-c Oct 24, 2023
ab2d81a
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Oct 24, 2023
bdb0f42
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Oct 26, 2023
5fad967
tempcommit
baiwusanyu-c Oct 26, 2023
c985113
chore: temp commit
baiwusanyu-c Oct 26, 2023
05c1891
chore: refactor code
baiwusanyu-c Oct 26, 2023
b134e13
chore: refactor code and format code
baiwusanyu-c Oct 26, 2023
2097807
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Oct 26, 2023
f3c09e7
fix: format code and fix typo
baiwusanyu-c Oct 27, 2023
f52b6ad
test: added ceStylesAttrs unit test
baiwusanyu-c Oct 27, 2023
d09dd00
chore: remove todo
baiwusanyu-c Oct 27, 2023
ce8e60d
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Oct 31, 2023
3b06ec6
feat(compiler): style attr compiler
baiwusanyu-c Nov 2, 2023
47d3900
feat(compiler): Optimization logic
baiwusanyu-c Nov 2, 2023
6ecb49c
chore(compiler): support normalScript
baiwusanyu-c Nov 2, 2023
c03e8b4
chore(custom-element): complate useCEStyleAttrs
baiwusanyu-c Nov 3, 2023
a449e22
chore(custom-element): useCEStyleAttrs unit test
baiwusanyu-c Nov 3, 2023
b697233
chore(custom-element): updated useCEStyleAttrs unit test
baiwusanyu-c Nov 6, 2023
6f7547f
chore(custom-element): compile useCEStyleAttrs unit test
baiwusanyu-c Nov 6, 2023
7532f97
chore(custom-element): updated useCEStyleAttrs unit test
baiwusanyu-c Nov 6, 2023
e39db13
Merge remote-tracking branch 'origin/main' into bwsy/feat/CEChildStyle
baiwusanyu-c Nov 6, 2023
00cc259
Merge remote-tracking branch 'origin/main' into bwsy/feat/CEChildStyle
baiwusanyu-c Nov 6, 2023
b82c7ee
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Nov 24, 2023
7a79b5e
chore: Only hmr will uninstall styles
baiwusanyu-c Nov 27, 2023
8c90a40
Merge remote-tracking branch 'origin/main' into bwsy/feat/CEChildStyle
baiwusanyu-c Dec 6, 2023
9877720
test: updated unit test snap
baiwusanyu-c Dec 6, 2023
1dfa2ab
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Dec 15, 2023
8b4a7f0
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Dec 15, 2023
1a97321
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Dec 19, 2023
40fbf73
Merge remote-tracking branch 'origin/main' into bwsy/feat/CEChildStyle
baiwusanyu-c Jan 3, 2024
b805943
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 3, 2024
9ff30fd
chore: updated unit test snap
baiwusanyu-c Jan 3, 2024
5cda20a
chore: updated unit test snap
baiwusanyu-c Jan 3, 2024
a6bb241
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Jun 5, 2024
1881ef1
Merge branch 'main' into bwsy/feat/CEChildStyle
baiwusanyu-c Aug 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/runtime-core/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import {
} from './compat/compatConfig'
import { SchedulerJob } from './scheduler'
import { LifecycleHooks } from './enums'
import { RendererNode } from './renderer'

export type Data = Record<string, unknown>

Expand Down Expand Up @@ -402,6 +403,14 @@ export interface ComponentInternalInstance {
isMounted: boolean
isUnmounted: boolean
isDeactivated: boolean

// Whether the component is a child component of a custom element
isCEChild: boolean | null
// When the component is a child component of a custom element,
// the method of adding style passed down from the ancestor
addCEChildStyle:
| null
| ((styles: string[], anchor?: RendererNode | null) => void)
/**
* @internal
*/
Expand Down Expand Up @@ -554,6 +563,14 @@ export function createComponentInstance(
isMounted: false,
isUnmounted: false,
isDeactivated: false,

// Whether the component is a child component of a custom element
isCEChild: parent && (parent.isCE || parent.isCEChild),
// When the component is a child component of a custom element,
// the method of adding style passed down from the ancestor
addCEChildStyle:
parent && parent.addCEChildStyle ? parent.addCEChildStyle : null,

bc: null,
c: null,
bm: null,
Expand Down
22 changes: 22 additions & 0 deletions packages/runtime-core/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import {
ComponentInternalInstance,
ComponentOptions,
ConcreteComponent,
createComponentInstance,
Data,
setupComponent
Expand Down Expand Up @@ -708,6 +709,27 @@ function baseCreateRenderer(
if (needCallTransitionHooks) {
transition!.beforeEnter(el)
}

// The component has styles
// and is a child component of a custom element,
// then inject the style into the shadow dom
if (
parentComponent &&
parentComponent.parent &&
// If the parent component is wrapped by an defineAsyncComponent function,
// it will not be processed
!(parentComponent.parent.type as ComponentOptions).__asyncLoader
) {
const styles =
(parentComponent.isCEChild &&
(parentComponent.type as ConcreteComponent & { styles?: string[] })
.styles) ||
null
if (parentComponent.addCEChildStyle && styles) {
parentComponent.addCEChildStyle(styles, anchor)
}
}

hostInsert(el, container, anchor)
if (
(vnodeHook = props && props.onVnodeMounted) ||
Expand Down
54 changes: 54 additions & 0 deletions packages/runtime-dom/__tests__/customElement.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,31 @@ describe('defineCustomElement', () => {
const style = el.shadowRoot?.querySelector('style')!
expect(style.textContent).toBe(`div { color: red; }`)
})

test('child components in shadow dom should have styles', async () => {
const Child = {
styles: [`.Child { color: blue; }`],
render() {
return h('div', { class: 'Child' }, 'hello')
}
}
const Foo = defineCustomElement({
components: { Child },
styles: [`div { color: red; }`],
render() {
return h('div', {}, ['hello', h(Child)])
}
})
customElements.define('my-el-with-child-styles', Foo)
container.innerHTML = `<my-el-with-child-styles></my-el-with-child-styles>`
await nextTick()

const el = container.childNodes[0] as VueElement
const style = el.shadowRoot?.querySelectorAll('style')!
expect(style.length).toBe(2)
expect(style[0].textContent).toBe(`div { color: red; }`)
expect(style[1].textContent).toBe(`.Child { color: blue; }`)
})
})

describe('async', () => {
Expand Down Expand Up @@ -602,6 +627,35 @@ describe('defineCustomElement', () => {
)
})

test('child components in shadow dom should have styles & async', async () => {
const Child = {
styles: [`.Child { color: blue; }`],
render() {
return h('div', { class: 'Child' }, 'hello')
}
}
const Foo = defineCustomElement(
defineAsyncComponent(() => {
return Promise.resolve({
components: { Child },
styles: [`div { color: red; }`],
render() {
return h('div', {}, ['hello', h(Child)])
}
})
})
)
customElements.define('my-el-with-child-styles-async', Foo)
container.innerHTML = `<my-el-with-child-styles-async></my-el-with-child-styles-async>`
await new Promise(r => setTimeout(r))

const el = container.childNodes[0] as VueElement
const style = el.shadowRoot?.querySelectorAll('style')!
expect(style.length).toBe(2)
expect(style[0].textContent).toBe(`div { color: red; }`)
expect(style[1].textContent).toBe(`.Child { color: blue; }`)
})

test('set DOM property before resolve', async () => {
const E = defineCustomElement(
defineAsyncComponent(() => {
Expand Down
26 changes: 23 additions & 3 deletions packages/runtime-dom/src/apiCustomElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import {
ConcreteComponent,
ComponentOptions,
ComponentInjectOptions,
SlotsType
SlotsType,
RendererNode
} from '@vue/runtime-core'
import { camelize, extend, hyphenate, isArray, toNumber } from '@vue/shared'
import { hydrate, render } from '.'
Expand Down Expand Up @@ -357,6 +358,9 @@ export class VueElement extends BaseClass {
vnode.ce = instance => {
this._instance = instance
instance.isCE = true
// Reference the _addStyles method on the instance,
// which will be used to add styles in the child components of the custom element
instance.addCEChildStyle = this._addStyles.bind(this)
// HMR
if (__DEV__) {
instance.ceReload = newStyles => {
Expand Down Expand Up @@ -406,17 +410,33 @@ export class VueElement extends BaseClass {
return vnode
}

private _applyStyles(styles: string[] | undefined) {
private _applyStyles(
styles: string[] | undefined,
anchor?: RendererNode | null
) {
if (styles) {
styles.forEach(css => {
const s = document.createElement('style')
s.textContent = css
this.shadowRoot!.appendChild(s)
if (anchor) {
this.shadowRoot!.insertBefore(s, anchor as Node)
} else {
this.shadowRoot!.appendChild(s)
}
baiwusanyu-c marked this conversation as resolved.
Show resolved Hide resolved
// record for HMR
if (__DEV__) {
;(this._styles || (this._styles = [])).push(s)
}
})
}
}

// The method used by custom element child components
// to add styles to the shadow dom
protected _addStyles(
styles: string[] | undefined,
anchor: RendererNode | null | undefined
) {
this._applyStyles(styles, anchor)
}
}