Skip to content

Discourage dynamic-component if it's toggling between 2~3 components #2520

Open
@privatenumber

Description

@privatenumber
Contributor

Please describe what the rule should do:
Discourage using a dynamic component when you can use a v-if/v-else for better readability & type hints.

When reading <component :is="componentType"> it doesn't give a lot of information to the reader (or static analyzer) so it feels like the component can be anything and increase mental burden when trying to understand what a component does.

If componentType is actually a toggle between 2, 3 components, I think a v-if/v-else would be preferable as it makes it clear what elements/components are used in the file.

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:

Composition API with inline computed:

<script setup>
const props = defineProps({
	isButton: Boolean,
});
</script>

<template>
	<component :is="isButton ? 'button' : 'a'">
		Text
	</component>
</template>

Options API with computed property:

<template>
	<component :is="componentType">
		Text
	</component>
</template>

<script>
export default {
	props: {
		isButton: Boolean
	},
	computed: {
		componentType() {
			return isButton ? 'button' : 'a'
		}
	}
}
</script>

Additional context

Activity

andreww2012

andreww2012 commented on Aug 4, 2024

@andreww2012

Another example of code that can be prevented by this rule.

Obviously, the imported component shouldn't be anything particular like an icon... On the other hand, it might be a good idea to actually allow (or even enforce) such a technique if an imported component's path matches some regex like \.svg$ (should be configurable) because <my-icon></my-icon> is quite verbose and doesn't accept any props anyway.

<template>
  <component :is="MyIcon"></component>
</template>

<script setup lang="ts">
import MyIcon from './any-icon.svg';

...
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @privatenumber@andreww2012

        Issue actions

          Discourage dynamic-component if it's toggling between 2~3 components · Issue #2520 · vuejs/eslint-plugin-vue