Subscribe on changes!

Style-vars-2 v-bind feature issue when using transition and v-if

avatar
Jun 6th 2021

Version

3.1.0-beta.7

Reproduction link

https://codesandbox.io/s/vue3-style-vars-2-issue-v-if-style-vars-binding-inside-transition-4qtf1

Steps to reproduce

Create the following component:

<template>
  <transition>
    <div v-if="isDisplayed" class="bloc"></div>
  </transition>
</template>

<script>
import { ref } from "vue"

export default {
  setup() {
    const isDisplayed = ref(false)
    const color = "#8BA7AF"

    setTimeout(() => isDisplayed.value = true, 1000)

    return {
      isDisplayed,
      color
    }
  }
}
</script>

<style scoped>
.bloc {
  width: 100px;
  height: 100px;
  background-color: v-bind(color);
}
</style>

The transition content will be displayed one second after the component was created.

What is expected?

The HTML node (transition child) should contain the style variables.

What is actually happening?

The HTML node (transition child) doesn't contain the style variables so the component is not well displayed.

sample


It doesn't work either with OptionAPI, neither with CompositionAPI. DOM inspection:

<div id="app" data-v-app="">
    <div class="bloc" data-v-149ffcac="" style="--149ffcac-color:#9F8BAF;"> [OptionAPI] not deferred</div>
    <div class="bloc" data-v-885362c0="" style="--885362c0-color:#8BA7AF;"> [CompositionAPI] not deferred</div>
    <div class="bloc" data-v-149ffcac=""> [OptionAPI] deferred</div>
    <div class="bloc" data-v-885362c0=""> [CompositionAPI] deferred</div>
</div>
avatar
Jun 7th 2021

as a workaround:

<template>
+   <div style="display:none">{{isDisplayed}}</div>
    <transition>
    <div v-if="isDisplayed" class="bloc">
      [CompositionAPI]
      {{ isDeferred ? "deferred" : "not deferred" }}
    </div>
  </transition>
</template>

The root cause is useCssVars called before the transition content is displayed and not re-called when subtree changed. this means the onUpdated is not called so that useCssVars is not called. if add <div style="display:none">{{isDisplayed}}</div>, the useCssVars will be re-called when isDisplayed changed.

With Options API also not working. see https://codesandbox.io/s/vue3-style-vars-2-issue-v-if-style-vars-binding-inside-transition-forked-hum9u?file=/src/OptionsStyle.vue:152-162

avatar
Jul 16th 2021

Fixed via 6ed23f6 (will be out in 3.2)