Open
Description
Vue version
3.5.11
Link to minimal reproduction
Steps to reproduce
- 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>
- 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
},
},
},
- 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)
- 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
Activity
catsmeatman commentedon Dec 27, 2024
bug exist from Vue 3.5.0. In Vue 3.4.38 all ok.
edison1105 commentedon 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 synchronouslycore/packages/runtime-dom/src/apiCustomElement.ts
Lines 502 to 505 in 352bc88
When the watch callback for
prop1
is triggered, the value ofprop2
is still the old one. while normal components are rendered asynchronously, bothprop1
andprop2
have the latest values.a workaround: use
watchEffect
instead ofwatch
, see Playground