Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Destructured prop variables aren't returned from setup() #11325

Closed
magicandskill opened this issue Jul 9, 2024 · 7 comments
Closed

Destructured prop variables aren't returned from setup() #11325

magicandskill opened this issue Jul 9, 2024 · 7 comments

Comments

@magicandskill
Copy link

magicandskill commented Jul 9, 2024

Vue version

3.4.29

Link to minimal reproduction

https://github.com/magicandskill/vuejs-props-reassignment-reactivity/tree/main

Steps to reproduce

npm install,
npm run dev,
press the add count button,

What is expected?

Props destructuring like this:

const { text, count } = defineProps(['text','count'])

doesn't affect the reactivity of the props within the template because these variables aren't returned from setup().

But reassignment like this:

const props = defineProps(['text','count'])

const text = props.text
const count = props.count

will make the props not reactive in the template because they get returned and mask the props in the template.

These two versions are creating the same variables, so the results should be consistent.

What is actually happening?

Inconsistent behaviors in regard to returned variables from setup().

System Info

No response

Any additional comments?

No response

@wangyewei
Copy link
Contributor

@linzhe141
Copy link
Contributor

const props = defineProps(['text','count'])
const text = props.text
const count = props.count

When the App component changes the text and count, the render function of the Hellowold component will be re-executed, but the setup function of Helloworld will not be re-executed, so the text and count returned by setup will not change.
So I think this should be correct.

@magicandskill
Copy link
Author

magicandskill commented Jul 10, 2024

const props = defineProps(['text','count'])
const text = props.text
const count = props.count

When the App component changes the text and count, the render function of the Hellowold component will be re-executed, but the setup function of Helloworld will not be re-executed, so the text and count returned by setup will not change. So I think this should be correct.

But with const { text, count } = defineProps(['text','count']) the props will still be reactive within the template. I'm saying these two versions are creating the same variables, their results should be consistent.

It looks like script setup automatically returns all variables except the ones created through props destructuring

@linzhe141
Copy link
Contributor

const props = defineProps(['text','count'])
const text = props.text
const count = props.count

When the App component changes the text and count, the render function of the Hellowold component will be re-executed, but the setup function of Helloworld will not be re-executed, so the text and count returned by setup will not change. So I think this should be correct.

But with const { text, count } = defineProps(['text','count']) the props will still be reactive within the template. I'm saying these two versions are creating the same variables, their results should be consistent.

It looks like script setup automatically returns all variables except the ones created through props destructuring

You are right, the compilation results of these two are different

image
image

@yangliguo7
Copy link
Contributor

@magicandskill

When props are changed, the reason for the execution of the render function is because during template parsing, reading props will store the render function as a dep.
As @linzhe141 said
The template parsing here does not store changes to props as dependencies

image

@magicandskill
Copy link
Author

magicandskill commented Jul 11, 2024

@magicandskill

When props are changed, the reason for the execution of the render function is because during template parsing, reading props will store the render function as a dep.

As @linzhe141 said

The template parsing here does not store changes to props as dependencies

image

This issue isn't about reactivity per se, it's about consistency in regard to what variables get returned from the setup().

Destructured prop variables don't get returned from setup(). Look at the other screenshot from @linzhe141.

@magicandskill magicandskill changed the title props destructuring doesn't affect template-scope reactivity, but dot assignment does Some variables aren't returned from setup() Jul 11, 2024
@magicandskill magicandskill changed the title Some variables aren't returned from setup() Destructured prop variables aren't returned from setup() Jul 11, 2024
yyx990803 added a commit that referenced this issue Jul 17, 2024
@yyx990803
Copy link
Member

There is indeed an inconsistency. In 3.4 Reactive Props Destructure (RPD) is disabled by default. The destructured props happens to be reactive in templates because they are of the same name. It breaks if they are destructured with alias.

This is fixed in the 3.5 minor branch in 0fd6193.

Not releasing this in 3.4 line because this might break code that previously relied on the previous behavior. They would continue to work in 3.5 with RPD enabled by default. So the only case affected will be those who choose to explicitly disable RPD post 3.5, and should result in minimal impact on end users.

@github-actions github-actions bot locked and limited conversation to collaborators Aug 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants