mirror of https://github.com/vuejs/core.git
fix(defineModel): detect changes respect custom getter and setter (#11543)
fix: #11541 fix: #11526 close: #11527
This commit is contained in:
parent
b1abac06cd
commit
e0428884b5
|
|
@ -657,4 +657,96 @@ describe('useModel', () => {
|
||||||
expect(setValue).toBeCalledTimes(2)
|
expect(setValue).toBeCalledTimes(2)
|
||||||
expect(msg.value).toBe(defaultVal)
|
expect(msg.value).toBe(defaultVal)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #11526
|
||||||
|
test('custom getter', () => {
|
||||||
|
let changeChildMsg!: (val: boolean) => void
|
||||||
|
const getter = (value: boolean) => !value
|
||||||
|
|
||||||
|
const Comp = defineComponent({
|
||||||
|
props: ['msg'],
|
||||||
|
emits: ['update:msg'],
|
||||||
|
setup(props) {
|
||||||
|
const childMsg = useModel(props, 'msg', {
|
||||||
|
get: getter,
|
||||||
|
set: value => !value,
|
||||||
|
})
|
||||||
|
changeChildMsg = (val: boolean) => (childMsg.value = val)
|
||||||
|
return () => {
|
||||||
|
return childMsg.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const defaultVal = false
|
||||||
|
const msg = ref(defaultVal)
|
||||||
|
const Parent = defineComponent({
|
||||||
|
setup() {
|
||||||
|
return () =>
|
||||||
|
h(Comp, {
|
||||||
|
msg: msg.value,
|
||||||
|
'onUpdate:msg': val => {
|
||||||
|
msg.value = val
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
render(h(Parent), root)
|
||||||
|
|
||||||
|
changeChildMsg(!getter(msg.value))
|
||||||
|
expect(msg.value).toBe(true)
|
||||||
|
|
||||||
|
changeChildMsg(!getter(msg.value))
|
||||||
|
expect(msg.value).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
// #11541
|
||||||
|
test('custom setter', () => {
|
||||||
|
let changeChildMsg!: (val: boolean) => void
|
||||||
|
|
||||||
|
const Comp = defineComponent({
|
||||||
|
props: ['msg'],
|
||||||
|
emits: ['update:msg'],
|
||||||
|
setup(props) {
|
||||||
|
const childMsg = useModel(props, 'msg', {
|
||||||
|
set: value => {
|
||||||
|
if (value === msg.value) {
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
changeChildMsg = (val: boolean) => (childMsg.value = val)
|
||||||
|
return () => {
|
||||||
|
return childMsg.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const defaultVal = false
|
||||||
|
const msg = ref(defaultVal)
|
||||||
|
const Parent = defineComponent({
|
||||||
|
setup() {
|
||||||
|
return () =>
|
||||||
|
h(Comp, {
|
||||||
|
msg: msg.value,
|
||||||
|
'onUpdate:msg': val => {
|
||||||
|
msg.value = val
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
render(h(Parent), root)
|
||||||
|
|
||||||
|
changeChildMsg(true)
|
||||||
|
expect(msg.value).toBe(true)
|
||||||
|
|
||||||
|
changeChildMsg(true)
|
||||||
|
expect(msg.value).toBe(null)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,9 @@ export function useModel(
|
||||||
},
|
},
|
||||||
|
|
||||||
set(value) {
|
set(value) {
|
||||||
|
const emittedValue = options.set ? options.set(value) : value
|
||||||
if (
|
if (
|
||||||
!hasChanged(value, localValue) &&
|
!hasChanged(emittedValue, localValue) &&
|
||||||
!(prevSetValue !== EMPTY_OBJ && hasChanged(value, prevSetValue))
|
!(prevSetValue !== EMPTY_OBJ && hasChanged(value, prevSetValue))
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
|
|
@ -74,7 +75,7 @@ export function useModel(
|
||||||
localValue = value
|
localValue = value
|
||||||
trigger()
|
trigger()
|
||||||
}
|
}
|
||||||
const emittedValue = options.set ? options.set(value) : value
|
|
||||||
i.emit(`update:${name}`, emittedValue)
|
i.emit(`update:${name}`, emittedValue)
|
||||||
// #10279: if the local value is converted via a setter but the value
|
// #10279: if the local value is converted via a setter but the value
|
||||||
// emitted to parent was the same, the parent will not trigger any
|
// emitted to parent was the same, the parent will not trigger any
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue