fix(v-model): respect checkbox true-value/false-value on initial render

fix #2694
This commit is contained in:
Evan You 2020-12-01 12:02:37 -05:00
parent 085bbd5fe0
commit 48f00c0f1b
2 changed files with 18 additions and 14 deletions

View File

@ -280,7 +280,7 @@ describe('vModel', () => {
it('should work with checkbox and true-value/false-value', async () => { it('should work with checkbox and true-value/false-value', async () => {
const component = defineComponent({ const component = defineComponent({
data() { data() {
return { value: null } return { value: 'yes' }
}, },
render() { render() {
return [ return [
@ -301,23 +301,26 @@ describe('vModel', () => {
const input = root.querySelector('input') const input = root.querySelector('input')
const data = root._vnode.component.data const data = root._vnode.component.data
input.checked = true // DOM checked state should respect initial true-value/false-value
triggerEvent('change', input)
await nextTick()
expect(data.value).toEqual('yes')
data.value = 'no'
await nextTick()
expect(input.checked).toEqual(false)
data.value = 'yes'
await nextTick()
expect(input.checked).toEqual(true) expect(input.checked).toEqual(true)
input.checked = false input.checked = false
triggerEvent('change', input) triggerEvent('change', input)
await nextTick() await nextTick()
expect(data.value).toEqual('no') expect(data.value).toEqual('no')
data.value = 'yes'
await nextTick()
expect(input.checked).toEqual(true)
data.value = 'no'
await nextTick()
expect(input.checked).toEqual(false)
input.checked = true
triggerEvent('change', input)
await nextTick()
expect(data.value).toEqual('yes')
}) })
it('should work with checkbox and true-value/false-value with object values', async () => { it('should work with checkbox and true-value/false-value with object values', async () => {

View File

@ -99,8 +99,7 @@ export const vModelText: ModelDirective<
} }
export const vModelCheckbox: ModelDirective<HTMLInputElement> = { export const vModelCheckbox: ModelDirective<HTMLInputElement> = {
created(el, binding, vnode) { created(el, _, vnode) {
setChecked(el, binding, vnode)
el._assign = getModelAssigner(vnode) el._assign = getModelAssigner(vnode)
addEventListener(el, 'change', () => { addEventListener(el, 'change', () => {
const modelValue = (el as any)._modelValue const modelValue = (el as any)._modelValue
@ -130,6 +129,8 @@ export const vModelCheckbox: ModelDirective<HTMLInputElement> = {
} }
}) })
}, },
// set initial checked on mount to wait for true-value/false-value
mounted: setChecked,
beforeUpdate(el, binding, vnode) { beforeUpdate(el, binding, vnode) {
el._assign = getModelAssigner(vnode) el._assign = getModelAssigner(vnode)
setChecked(el, binding, vnode) setChecked(el, binding, vnode)