瀏覽代碼

fix(v-model): v-if / v-else not working with :type + v-model (#6955)

fix #6918
Soo Jae Hwang 8 年之前
父節點
當前提交
0c703e34d1
共有 2 個文件被更改,包括 51 次插入0 次删除
  1. 9 0
      src/platforms/web/compiler/modules/model.js
  2. 42 0
      test/unit/features/directives/model-dynamic.spec.js

+ 9 - 0
src/platforms/web/compiler/modules/model.js

@@ -29,6 +29,8 @@ function preTransformNode (el: ASTElement, options: CompilerOptions) {
       const typeBinding: any = getBindingAttr(el, 'type')
       const ifCondition = getAndRemoveAttr(el, 'v-if', true)
       const ifConditionExtra = ifCondition ? `&&(${ifCondition})` : ``
+      const hasElse = getAndRemoveAttr(el, 'v-else', true) != null
+      const elseIfCondition = getAndRemoveAttr(el, 'v-else-if', true)
       // 1. checkbox
       const branch0 = cloneASTElement(el)
       // process for on the main node
@@ -59,6 +61,13 @@ function preTransformNode (el: ASTElement, options: CompilerOptions) {
         exp: ifCondition,
         block: branch2
       })
+
+      if (hasElse) {
+        branch0.else = true
+      } else if (elseIfCondition) {
+        branch0.elseif = elseIfCondition
+      }
+
       return branch0
     }
   }

+ 42 - 0
test/unit/features/directives/model-dynamic.spec.js

@@ -40,6 +40,48 @@ describe('Directive v-model dynamic input type', () => {
     assertInputWorks(vm, chain).then(done)
   })
 
+  it('with v-else', done => {
+    const data = {
+      ok: true,
+      type: null,
+      test: 'b'
+    }
+    const vm = new Vue({
+      data,
+      template: `<div v-if="ok">haha</div><input v-else :type="type" v-model="test">`
+    }).$mount()
+    document.body.appendChild(vm.$el)
+    expect(vm.$el.textContent).toBe('haha')
+
+    vm.ok = false
+    assertInputWorks(vm).then(done)
+  })
+
+  it('with v-else-if', done => {
+    const vm = new Vue({
+      data: {
+        foo: true,
+        bar: false,
+        type: null,
+        test: 'b'
+      },
+      template: `<div v-if="foo">text</div><input v-else-if="bar" :type="type" v-model="test">`
+    }).$mount()
+    document.body.appendChild(vm.$el)
+
+    const chain = waitForUpdate(() => {
+      expect(vm.$el.textContent).toBe('text')
+    }).then(() => {
+      vm.foo = false
+    }).then(() => {
+      expect(vm._vnode.isComment).toBe(true)
+    }).then(() => {
+      vm.bar = true
+    })
+
+    assertInputWorks(vm, chain).then(done)
+  })
+
   it('with v-for', done => {
     const vm = new Vue({
       data: {