diff --git a/lib/rules/no-use-v-if-with-v-for.js b/lib/rules/no-use-v-if-with-v-for.js index 754086f7e..70d720750 100644 --- a/lib/rules/no-use-v-if-with-v-for.js +++ b/lib/rules/no-use-v-if-with-v-for.js @@ -37,7 +37,7 @@ function getVForUsingIterationVar (vIf) { variable.kind === 'v-for' ) if (targetVFor) { - return targetVFor.id.parent + return targetVFor } } return undefined @@ -76,13 +76,20 @@ module.exports = { if (utils.hasDirective(element, 'for')) { if (isUsingIterationVar(node)) { if (!allowUsingIterationVar) { - const vFor = getVForUsingIterationVar(node) + const vForVar = getVForUsingIterationVar(node) + + let targetVForExpr = vForVar.id.parent + while (targetVForExpr.type !== 'VForExpression') { + targetVForExpr = targetVForExpr.parent + } + const iteratorNode = targetVForExpr.right context.report({ node, loc: node.loc, - message: "The '{{iteratorName}}' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if'.", + message: "The '{{iteratorName}}' {{kind}} inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if'.", data: { - iteratorName: vFor.right.name + iteratorName: iteratorNode.type === 'Identifier' ? iteratorNode.name : context.getSourceCode().getText(iteratorNode), + kind: iteratorNode.type === 'Identifier' ? 'variable' : 'expression' } }) } diff --git a/tests/lib/rules/no-use-v-if-with-v-for.js b/tests/lib/rules/no-use-v-if-with-v-for.js index a47e858a5..c8bcda784 100644 --- a/tests/lib/rules/no-use-v-if-with-v-for.js +++ b/tests/lib/rules/no-use-v-if-with-v-for.js @@ -73,6 +73,55 @@ tester.run('no-use-v-if-with-v-for', rule, { ` + }, + { + filename: 'test.vue', + code: '', + options: [{ allowUsingIterationVar: true }] + }, + { + filename: 'test.vue', + code: '', + options: [{ allowUsingIterationVar: true }] + }, + { + filename: 'test.vue', + code: '', + options: [{ allowUsingIterationVar: true }] + }, + { + filename: 'test.vue', + code: '' + }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` } ], invalid: [ @@ -139,6 +188,70 @@ tester.run('no-use-v-if-with-v-for', rule, { message: "This 'v-if' should be moved to the wrapper element.", line: 6 }] + }, + { + filename: 'test.vue', + code: '', + errors: [{ + message: "The 'list' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if'.", + line: 1 + }] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [{ + message: "The 'users' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if'.", + line: 6 + }] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [{ + message: "This 'v-if' should be moved to the wrapper element.", + line: 6 + }] + }, + { + filename: 'test.vue', + code: '', + errors: [{ + message: "The 'list()' expression inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if'.", + line: 1 + }] + }, + { + filename: 'test.vue', + code: '', + errors: [{ + message: "The '5' expression inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if'.", + line: 1 + }] } ] })