Subscribe on changes!

Transition not working with custom transition classes in Vue 3 migration build

avatar
Jul 11th 2022

Vue version

3.2.37 (migration build)

Link to minimal reproduction

https://github.com/jamisuomalainen/vue-3-migration-build-transition-bug

Steps to reproduce

  1. Clone the repro-project: git clone git@github.com:jamisuomalainen/vue-3-migration-build-transition-bug.git
  2. Run yarn install in the project folder
  3. Run yarn serve in the project folder
  4. Open the running app in any browser
  5. Click the "Toggle text"-button
  6. See errors in browser console
  7. See src/App.vue for the defined transition and transition classes

What is expected?

On the first button click, the visible text should fade out in half a second.

On the second button click, the viisble text should fade in in half a second.

Subsequent button clicks repeat this cycle as it toggles the text visibility.

What is actually happening?

On the first button click: no transition happens and the text stays visible. Additionally, two warnings and one error is shown in Chrome's console:

Warning 1
[Vue warn]: Unhandled error during execution of transition hook 
  at <BaseTransition appear=false persisted=false mode=undefined  ... > 
  at <Transition enter-active-class="transition-duration" enter-from-class="opacity-0" enter-to-class="opacity-100"  ... > 
  at <App> 
  at <App>
Warning 2
[Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core 
  at <BaseTransition appear=false persisted=false mode=undefined  ... > 
  at <Transition enter-active-class="transition-duration" enter-from-class="opacity-0" enter-to-class="opacity-100"  ... > 
  at <App> 
  at <App>
Error
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'split')
    at addTransitionClass (vue.runtime.esm-bundler.js?fe26:12154:1)
    at onLeave (vue.runtime.esm-bundler.js?fe26:12073:1)
    at callWithErrorHandling (vue.runtime.esm-bundler.js?fe26:1563:1)
    at callWithAsyncErrorHandling (vue.runtime.esm-bundler.js?fe26:1563:1)
    at callHook (vue.runtime.esm-bundler.js?fe26:4136:1)
    at callAsyncHook (vue.runtime.esm-bundler.js?fe26:4136:1)
    at leave (vue.runtime.esm-bundler.js?fe26:4178:1)
    at performLeave (vue.runtime.esm-bundler.js?fe26:9325:1)
    at remove (vue.runtime.esm-bundler.js?fe26:9325:1)
    at unmount (vue.runtime.esm-bundler.js?fe26:9325:1)

On subsequent button clicks: no transition happens and the text stays visible. Additionally, one warning and one error is shown in Chrome's console:

Warning
[Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core 
  at <BaseTransition appear=false persisted=false mode=undefined  ... > 
  at <Transition enter-active-class="transition-duration" enter-from-class="opacity-0" enter-to-class="opacity-100"  ... > 
  at <App> 
  at <App>
Error
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'parentNode')
    at parentNode (vue.runtime.esm-bundler.js?fe26:11208:1)
    at ReactiveEffect.componentUpdateFn [as fn] (vue.runtime.esm-bundler.js?fe26:8920:1)
    at ReactiveEffect.run (vue.runtime.esm-bundler.js?fe26:495:1)
    at instance.update (vue.runtime.esm-bundler.js?fe26:8953:1)
    at callWithErrorHandling (vue.runtime.esm-bundler.js?fe26:1563:1)
    at flushJobs (vue.runtime.esm-bundler.js?fe26:1909:1)

System Info

System:
    OS: macOS 12.4
    CPU: (4) x64 Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz
    Memory: 23.81 MB / 8.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.10.0 - ~/.nvm/versions/node/v16.10.0/bin/node
    Yarn: 1.22.17 - ~/.yarn/bin/yarn
    npm: 7.24.0 - ~/.nvm/versions/node/v16.10.0/bin/npm
    Watchman: 2022.02.14.00 - /usr/local/bin/watchman
  Browsers:
    Chrome: 103.0.5060.114
    Firefox Developer Edition: 103.0
    Safari: 15.5
  npmPackages:
    vue: ^3.1.0 => 3.2.37

Any additional comments?

Encountered this bug as we are currently in the progress of adding the Vue 3 migration build to our Vue 2.6.14 (Vue CLI 5.0.8) app.

I could not reproduce this issue on StackBlitz because (if I understood correctly) it does not run the app via the Vue CLI service (Webpack) and thus does not seem to use the migration build.

Please let me know if I can be of any more assistance or provide any more information regarding the subject.

avatar
Jul 11th 2022

Here, we create the legacyLeaveFromClass only if there isn't a custom classname set.

https://github.com/vuejs/core/blob/6f1b36d0a8e2ec4f7c8f8f082056c6c32226da92/packages/runtime-dom/src/components/Transition.ts#L152-L155

as OP has set one, it stays undefined

But here, we try and apply this (undefined) legacyclass) regardless of wether or not it's actually defined:

https://github.com/vuejs/core/blob/6f1b36d0a8e2ec4f7c8f8f082056c6c32226da92/packages/runtime-dom/src/components/Transition.ts#L232-L235

The solution would likely be to just skip this step if the class is undefined (because we now have a custom class to apply anyway), i.e. like this:

if (__COMPAT__ && legacyClassEnabled && legacyLeaveFromClass) {
  addTransitionClass(el, legacyLeaveFromClass)
}

this has to be fixed for the other legacy classes and their addition/removal as well.

avatar
Dec 10th 2022

Any update on when this will be merged? Same here for us.

avatar
Dec 14th 2022

Any update here? This is a huge thing if this is not solved, as this cannot be worked around.

Even when deactivating the TRANSITION_CLASSES in the compatConfig, this error will still be there.