Subscribe on changes!

Migration Problems: ExposeProxy interactions with Vue2 VueRouter

avatar
Jul 6th 2021

Version

3.1.4

Reproduction link

https://tinyurl.com/4hewu2k6

Steps to reproduce

  1. Open the SFC Playground link
  2. Read the content in rendered app in the SFC playground.
  3. Click the button to see that it breaks
  4. Consider removing the 'expose()' call in parent and retriggering the button.

What is expected?

The Vue2 router to work during the migration process, which it does for the most part. ExposeProxy runs amuck on the VueRouter.

What is actually happening?

The ExposeProxy (correctly) prevents internal information from being exposed, but the Vue2 based VueRouter depends on this functionality to properly function, so parent components using ExposeProxy will break the VueRouter during migration.


This is not a functionality bug in Vue2 nor Vue3. This is exclusively a behavior "problem" visible when migrating Vue2 code to Vue3. I'm surfacing this because it bit me pretty hard when suddenly after upgrading a library from Vue2 to Vue3 (that was rewritten to use the composition api expose) portions of my App's component tree no longer had access to the VueRouter (which was still on the Vue2 based VueRouter).

avatar
Jul 6th 2021

I would suggest not using expose (which isn't even a merged RFC yet) before you migrate to Vue Router 4.x. This is unfortuanately a wontfix.

avatar
Jul 6th 2021

To be clear, this issue is not opened with the hope that something will be fixed. It is opened to help explain this functionality problem for other users that are upgrading.

avatar
Jul 6th 2021

As a note, this was originally noticed in focus-trap-vue after it started using expose({ ... }) to expose some methods since it was returning a render function from the setup function.

The workaround to handle this (at least for now while the userbase is migrating) involves exposing a renderImpl function publicly along with the methods we actually wanted to reveal via the object returned by setup. The renderImpl is then used in an options-style attached render function. https://github.com/posva/focus-trap-vue/pull/376

This work around works to not break users, but it isn't fantastic.