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

Using watch to observe a prop in a vue custom element, the other props accessed in the listener are the old values. #12619

Open
hanshy1 opened this issue Dec 26, 2024 · 2 comments
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. has workaround A workaround has been found to avoid the problem scope: custom elements

Comments

@hanshy1
Copy link

hanshy1 commented Dec 26, 2024

Vue version

3.5.11

Link to minimal reproduction

https://play.vuejs.org/#eNqVVU1v2zAM/SuEL3aL1Knd7pIlAbaih+2wFWuPBgbPZhJ3smRIcpohyH8fJfkrTdK0udQin56eHil2632pqnBdozfxpiqTRaVBoa6recKLshJSwxYkLmAHCylK8Anqd6m7VcHyJhGO7cpw9YAt5LgoON7VSovynmGJXO9xfU54wjPBlYZ1ymqMYGbOC3xBzC7iX+wh4gNEbBAJJ91PRYmi1kFwAbM5bBMODUdo/9BOn+NLy9ul4yPpmNK7EVxb6vHl5cf5r86dYAF0RnRtToHLsfViaJUKnX+Br1HpK2T+6JijgbX+gkimY1dEKh8tNJYVSzXSCmCaF+t5liqEaDIdm4WNNsQwqaSoolniOfGJ5yJxG4kTbz4dN2i39Y98RRyfJB7SHB51lvhmSOy67n16LfYE6e0J0rNaX5Ma9Z3R3sjTitp1USzDZyU4PSzbJ4mXibIqGMqflS6onRNv4jrI5FLGxMt3G9OyxlEbz1aY/T0Sf1YbE0u8B4kK5RoTr8vpVC5Ru/T94w/c0HeXLEVeM0K/kfyFSrDaaHSwrzXPSfYAZ9V+s0+84Msndb/RyFV7KSPUIHcWT87VePfG1Xu5N+Gt3UePglzsxokZTQedDBlLlaK65FgKqopjs8W1FYNCwXYLZt+DXe92fbUHwPgVMN4Dtl97FSbRvJmVzQo3dtrRy0xrRlPPRA256q5pNXUrAP2vwgk8akn+NbZCu38CfvPlBkjrpGOJP8xiJpll6YuSpzqlGdYQSRr4kg9oW9N6Dr+j74xqktQph/wvqc5WJy+/Sm1DBfSkOg3mZ4a8YBgysQx8V8WMsEvMR+7qplY0AfWqUKENmLHZ/Gywr+JsgGpBrY2n7Hy3rnhfl2m2oazolCzzz61HHZPVW1iKmmvM2yqZIBk8mO/0RH6vUZpnRy/kJvwURpG3+w9vZ4NB

Steps to reproduce

  1. Add custom components in the <template> of the parent component with different prop orders.
<template>
  <test-el :prop1="value1" :prop2="value2"></test-el>
  <test-el :prop2="value2" :prop1="value1"></test-el>
</template>
  1. Use watch in the child component to monitor changes in a prop and record the value of another prop.
  watch: {
    prop1: {
      handler(val) {
        console.log('prop1 changed, prop2 is ', this.prop2)
        this.tempProp2 = this.prop2
      },
    },
    prop2: {
      handler(val) {
        console.log('prop2 changed, prop1 is', this.prop1)
        this.tempProp1 = this.prop1
      },
    },
  },
  1. Update the prop value in the parent component.
const value1 = ref('old value1')
const value2 = ref('old value2')

setTimeout(() => {
  value1.value = 'new value1'
  value2.value = 'new value2'
}, 0)
  1. Observe the results.

What is expected?

The watch listener in a custom element can access the latest prop values.

What is actually happening?

For a custom element, when using watch to observe a prop, accessing the values of other props defined later in the order within the listener will return their old values.

System Info

No response

Any additional comments?

No response

@edison1105 edison1105 added 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. scope: custom elements labels Dec 27, 2024
@catsmeatman
Copy link

catsmeatman commented Dec 27, 2024

bug exist from Vue 3.5.0. In Vue 3.4.38 all ok.

@edison1105
Copy link
Member

edison1105 commented Dec 30, 2024

@catsmeatman
It seems not, see Playground with v3.4.38. Does the issue you're experiencing seem different from this one?

The issue is caused by custom-element being rendered synchronously

}
if (shouldUpdate && this._instance) {
this._update()
}

When the watch callback for prop1 is triggered, the value of prop2 is still the old one. while normal components are rendered asynchronously, both prop1 and prop2 have the latest values.

a workaround: use watchEffect instead of watch, see Playground

@edison1105 edison1105 added the has workaround A workaround has been found to avoid the problem label Dec 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. has workaround A workaround has been found to avoid the problem scope: custom elements
Projects
None yet
Development

No branches or pull requests

3 participants