Forráskód Böngészése

also bind static special attrs as props (fix #4530)

Evan You 9 éve
szülő
commit
b3ebfef91d

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

@@ -459,6 +459,15 @@ function processAttrs (el) {
         }
       }
       addAttr(el, name, JSON.stringify(value))
+      // #4530 also bind special attributes as props even if they are static
+      // so that patches between dynamic/static are consistent
+      if (platformMustUseProp(el.tag, name)) {
+        if (name === 'value') {
+          addProp(el, name, JSON.stringify(value))
+        } else {
+          addProp(el, name, 'true')
+        }
+      }
     }
   }
 }

+ 8 - 1
test/unit/modules/compiler/parser.spec.js

@@ -391,7 +391,7 @@ describe('parser', () => {
 
   it('literal attribute', () => {
     // basic
-    const ast1 = parse('<input type="text" name="field1" value="hello world">', baseOptions)
+    const ast1 = parse('<input type="text" name="field1" value="hello world" checked>', baseOptions)
     expect(ast1.attrsList[0].name).toBe('type')
     expect(ast1.attrsList[0].value).toBe('text')
     expect(ast1.attrsList[1].name).toBe('name')
@@ -407,6 +407,13 @@ describe('parser', () => {
     expect(ast1.attrs[1].value).toBe('"field1"')
     expect(ast1.attrs[2].name).toBe('value')
     expect(ast1.attrs[2].value).toBe('"hello world"')
+    expect(ast1.attrs[3].name).toBe('checked')
+    expect(ast1.attrs[3].value).toBe('""')
+    // also bind speicals as props
+    expect(ast1.props[0].name).toBe('value')
+    expect(ast1.props[0].value).toBe('"hello world"')
+    expect(ast1.props[1].name).toBe('checked')
+    expect(ast1.props[1].value).toBe('true')
     // interpolation warning
     parse('<input type="text" name="field1" value="{{msg}}">', baseOptions)
     expect('Interpolation inside attributes has been removed').toHaveBeenWarned()

+ 26 - 0
test/unit/modules/vdom/patch/edge-cases.spec.js

@@ -114,4 +114,30 @@ describe('vdom patch: edge cases', () => {
     })
     .then(done)
   })
+
+  // #4530
+  it('should not reset value when patching bewteen dyanmic/static bindings', done => {
+    const vm = new Vue({
+      data: { ok: true },
+      template: `
+        <div>
+          <input v-if="ok" value="a">
+          <input v-else :value="'b'">
+          <input v-if="ok" type="checkbox" checked>
+          <input v-else type="checkbox" :checked="false">
+        </div>
+      `
+    }).$mount()
+    expect(vm.$el.children[0].value).toBe('a')
+    expect(vm.$el.children[1].checked).toBe(true)
+    vm.ok = false
+    waitForUpdate(() => {
+      expect(vm.$el.children[0].value).toBe('b')
+      expect(vm.$el.children[1].checked).toBe(false)
+      vm.ok = true
+    }).then(() => {
+      expect(vm.$el.children[0].value).toBe('a')
+      expect(vm.$el.children[1].checked).toBe(true)
+    }).then(done)
+  })
 })