vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
45.61k stars 8k forks source link

Compiled Vue 2.7 Script Setup Components crash when mounted in Vue 3 Compat #11164

Open jssullivan opened 2 weeks ago

jssullivan commented 2 weeks ago

Vue version

3.4.27 (happens in 3.3 as well) with both Vue Compat and Vue

Link to minimal reproduction

https://github.com/jssullivan/vue-3-not-running-compiled-script-setup

Steps to reproduce

1.Pull down the linked repository 2.Run pnpm i && pnpm dev

  1. Open the app, Click the first button of a Compiled Vue 3 component working correctly
  2. Click the second button, this is a Compiled Vue 2 component that uses the Composition Api with defineComponent
  3. Click the last button, this is a Compiled Vue 2 component that uses script setup, see this crashes when trying to read the ref hello_vue_team

What is expected?

All three components render correctly

What is actually happening?

It crashes when reading the variable hello_vue_team defined in the script setup of the compiled Vue 2.7 component.

System Info

No response

Any additional comments?

Looking from a debugger it appears that the variable hello_vue_team is being correctly evaluated and attached to this. However _vm._self._setupProxy is undefined (which also happens for a non script setup component in that example).

Screenshot 2024-06-17 at 5 00 11 PM

This only caused a warning for the defineComponent compiled component, as the template as its reading directly from _vm

Screenshot 2024-06-17 at 5 00 30 PM

Naively in this minimum viable repro, it seems like thisProxy._self._setupProxy needs to be set to thisProxy inside renderComponentRoot. I can submit a PR with that change, but don't know if there are other impacts. I can alternatively add this to compatRender in @vue/compat.

Appreciate the assistance!

jssullivan commented 2 weeks ago

If others hit this, you can apply this pnpm patch to compatRender in @vue/compat to address this crash. https://github.com/jssullivan/vue-3-not-running-compiled-script-setup/commit/7dcda5b5f0b2db551cd86c848ed8558aae75f9f0

I can create an MR to add this, or create a new @vue/compat flag to add this. Looking at the Vue 2 code _setupProxy only contains values returned from the setup function vs the whole component instance. But this should handle most cases, and atleast create warnings instead of a crash.

yyx990803 commented 1 week ago

Technically pre-compiled components have no compatibility guarantees as it relies on Vue 2 internals and we strongly recommend you to use the source SFC instead of Vue 2 compiled code.

That said if you can submit a PR to get these components working I'd be happy to merge it.