Skip to content
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

[2.0] Templates for functional components #3977

Closed
Akryum opened this issue Oct 18, 2016 · 34 comments
Closed

[2.0] Templates for functional components #3977

Akryum opened this issue Oct 18, 2016 · 34 comments

Comments

@Akryum
Copy link
Member

Akryum commented Oct 18, 2016

I'd like to be able to write templates and .vue files for functional components the same way as standard components.

I made a proof-of-concept in this fiddle, but it's quite hacky. Maybe the template compiler could have a functional option to make the resulting functions more adapted to the context object and not this.

It would look like this:

Vue.component('test', {
  functional: true',
  props: ['msg'],
  template: `<div>
    <h1>{{props.msg}}</h1>
    <h2>Static content</h2>
    <span v-for="n in 10">{{n}} </span>
    <button @click="console.log('click', props.msg)"><slot></slot></button>
  </div>`,
});

Or:

<template>
  <div class="test">
    <h1>{{props.msg}}</h1>
    <h2>Static content</h2>
    <span v-for="n in 10">{{n}} </span>
    <button @click="console.log('click', props.msg)"><slot></slot></button>
  </div>
</template>

<script>
export default {
  functional: true,
  props: ['msg'],
}
</script>

<style scoped>
.test {
  margin: 12;
}
</style>
@LinusBorg
Copy link
Member

LinusBorg commented Oct 18, 2016

We already have this as an option on our roadmap. However, we will pospone this until 2.0 is out of the current post-release phase and all work we have left in the ecosystem for 2.0 is done, because this will involve a considerable amount of work to get right, tested and so on (also, making vue-loader/vueify work with it etc. pp.)

Thanks for the PoC, seems helpful!

@s130059660
Copy link

Yes please.
I was looking at exactly that. For me, render functions are too overwhelming and "feels" disjointed from the overall feel of single file component.

@yyx990803 yyx990803 added 2.x and removed 2.0 labels Nov 24, 2016
@blocka
Copy link

blocka commented Nov 28, 2016

What would be most useful to me would be to scope css on to functional components.

@reachtrevor
Copy link

Can we get a status update on this functional single file component? I am coming from React and missing this quite a bit.

@Akryum
Copy link
Member Author

Akryum commented Feb 5, 2017

It is coming soon.

@rnenjoy
Copy link

rnenjoy commented Feb 7, 2017

Can anyone explain for a n00b what its new with this against what we have now?

@Akryum
Copy link
Member Author

Akryum commented Feb 7, 2017

You will be able to create functional components with .vue files like this:

<template functional>
  <div class="test">
    <h1>{{props.msg}}</h1>
    <h2>Static content</h2>
    <span v-for="n in 10">{{n}} </span>
    <button @click="console.log('click', props.msg)"><slot></slot></button>
  </div>
</template>

<script>
export default {
  props: ['msg'],
}
</script>

<style scoped>
.test {
  margin: 12;
}
</style>

@rnenjoy
Copy link

rnenjoy commented Feb 7, 2017

Ahh ok thanks!!

@haizop
Copy link

haizop commented Mar 15, 2017

That looks great. Any idea of the timeframe for when this feature will be released?

@scottbedard
Copy link

This is going to make functional components so much easier to use!

@carrotscarrots
Copy link

any updates on this topic ? will it be part of the 2.3 release ?

mosinve referenced this issue in bootstrap-vue/bootstrap-vue May 4, 2017
For an unknown reason SSR fails during rehydration of <b-input-groups> with addons enabled.
Inlining seems fixing problem.
@scottbedard
Copy link

@Akryum Do you know the status of this issue? It seems like it's been in limbo for months. Is there anything we can do to help move this along?

@Akryum
Copy link
Member Author

Akryum commented Jun 7, 2017

/ping @blake-newman

@c01nd01r
Copy link

Are there any news about this feature?

@blocka
Copy link

blocka commented Jul 17, 2017

Seems work was started on this in february: https://github.com/vuejs/vue/tree/feature/fn-templates

@GoodeUser
Copy link

Is there any update on this? It has been open a while now - is there anything that can be done to help move this issue?

@vuejs vuejs deleted a comment from up9cloud Aug 4, 2017
@scottbedard
Copy link

scottbedard commented Aug 4, 2017

@Akryum since your teaser back in February, this has seemed dead in the water. @blake-newman I see you were pinged a few months ago, do you have any information on this issue?

I'm sorry if this is getting annoying, I'd just really like to know how we can make this happen :)

@blake-newman
Copy link
Member

@scottbedard I was working on it, there was a few hidden gotchas. However, these could just be documented as unusable features. The work was done quite a while ago and unfortuently doesn't map to the current state of the rendering system so work will need to be done.

@vuejs/collaborators What is you opinion on this feature overall, is the development effort and additional cost to the core worth this feature?

@Akryum
Copy link
Member Author

Akryum commented Aug 15, 2017

I think if it's a nice to have feature, since the default way to write components is using the templates. And IMHO decoupling all the rendering functions from the components (used in the templates compiler) would be great.

@blake-newman
Copy link
Member

blake-newman commented Aug 15, 2017

The problem is that the scope of using templates functionally is limiting, much more than using JSX/Render functions. A

I think at the point of building functional components, the constraints and design patterns don't fit a template model. This feature requires a small amount of extra runtime (f632033#diff-4d479bb000ed54582de8e4cd8318ef64R157) and will never have the same performance as pure render functions.

Enabling this feature will assume better performance, comparative to pure render functions this is not true. My stance on the feature at the moment, is that it will only empower templates to be used functionality but gives no true reward.

@Akryum
Copy link
Member Author

Akryum commented Aug 16, 2017

Also, it would be nice to have scoped style support for functional components but it may be unrelated.

@blake-newman
Copy link
Member

That is unrelated, i believe that is working. I did work on that before. Unless there is a regression?

@Telanx
Copy link

Telanx commented Sep 1, 2017

Vue的函数式组件相对于React来说略显丑陋,template远不如jsx更加函数式,或许可以借用vue-loader来进行转化处理,希望可以像这样:

<script functional>
const DumbCmp = props => (
  <Button>{props.label}</Button>
);

export default DumbCmp;
</script>

actually, some guys have done this serval months ago https://github.com/nickmessing/babel-plugin-jsx-vue-functional

@eshell
Copy link

eshell commented Oct 11, 2017

Is this what we've been waiting for? ea0d227

@yyx990803
Copy link
Member

Yes, Vue 2.5 + vue-loader 13.3 will have proper support for template compilation, scoped CSS and hot-reload for functional components :)

@robokozo
Copy link

robokozo commented Jan 3, 2018

Is it possible to $emit from functional components?

@alexsasharegan
Copy link

Unless I'm mistaken, the short answer is no. A functional component is not an instance, and therefore has no methods.

Through some hackery, I believe you actually can emit. The context object the render fn receives contains a parent which should always be a vue instance. You could choose to context.parent.$emit() or context.parent.$root.$emit() to take a more global approach. As you can see, this is not event emitting from the functional component, so depending on your use case, this is likely not the best solution.

@dobromir-hristov
Copy link

Hey, I was researching into optimizing some of our Dashboard elements and making an SFC component functional sounds awesome, but I wont be able to have any methods or computed props there, right?
If I use a render function or JSX, I can at least define those inside the render function it self, correct?

@Akryum
Copy link
Member Author

Akryum commented Jan 5, 2018

Is it possible to $emit from functional components?

You can access the listeners object on the functional context. For example:

<my-functional-component @request-something="onRequestSomething" />

Call the listener like a method inside my-functional-component:

listeners['request-something'](42)

If I use a render function or JSX, I can at least define those inside the render function it self, correct?

Yes.

@dobromir-hristov
Copy link

@Akryum thanks. Larger, more template heavy func components might be better off with JSX because standard render functions would make things a bit harder to read. A more advanced tutorial on these would be really sweet :)

@blocka
Copy link

blocka commented Jan 5, 2018 via email

@dobromir-hristov
Copy link

@blocka how will you use a function to do something? instantiate a chart for example?

@blocka
Copy link

blocka commented Jan 5, 2018 via email

@robokozo
Copy link

robokozo commented Jan 5, 2018

@Akryum Your solution works but it leaves me feeling that functional sfc templates could use a little more love. I'm in the process of re-writing several components that could have been functional from the get-go and I'm a little disappointed with the experience. The sfc already has a context that is accessible from the template for props and listeners. Couldn't these properties just be mapped to the 'root' for props and '$emit' for listeners allowing each type of sfc to work with the same api.

<template functional>
    <div @click="listeners['request-something'](42)">
        {{props.hello}}
        {{props.world}}
    </div>
</template>

<script>
export default {
    props: ["hello", "world"]
}
</script>

could become

<template functional>
    <div @click="$emit('request-something', 42)">
        {{hello}}
        {{world}}
    </div>
</template>

<script>
export default {
    props: ["hello", "world"]
}
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests