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

fix(runtime-dom): before update should also set css vars #11561

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

linzhe141
Copy link
Contributor

@linzhe141 linzhe141 commented Aug 8, 2024

close #11533

before update should also set css vars

this pr playground case1

this pr playground case2

Copy link

github-actions bot commented Aug 8, 2024

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 98.8 kB (+16 B) 37.4 kB (+7 B) 33.7 kB (-36 B)
vue.global.prod.js 156 kB (+16 B) 57.2 kB (+7 B) 50.8 kB (-55 B)

Usages

Name Size Gzip Brotli
createApp 54.2 kB 21 kB 19.1 kB
createSSRApp 58.1 kB 22.6 kB 20.6 kB
defineCustomElement 58.8 kB 22.5 kB 20.5 kB
overall 67.8 kB 26 kB 23.7 kB

@linzhe141 linzhe141 changed the title fix(runtime-dom): apply css vars before mount and before update fix(runtime-dom): before update should also set css vars Aug 8, 2024
@@ -47,6 +48,10 @@ export function useCssVars(getter: (ctx: any) => Record<string, string>) {
watchPostEffect(setVars)
})

onBeforeUpdate(() => {
watchPostEffect(setVars)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should just call setVars and not create another watcher on each update.

Copy link
Contributor Author

@linzhe141 linzhe141 Aug 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I just call setVars before update, the vnode is still a v-if comment, and it doesn't make sense to set custom properties for this comment.

image

But when I combine it with watchPostEffect, the vnode is correct.

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or use queuePostFlushCb instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

@edison1105
Copy link
Member

Maybe we should add corresponding test cases to prevent regression.
Could you please try to add one?

@linzhe141
Copy link
Contributor Author

Maybe we should add corresponding test cases to prevent regression. Could you please try to add one?

Of course, I'll add the necessary test cases to prevent any regression.

@linzhe141
Copy link
Contributor Author

Maybe we should add corresponding test cases to prevent regression. Could you please try to add one?

If I want to reproduce this issue through single test, it seems that I can only do it through e2e test, and simple unit test does not seem to be able to reproduce it.

@edison1105
Copy link
Member

@linzhe141
only need to check if css vars is set in onMounted

// useCssVars.spec.ts
test('with delay mount child', async () => {
    const state = reactive({ color: 'red' })
    const value = ref(false)
    const root = document.createElement('div')

    const Child = {
      setup(){
        onMounted(()=>{
          const childEl = root.children[0]
          expect(getComputedStyle(childEl!).getPropertyValue(`--color`)).toBe(`red`)
        })
        return () => h('div',{id:'childId'})
      }
    }
    const App = {
      setup() {
        useCssVars(() => state)
        return () => value.value ? h(Child) :[h('span')]
      },
    }

    render(h(App), root)
    await nextTick()
    // css vars use with fallback tree
    for (const c of [].slice.call(root.children as any)) {
      expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
    }

    // mount child
    value.value = true
    await nextTick()
    for (const c of [].slice.call(root.children as any)) {
      expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
    }
  })

@linzhe141
Copy link
Contributor Author

@linzhe141 only need to check if css vars is set in onMounted

// useCssVars.spec.ts
test('with delay mount child', async () => {
    const state = reactive({ color: 'red' })
    const value = ref(false)
    const root = document.createElement('div')

    const Child = {
      setup(){
        onMounted(()=>{
          const childEl = root.children[0]
          expect(getComputedStyle(childEl!).getPropertyValue(`--color`)).toBe(`red`)
        })
        return () => h('div',{id:'childId'})
      }
    }
    const App = {
      setup() {
        useCssVars(() => state)
        return () => value.value ? h(Child) :[h('span')]
      },
    }

    render(h(App), root)
    await nextTick()
    // css vars use with fallback tree
    for (const c of [].slice.call(root.children as any)) {
      expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
    }

    // mount child
    value.value = true
    await nextTick()
    for (const c of [].slice.call(root.children as any)) {
      expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
    }
  })

thanks!!!!!!

@edison1105 edison1105 added 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. scope: sfc-style-vars ready for review This PR requires more reviews labels Aug 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. ready for review This PR requires more reviews scope: sfc-style-vars
Projects
None yet
Development

Successfully merging this pull request may close these issues.

v-bind in CSS values are set after the component's element is already in the DOM
3 participants