-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
Functional single file component with components option. #7492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Ran into exact same issue here, nice workaround!!! |
Just learning Vue and struggling with this for the past few hours! Thanks for bringing it up! |
Here is another workaround, it avoids global component, but looks not pretty <template functional>
<div>
<component :is="props.components.SomeChildren"></component>
</div>
</template>
<script>
import SomeChildren from "./SomeChildren.vue";
export default {
props: {
components: {
type: Object,
default() {
return {
SomeChildren
};
}
}
}
};
</script> |
I think it's worth mentioning here that the error message is quite unintuitive. The Also, as awkward as it is, registering the unknown component in the first parent instance component clears the error without polluting the global component name scope. It's a strange coupling of components though. Choose your hack for now I suppose. |
@ywwhack Your workaround is great! I made some improvements. We can use injections instead of props, so that props will not be polluted, and the code looks a little prettier. <template functional>
<div>
<component :is="injections.components.SomeChildren"></component>
</div>
</template>
<script>
import SomeChildren from "./SomeChildren.vue";
export default {
inject: {
components: {
default: {
SomeChildren
}
}
}
};
</script> |
any update on implementing components option in functional components ? The workarounds are good but that seems pretty hacky IMO especially when mentioning that |
Adds support for the components hash to be used in functional components fix vuejs#7492
parent: // template functional
v-list
component(
:is='injections.components.myListItem'
v-for='item in props.data',
:key='item.title',
:data='item')
// script
import myListItem from './listItem'
export default {
name: 'myList',
inject: {
components: {
default: {myListItem}
}
}
} children: // template functional
v-list-group(v-if='Array.isArray(props.data.children)')
v-list-tile(slot='activator')
v-list-tile-content
v-list-tile-title {{props.data.title}}
my-list-item(
v-for='item in props.data.children',
:key='item.title',
:data='item')
v-list-tile(v-else)
v-list-tile-content
v-list-tile-title {{props.data.title}}
// script
export default {
name: 'myListItem'
} app: // template
#app
my-list(:data='list')
// script
import myList from './list'
export default {
name: 'App',
components: {myList},
data() {
return {
list: [
{title: 1},
{title: 2},
{title: 3},
{
title: 4,
children: [
{title: 41},
{title: 42},
{title: 43}
]
},
{title: 5}
]
}
}
} children error: Unknown custom element |
Any ideas how to implement dynamic async components inside functional components? E.g. functional should be simple wrapper like <component :is="componentName" /> where For non-functional component it looks like this: <template>
<component :is="componentName" v-bind="$attrs"/>
</template>
<script>
const someCondition = Math.random() > 0.5
export default {
name: 'PolicyRequestInfo',
components: {
FirstDynamic: () => import('./FirstDynamic'),
SecondDynamic: () => import('./SecondDynamic')
},
computed: {
componentName() {
return SomeCondition ? 'FirstDynamic' : 'SecondDynamic'
}
}
}
</script> For functional component I have no idea how to make it work. |
Lines 123 to 133 in 7075408
The type declaration shows that, functional component of current version can't accept Of course a possible solution is to use the render function: <script>
import SomeChildren from './SomeChildren.vue'
export default {
render (h) {
return h('div', [
h(SomeChildren),
])
}
}
</script> |
Yep, it actually works with render functions. I use something like that now: <script>
const component = Math.random() > 0.5
? () => import('./compA')
: () => import('./compB')
export default {
functional: true,
render(h, context) {
return h(component, context.data, context.children)
}
}
</script> |
Would really love to see |
This feature would certainly extend the usefulness of functional components in a natural way. I for one had not realised that At the moment, if a component is a SFC and has child component dependencies and we want to mark it functional, the options would seem to be:
However, in a library of many interlinked components all done as SFCs it is desirable to retain the template for consistency with the other components, and undesirable to globally register names. The workaround for all its ingenuity looks rather messy/fiddly and would require explanation for maintenance. It would be much neater just to be able to declare child components with Fix #8143 looks good and ready to go. If there isn't a reason not to, can it be delivered? We've held off from making any of our components functional atm, and would use it right away :-) |
That was my experience too. I remember being quite surprised when I discovered components weren't supported in functional components. This really, really diminished the usefulness of functional components and I rarely use them because of this. I do use JSX in my Vue projects because sometimes I need to drop down into the render function, so this isn't technically a huge issue for me, but I like to avoid JSX whenever possible. I'm hoping Vue 3 will improve on this in some way. React already does functional components well.
I'm not a fan of this hack TBH. I will just stay clear of functional components until this issue is officially resolved. |
Correction: After restarting the build it does not work in fact. |
+1. Will not be using the work around as it decreases code readability (since it cannot be found in Vue documentation). Please implement this much needed fix. Thank you |
I suspect this, like some other features for functional components, will not be implemented since Vue 3 (the alpha/proposal) alleviates the whole issue by making the difference between functional and non-functional components small. See this and the following comments: #8143 (comment) |
hey @maksnester I'm working on this for a Vue 2.6.x project. I'm trying to allow the functional component to accept a Asked on Stackoverflow too (here) if you want more details about my problem. Thanks! |
As an alternative option, vue-import-loader offers support for component resolution in functional components |
Still no improvements on this till now? <script>
import ChildComp from '@/components/ChildComp.vue';
export default {
components: {
ChildComp,
},
};
</script>
<template>
<component :is="$options.components.ChildComp" any-prop="value" />
</template> |
@darkylmnx it's a #wontfix since Vue 3 will make functional components irrelevant, as I understood. |
Oh... I see.
Le jeu. 18 juin 2020 à 22:30, andreas <notifications@github.com> a écrit :
… @darkylmnx <https://github.com/darkylmnx> it's a #wontfix since Vue 3
will make functional components irrelevant, as I understood.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#7492 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAK4HNNSMXAU3KXBWHRMYKTRXJ2NNANCNFSM4EMWWNEA>
.
|
There's RFC: https://github.com/vuejs/rfcs/blob/master/active-rfcs/0007-functional-async-api-change.md We will just rewrite our functional components as plain functions, that's all, much better, imo. |
Version
2.5.13
Reproduction link
NG pattern (functional)
https://codesandbox.io/s/004vv2onw0
OK pattern (no functional)
https://codesandbox.io/s/q9k5q8qq56
Steps to reproduce
I found can't use
components
option whenfunctional
single file component.It's occure
Unknown custom element
.What is expected?
Not occure
Unknown custom element
and use child componentWhat is actually happening?
It's occure
Unknown custom element
In workaround, it not occure when use
Vue.component
.The text was updated successfully, but these errors were encountered: