Support Inheritance (extends) in the Composition API
What problem does this feature solve?
Intro
There is no native process in the Composition API that supports inheritance (extends). This creates a huge blocker for adoption. The Composition API may prefer a composition ideology, but it should allow for inheritance as complementary design element as is simplifies architecture, design, and coding. Composition and Inheritance are complimentary design patterns.
Inheritance and Composition
Inheritance and composition are simply design patterns a user can and should use at will. There is no valid reason that composition abrogates inheritance even in a so-called "composition" API. These two design patterns are not add odds with each other and doesn't necessitate using one over the other. The Options API does not "demand" using inheritance over composition.
While the Composition API "suggests" the composition design, it shouldn't "demand" exclusive use. In fact, there is a huge body of work that use both together. Then, use the Options API? The Composition API provides a valuable, condensed, and simplified coding structure. Why double coding methodologies and mindsets? Mixing the two APIs is problematic and a developer needs to juggle two different mindsets leading to error. Extending one "composable" object from another should be easy.
The primary differences between the Options and Composition API seems to be:
- The Options API tends to use a Public first interface...the component is "open" by default.
- The Composition API tends to use a Private first interface...the component is "closed" by default.
Project Issues
Forcing Composition API adopters to re-engineer projects to conform to a strict composition ideology is an unnecessary blocker. In fact, the "composition only" ideology is forcing a more verbose method and process when it should be complementary to inheritance. This also leads to the crazy notion of putting most functions in a singular "utility" JS/TS file and "composing" components by importing the needed functions to use in the control functions for the component...little organization, little structure, everything is global, back to the good ol' spaghetti code days. Then, use JS/TS directly and dump the API usage.
What does the proposed API look like?
Class Exposure
In the Composition API, a component is "closed by default"--elements are private by default. Then, expected behavior is that only exposed (i.e., public) elements should be available to the derived component.
Using setup()
<script>
import SomeOtherComponent from some_other_component.vue
export default {
setup(props, { extends }) {
...
extends({
SomeOtherComponent
})
...
}
}
</script>
OR
<script>
import SomeOtherComponent from some_other_component.vue
export default {
setup(props, { options }) {
...
options({
extends: SomeOtherComponent,
...
})
...
}
}
</script>
Using <script setup>
<script setup>
import SomeOtherComponent from some_other_component.vue
defineExtends({ SomeOtherComponent })
</script>
OR
<script setup>
import SomeOtherComponent from some_other_component.vue
defineOptions({
extends: SomeOtherComponent,
...
})
</script>
- for setup, It should be:
export default {
extends: Comp,
setup(){}
}
defineOptions
already supported extends see
With all due respect, here's exactly what I suggest: if you are using Composition API, then follow the recommended best practice. My opinion is that the concept of "inheritance" is inherently incompatible with the Composition mindset. If you want to reuse logic in Composition API, reuse them as composables. One pattern to rule them of all. I don't see the point of complicating the model with inheritance.
If you believe your suggested API solves a real issue rather than stylistic preferences, please open an RFC discussion here with detailed design, so that it can gather feedback / interest.