Browse Source

expand .sync into extra listener

Evan You 9 years ago
parent
commit
931aaea8dc
2 changed files with 29 additions and 0 deletions
  1. 8 0
      src/compiler/parser/index.js
  2. 21 0
      test/unit/features/directives/bind.spec.js

+ 8 - 0
src/compiler/parser/index.js

@@ -6,6 +6,7 @@ import { parseText } from './text-parser'
 import { parseFilters } from './filter-parser'
 import { cached, no, camelize } from 'shared/util'
 import { isIE, isServerRendering } from 'core/util/env'
+import { genAssignmentCode } from '../directives/model'
 
 import {
   addProp,
@@ -462,6 +463,13 @@ function processAttrs (el) {
           if (modifiers.camel) {
             name = camelize(name)
           }
+          if (modifiers.sync) {
+            addHandler(
+              el,
+              `update:${camelize(name)}`,
+              genAssignmentCode(value, `$event`)
+            )
+          }
         }
         if (isProp || platformMustUseProp(el.tag, el.attrsMap.type, name)) {
           addProp(el, name, value)

+ 21 - 0
test/unit/features/directives/bind.spec.js

@@ -143,6 +143,27 @@ describe('Directive v-bind', () => {
     expect(vm.$el.getAttribute('viewBox')).toBe('0 0 1 1')
   })
 
+  it('.sync modifier', done => {
+    const vm = new Vue({
+      template: `<test :foo-bar.sync="bar"/>`,
+      data: {
+        bar: 1
+      },
+      components: {
+        test: {
+          props: ['fooBar'],
+          template: `<div @click="$emit('update:fooBar', 2)">{{ fooBar }}</div>`
+        }
+      }
+    }).$mount()
+
+    expect(vm.$el.textContent).toBe('1')
+    triggerEvent(vm.$el, 'click')
+    waitForUpdate(() => {
+      expect(vm.$el.textContent).toBe('2')
+    }).then(done)
+  })
+
   it('bind object', done => {
     const vm = new Vue({
       template: '<input v-bind="test">',