vue.js

Vue 3 use imported component template


There is a component A in vue 3. I would like to write a component that inherits from A by using only A's template and changing only the script and style.

Is there a way to configure the component in a setup script tag to use the template of component A without creating unnecessary component?

In Vue 2 I could use mixins for this:

<script>
import A from './A';

export default {
    mixins: [
        A,
    ],
}
</script>

In Vue 3 I can do it this way:

<template>
    <A></A>
</template>

<script setup>
import A from './A';
</script>

But the documentation says that this is not recommended because unnecessarily create a new component and too many components can slow down the page:

When used across an entire application, the amount of extra component instances created by the renderless component pattern can become a noticeable performance overhead.

From this part I thought in vue it would be worth reducing the number of components where possible


Solution

  • The use of wrapper components (snippet 2) is a common and legitimate practice.

    The recommendation in the question specifically applies to the choice between a composable and renderless component. It makes sense to use a composable instead of a component when the choice is a matter of taste and it benefits the performance.

    When this is not the case, a well-known statement comes to rescue, "premature optimization is the root of all evil." It is necessary to benchmark and confirm that the amount of components is a bottleneck and reducing it as an optimization strategy at the expense of application design is justified.

    It's still possible to use component mixins in Vue 3, though composition API limits their use.

    It's also possible to inherit a template of another component manually (render may not exist in components that weren't precompiled), though there are more reasons to use this approach with third-party components that cannot be refactored:

    <script setup>
    import A from './A';
    
    defineOptions({
      render: A.render
    });
    </script>