Skip to content

Commit

Permalink
fix(props): should not unwrap props that are raw refs
Browse files Browse the repository at this point in the history
close #12930
  • Loading branch information
yyx990803 committed Dec 6, 2023
1 parent 947993f commit 08382f0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 12 deletions.
30 changes: 18 additions & 12 deletions src/core/instance/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,19 +95,25 @@ function initProps(vm: Component, propsOptions: Object) {
vm
)
}
defineReactive(props, key, value, () => {
if (!isRoot && !isUpdatingChildComponent) {
warn(
`Avoid mutating a prop directly since the value will be ` +
`overwritten whenever the parent component re-renders. ` +
`Instead, use a data or computed property based on the prop's ` +
`value. Prop being mutated: "${key}"`,
vm
)
}
})
defineReactive(
props,
key,
value,
() => {
if (!isRoot && !isUpdatingChildComponent) {
warn(
`Avoid mutating a prop directly since the value will be ` +
`overwritten whenever the parent component re-renders. ` +
`Instead, use a data or computed property based on the prop's ` +
`value. Prop being mutated: "${key}"`,
vm
)
}
},
true
)
} else {
defineReactive(props, key, value)
defineReactive(props, key, value, undefined, true)
}
// static props are already proxied on the component's prototype
// during Vue.extend(). We only need to proxy props defined at
Expand Down
18 changes: 18 additions & 0 deletions test/unit/features/options/props.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Vue from 'vue'
import { hasSymbol } from 'core/util/env'
import testObjectOption from '../../../helpers/test-object-option'
import { ref } from 'v3'

describe('Options props', () => {
testObjectOption('props')
Expand Down Expand Up @@ -593,4 +594,21 @@ describe('Options props', () => {
'Invalid prop type: "String" is not a constructor'
).toHaveBeenWarned()
})

// #12930
it('should not unwrap prop values that are raw refs', () => {
let val
const Comp = {
props: ['msg'],
created() {
val = this.msg
},
render() {}
}
const r = ref()
new Vue({
render: h => h(Comp, { props: { msg: r }})
}).$mount()
expect(val).toBe(r)
})
})

0 comments on commit 08382f0

Please sign in to comment.