Migration Problems: ExposeProxy interactions with Vue2 VueRouter
Version
3.1.4
Reproduction link
Steps to reproduce
- Open the SFC Playground link
- Read the content in rendered app in the SFC playground.
- Click the button to see that it breaks
- 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).
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.
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.
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.