eslint-plugin-vue
eslint-plugin-vue copied to clipboard
Rule suggestion: `vue/no-use-v-else-with-v-for`
What rule do you want to change?
~vue/no-use-v-if-with-v-for~ New rule vue/no-use-v-else-with-v-for
Does this change cause the rule to produce more or fewer warnings? More
How will the change be implemented? (New option, new default behavior, etc.)? Not sure, but probably default behavior.
Please provide some example code that this change will affect:
<!-- GOOD -->
<div v-if="foo" v-for="x in xs">{{ x }}</div>
<!-- BAD -->
<div v-if="foo">foo</div>
<div v-else v-for="x in xs">{{ x }}</div>
<!-- GOOD -->
<div v-if="foo">foo</div>
<template v-else>
<div v-for="x in xs">{{ x }}</div>
</template>
<!-- BAD -->
<div v-if="foo">foo</div>
<div v-else-if="bar" v-for="x in xs">{{ x }}</div>
<!-- GOOD -->
<div v-if="foo">foo</div>
<template v-else-if="bar">
<div v-for="x in xs">{{ x }}</div>
</template>
What does the rule currently do for this code?
Only report the first case (v-if+v-for).
What will the rule do after it's changed?
Also warn about the other cases (v-else+v-for and v-else-if+v-for), and maybe even autofix to add a wrapper <template> tag.
Thank you for your suggestion. I think it would be great if could check them out with a plugin :+1:. The sample code you provided is very hard to read.
But I don't think it needs to be included in vue/no-use-v-if-with-v-for. Avoiding the combination of v-if and v-for is intended to avoid unintended behavior, but avoiding the combination of v-else and v-for improves readability. I think the purpose is a little different. What do you think?
I think it would be great if could check them out with a plugin 👍. The sample code you provided is very hard to read.
Sorry, I don't understand. What do you mean?
I think the purpose is a little different.
That't true, v-else-if or v-else work together with v-for. But Volar (the new VS Code extension for Vue) complains about it anyway, and it improves readability. Do you think a new rule or a new option in vue/no-use-v-if-with-v-for makes more sense? Any naming suggestions?
Sorry, I don't understand. What do you mean?
Sorry, I didn't communicate it well. It meant that the code was hard to read and should be checked. Your sample code made me clearly understand the intent.
Volar complains about it anyway
I've referenced the following code using Volar, but it doesn't seem to give any warnings.
<script setup>
const foo = false, bar = true
const xs = [1,2,3]
</script>
<template>
<div v-if="foo">foo</div>
<div v-else v-for="x in xs">{{ x }}</div>
<div v-if="foo">foo</div>
<div v-else-if="bar" v-for="x in xs">{{ x }}</div>
</template>
Can you share the code you tried?
In my opinion for now, it's better to add a new rule. For example, vue/no-use-v-else-with-v-for
For this code:
<template>
<table>
<template v-for="position in positions">
<template v-for="subPosition in position.subPositions">
<tr v-if="subPosition.products.length === 0" :key="subPosition.positionNumber" />
<tr v-else v-for="product in subPosition.products" :key="`${subPosition.positionNumber}-${product.name}`" />
</template>
</template>
</table>
</template>
- Volar complains about the second
<tr>:v-else/v-else-if has no adjacent v-if or v-else-if. - eslint-plugin-vue (vue/attributes-order) complains about the second
<tr>:Attribute "v-for" should go before "v-else".
Thank you for sharing the source code. But I still can't reproduce it in Volar 😓. Do I need to make any settings...?
I reproduced it in the Vue2 environment. However, it cannot be reproduced in the Vue3 environment.
Oh sorry, the code above is indeed from a Vue 2 environment.
Hmm... I think it may be a Volar bug that Volar warns in a Vue2 environment 🤔. Vue compilation works fine.
~~It may be related to a newly posted issue. https://github.com/johnsoncodehk/volar/issues/1638~~
I seem to have misunderstood it. Not related.
Hmm... I think it may be a Volar bug that Volar warns in a Vue2 environment 🤔.
I think it's a Volar bug. Volar transforms v-else after transforming v-for.
https://github.com/johnsoncodehk/volar/blob/9d70df78b2e08ec472f97b315d09565d95e89357/packages/vue-code-gen/src/vue2TemplateCompiler.ts#L54-L58
https://github.com/vuejs/core/blob/a95554d35c65e5bfd0bf9d1c5b908ae789345a6d/packages/compiler-core/src/compile.ts#L33
https://github.com/vuejs/core/blob/a95554d35c65e5bfd0bf9d1c5b908ae789345a6d/packages/compiler-core/src/transforms/vIf.ts#L43
@kleinfreund Could you elaborate why you are against this rule? (I'm interpreting your :-1: reaction on the issue that way.)
@FloEdelmann Because to me, the following is not ambiguous:
<div v-if="foo">foo</div>
<div v-else v-for="x in xs">{{ x }}</div>
I suppose the intent here is to avoid ambiguity like this:
<div v-if="foo">foo</div>
<div v-else-if="x === thing" v-for="x in xs">{{ x }}</div>
Now that’s perhaps something that’s worth it to make less ambiguous via stricter linter rules in which I don’t feel strongly about the introduction of the proposed rule.