mirror of https://github.com/vuejs/core.git
fix(defineModel): support local mutation when only prop but no listener is passed
This commit is contained in:
parent
6fab8551e4
commit
97ce041910
|
@ -279,6 +279,41 @@ describe('SFC <script setup> helpers', () => {
|
|||
expect(serializeInner(root)).toBe('bar')
|
||||
})
|
||||
|
||||
test('without parent listener (local mutation)', async () => {
|
||||
let foo: any
|
||||
const update = () => {
|
||||
foo.value = 'bar'
|
||||
}
|
||||
|
||||
const compRender = vi.fn()
|
||||
const Comp = defineComponent({
|
||||
props: ['foo'],
|
||||
emits: ['update:foo'],
|
||||
setup(props) {
|
||||
foo = useModel(props, 'foo')
|
||||
return () => {
|
||||
compRender()
|
||||
return foo.value
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const root = nodeOps.createElement('div')
|
||||
// provide initial value
|
||||
render(h(Comp, { foo: 'initial' }), root)
|
||||
expect(compRender).toBeCalledTimes(1)
|
||||
expect(serializeInner(root)).toBe('initial')
|
||||
|
||||
expect(foo.value).toBe('initial')
|
||||
update()
|
||||
// when parent didn't provide value, local mutation is enabled
|
||||
expect(foo.value).toBe('bar')
|
||||
|
||||
await nextTick()
|
||||
expect(compRender).toBeCalledTimes(2)
|
||||
expect(serializeInner(root)).toBe('bar')
|
||||
})
|
||||
|
||||
test('default value', async () => {
|
||||
let count: any
|
||||
const inc = () => {
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
type LooseRequired,
|
||||
type Prettify,
|
||||
type UnionToIntersection,
|
||||
camelize,
|
||||
extend,
|
||||
hasChanged,
|
||||
isArray,
|
||||
|
@ -380,6 +381,8 @@ export function useModel(
|
|||
return ref() as any
|
||||
}
|
||||
|
||||
const camelizedName = camelize(name)
|
||||
|
||||
const res = customRef((track, trigger) => {
|
||||
let localValue: any
|
||||
watchSyncEffect(() => {
|
||||
|
@ -396,7 +399,16 @@ export function useModel(
|
|||
},
|
||||
set(value) {
|
||||
const rawProps = i.vnode!.props
|
||||
if (!(rawProps && name in rawProps) && hasChanged(value, localValue)) {
|
||||
if (
|
||||
!(
|
||||
rawProps &&
|
||||
// check if parent has passed v-model
|
||||
(name in rawProps || camelizedName in rawProps) &&
|
||||
(`onUpdate:${name}` in rawProps ||
|
||||
`onUpdate:${camelizedName}` in rawProps)
|
||||
) &&
|
||||
hasChanged(value, localValue)
|
||||
) {
|
||||
localValue = value
|
||||
trigger()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue