Просмотр исходного кода

add warning for using v-model on v-for alias

Evan You 9 лет назад
Родитель
Сommit
e9bf5d1cd9
2 измененных файлов с 35 добавлено и 0 удалено
  1. 19 0
      src/compiler/parser/index.js
  2. 16 0
      test/unit/features/directives/model-text.spec.js

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

@@ -388,6 +388,9 @@ function processAttrs (el) {
           name = name.slice(0, -(arg.length + 1))
         }
         addDirective(el, name, value, arg, modifiers)
+        if (process.env.NODE_ENV !== 'production' && name === 'model') {
+          checkForAliasModel(el, value)
+        }
       }
     } else {
       // literal attribute
@@ -469,3 +472,19 @@ function guardIESVGBug (attrs) {
   }
   return res
 }
+
+function checkForAliasModel (el, value) {
+  let _el = el
+  while (_el) {
+    if (_el.for && _el.alias === value) {
+      warn(
+        `<${el.tag} v-model="${value}">: ` +
+        `You are binding v-model directly to a v-for iteration alias. ` +
+        `This will not be able to modify the v-for source array because ` +
+        `writing to the alias is like modifying a function local variable. ` +
+        `Consider using an array of objects and use v-model on an object property instead.`
+      )
+    }
+    _el = _el.parent
+  }
+}

+ 16 - 0
test/unit/features/directives/model-text.spec.js

@@ -160,4 +160,20 @@ describe('Directive v-model text', () => {
     triggerEvent(vm.$el, 'input')
     expect(spy).toHaveBeenCalledWith('b')
   })
+
+  it('warn binding to v-for alias', () => {
+    new Vue({
+      data: {
+        strings: ['hi']
+      },
+      template: `
+        <div>
+          <div v-for="str in strings">
+            <input v-model="str">
+          </div>
+        </div>
+      `
+    }).$mount()
+    expect('You are binding v-model directly to a v-for iteration alias').toHaveBeenWarned()
+  })
 })