eslint-plugin-vue
eslint-plugin-vue copied to clipboard
rule: no v-if on template root
Please describe what the rule should do:
Warn on using v-if
on the template root node, because:
-
Whether a component should be rendered or not is a usage concern. Specifically, it's confusing when a declared component is not rendered:
/* Usage */ <template> <div> ... <custom-component /> /* Readers expect this to be rendered */ </div> </template> /* CustomComponent.vue */ <template> <div v-if="false"> ... </div> </template>
-
There are performance benefits:
- Instantiating a new stateful component only for it to not be rendered via root
v-if="false"
is wasteful. If possible, it should happen in the parent usage life-cycle. - When moving the
v-if
to the parent, the component can be asynchronously loaded when needed, so not only will it save on component registration, it will save on module declaration and asset size.<template> <div> ... <custom-component v-if="shouldShow" /> /* Won't be loaded till true */ </div> </template> <script> export default { components: { CustomComponent: () => import('./CustomComponent.vue') } } </script>
- Instantiating a new stateful component only for it to not be rendered via root
What category should the rule belong to?
[ ] Enforces code style (layout) [ ] Warns about a potential error (problem) [x] Suggests an alternate way of doing something (suggestion) [ ] Other (please specify:)
Provide 2-3 code examples that this rule should warn about:
Bad
/* Usage */
<template>
<div>
<custom-component />
</div>
</template>
/* CustomComponent.vue */
<template>
<div v-if="shouldShow">
...
</div>
</template>
Good
/* Usage */
<template>
<div>
<custom-component v-if="shouldShow" />
</div>
</template>
/* CustomComponent.vue */
<template>
<div>
...
</div>
</template>
Additional context
- There are likely cases where it's not possible to do this. I think this would be a warning in "recommended", or not even a pre-enabled rule.
Thank you for rule proposal! I think it's good to make it rule available to users.
I think the following template needs to be valid.
<template>
<div v-if="mode === 'a'">
...
</div>
<div v-if="mode === 'b'">
...
</div>
</template>
<template>
<div v-if="loading">
...
</div>
<div v-else>
...
</div>
</template>
Yeah that's a great point. Good catch!
I think that this is already covered by this rule vue/valid-template-root
How so?
I would like to work on this @ota-meshi
Yeah, thank you!