Skip to content

Commit c71f6ae

Browse files
shortdivhefeng
authored and
hefeng
committed
feat: v-bind.sync also listens for kebab-case update event (vuejs#8297)
fix vuejs#6428
1 parent c3dde99 commit c71f6ae

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

src/compiler/parser/index.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { parseHTML } from './html-parser'
55
import { parseText } from './text-parser'
66
import { parseFilters } from './filter-parser'
77
import { genAssignmentCode } from '../directives/model'
8-
import { extend, cached, no, camelize } from 'shared/util'
8+
import { extend, cached, no, camelize, hyphenate } from 'shared/util'
99
import { isIE, isEdge, isServerRendering } from 'core/util/env'
1010

1111
import {
@@ -524,7 +524,7 @@ function processComponent (el) {
524524

525525
function processAttrs (el) {
526526
const list = el.attrsList
527-
let i, l, name, rawName, value, modifiers, isProp
527+
let i, l, name, rawName, value, modifiers, isProp, syncGen
528528
for (i = 0, l = list.length; i < l; i++) {
529529
name = rawName = list[i].name
530530
value = list[i].value
@@ -558,11 +558,19 @@ function processAttrs (el) {
558558
name = camelize(name)
559559
}
560560
if (modifiers.sync) {
561+
syncGen = genAssignmentCode(value, `$event`)
561562
addHandler(
562563
el,
563564
`update:${camelize(name)}`,
564-
genAssignmentCode(value, `$event`)
565+
syncGen
565566
)
567+
if (hyphenate(name) !== camelize(name)) {
568+
addHandler(
569+
el,
570+
`update:${hyphenate(name)}`,
571+
syncGen
572+
)
573+
}
566574
}
567575
}
568576
if (isProp || (

test/unit/features/directives/bind.spec.js

+21
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,27 @@ describe('Directive v-bind', () => {
166166
}).then(done)
167167
})
168168

169+
it('.sync modifier with kebab case event', done => {
170+
const vm = new Vue({
171+
template: `<test :foo-bar.sync="bar"/>`,
172+
data: {
173+
bar: 1
174+
},
175+
components: {
176+
test: {
177+
props: ['fooBar'],
178+
template: `<div @click="$emit('update:foo-bar', 2)">{{ fooBar }}</div>`
179+
}
180+
}
181+
}).$mount()
182+
183+
expect(vm.$el.textContent).toBe('1')
184+
triggerEvent(vm.$el, 'click')
185+
waitForUpdate(() => {
186+
expect(vm.$el.textContent).toBe('2')
187+
}).then(done)
188+
})
189+
169190
it('bind object', done => {
170191
const vm = new Vue({
171192
template: '<input v-bind="test">',

0 commit comments

Comments
 (0)