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

Explanation for `render: h => h(App)` please #29

Closed
kaihendry opened this issue Oct 13, 2016 · 23 comments

Comments

Projects
None yet
@kaihendry
Copy link

commented Oct 13, 2016

https://github.com/vuejs-templates/webpack-simple/blob/master/template/src/main.js

What does render: h => h(App) mean?

@LinusBorg

This comment has been minimized.

Copy link
Contributor

commented Oct 13, 2016

@LinusBorg LinusBorg closed this Oct 13, 2016

@kaihendry

This comment has been minimized.

Copy link
Author

commented Oct 14, 2016

It's the h I was puzzled about.

@chrisvfritz

This comment has been minimized.

Copy link
Contributor

commented Oct 14, 2016

From the page @LinusBorg linked to:

Aliasing createElement to h is a common convention you’ll see in the Vue ecosystem and is actually required for JSX. If h is not available in the scope, your app will throw an error.

@bubnenkoff

This comment has been minimized.

Copy link

commented Mar 1, 2017

What is alternative to this function? In which cases I should use it?

For example next code:

import Vue from 'vue'
import App from './App.vue'

new Vue({
    el: '#app',
    components: { App }
})

Should I add here render: h => h(App) or not?

@LinusBorg

This comment has been minimized.

Copy link
Contributor

commented Mar 1, 2017

This issue is closed, and ideally, issues are not for support questions, but only for bugs and feature discussions.

Please ask your question on the forum , Stack Overflow or on gitter and are happy to help you out there.

@bjunc

This comment has been minimized.

Copy link

commented Jul 4, 2017

You know, a major gripe I have with Vue is the documentation gap at the intermediate level. The docs provide excellent beginner examples, and then you use the CLI templates and find more evolved syntax, naming/structure conventions despite Vue being "unopinionated" (to a fault, IMO), and complex Webpack configurations with limited comments/explanations. Linus dismissively links to the docs, but they don't really address the spirit of the OP's question.

The answer (for anyone else who comes across this), is that render: h => h(App) is shorthand for:

render: function (createElement) {
    return createElement(App);
}

Which can be shortened to:

render (createElement) {
    return createElement(App);
}

Which can again be shortened to (with h being an alias to createElement as noted above):

render (h){
    return h(App);
}

Which is then shortened further to (using ES6 "fat arrow" syntax):

render: h => h(App);

As noted by Evan in this issue reply, the meaning of h comes from hyperscript:

It comes from the term "hyperscript", which is commonly used in many virtual-dom implementations. "Hyperscript" itself stands for "script that generates HTML structures" because HTML is the acronym for "hyper-text markup language".

Lastly, I really appreciate the Elixir community's philosophy that poor documentation and unintuitive error messages are considered bugs.

@dc3671

This comment has been minimized.

Copy link

commented Oct 4, 2017

@bjunc I think a more "accurate" paraphrase is:

render: function(createElement) {
    return createElement(App);
}
@bjunc

This comment has been minimized.

Copy link

commented Oct 4, 2017

@dc3671 Technically, yeah that would be the most un-shortened version of the render function. I'll update my answer to show the full evolution of that method's syntax.

@Johnsoct

This comment has been minimized.

Copy link

commented Dec 27, 2017

@bjunc Thank you for breaking it down... Now I know how it got to the aliased + ES6 version.

@Jet12138

This comment has been minimized.

Copy link

commented Jan 31, 2018

h( ) means creatElement( ) ,and App is the first argument and also it is the only argument.So according to the offcial demo,we know that it is just want render the '' in the 'el option' HTML,the usage just same to another way: components:{ App},template: '' .You know it.

@stevebauman

This comment has been minimized.

Copy link

commented Mar 13, 2018

Thank you @bjunc! Jesus, seems like pulling teeth asking questions on Vue repo's just to get simple answers.

I get down-voted on StackOverflow, ignored on Forums and Gitter, and my issues are automatically closed on GitHub when I ask any type of question.

I truly believe issues on GitHub should be a source of documentation.

@LinusBorg

This comment has been minimized.

Copy link
Contributor

commented Mar 13, 2018

Jesus, seems like pulling teeth asking questions on Vue repo's just to get simple answers.
[...] my issues are automatically closed on GitHub when I ask any type of question.

That may be because our Issue guidelines explicitly state that Issues are not a medium to ask questions. We have dedicated forums and chat for that.

ignored on Forums

I'm very active on the forum and happy to help, still things can fall through the cracks with the number of topics we handle each day.

Can you point me to a topic of yours that was not answered? I'll see what I can come up with.

Gitter

We abandoned Gitter months ago, we have an active and helpful Discord chat at chat.vuejs.org (linked from our website)

@katerlouis

This comment has been minimized.

Copy link

commented Jul 25, 2018

Thanks very much for the clarification! Too bad, though, that I have to google the exact code and get info from a github issue..

I have a similar issue with the .$mount("#app") in

new Vue({
  render: h => h(App)
}).$mount('#app')

I think this is interchangable with:

new Vue({
  el: "#app",
  render: h => h(App)
})

If that's correct I really don't see the point in choosing this "new syntax" in a fresh vue-cli project, which is supposed to make things easier.

Vue has many ways of doing the same thing, which is great in many cases.. but in some, it is another hurdle for newcomers (like me) – More consistency throughout the whole vue eco system would be great.

Or atleast properly comment things like render: h => h(App) to educate people.

@luaz

This comment has been minimized.

Copy link

commented Jul 29, 2018

I suspect .$mount('#app') is used instead of el: "#app" is to avoid the need for /* eslint-disable no-new */

@katerlouis

This comment has been minimized.

Copy link

commented Jul 30, 2018

What is eslint-disableno-new?

Too bad that we have to guess this :D

@pfeiferbit

This comment has been minimized.

Copy link

commented Aug 16, 2018

@katerlouis https://eslint.org/docs/rules/no-new

According to this rule new should only be used to create a new instance of an object which would have to be side-effect free. But calling new Vue({...}) implies side-effects when given an el in the config object. The side effect would be DOM manipulation.

If this Vue instance was further assigned to a variable the rule wouldn't be violated. Eslint doesn't actually check whether the new ... call has side-effects or not.

If this Vue instance was directly used through the .$mount(...) method the rule isn't violated either because, again, eslint doesn't actually care about side-effects at all. It just assumes there are none when an object is instantiated and used immediately.

Since many people adopt coding style guidelines like Standard.js or Airbnb which enforce the no-new rule of eslint the typical call of new Vue({...}) without .$mount(...) would be marked as errors.

@15621070585

This comment has been minimized.

Copy link

commented Aug 21, 2018

It's ES6 function

@dvelitchkov

This comment has been minimized.

Copy link

commented Dec 19, 2018

As someone new to Vue, the "there are 4 ways to accomplish the same thing, we'll document 2 of them in the tutorial, but have our bootstrapping tools emit code for the other 2 exclusively" philosophy is really off-putting.

This is probably the wrong place for this, but the docs should really start with the "single file component" style for structuring projects, there's no reason to teach someone an inferior way to structure their project and to leave them scratching their head when actual code doesn't follow any of that.

I think you were going for "noob-friendly" and that's commendable, but I think you're accomplishing the exact opposite in the end - there is nothing "friendly" about writing inline templates as raw strings and getting no code editor help, no highlighting, no automatic balancing, when I could just put my template inside <template>...</template> in a .vue file and make my life that much easier.

@KerimG

This comment has been minimized.

Copy link

commented Dec 26, 2018

Was wondering about the render function myself, Landed here, read a few responses. Then again wondered what the $mount method does and landed here again.

Maybe vue-cli needs some docs about what kind of code its generating and why.

@bjunc

This comment has been minimized.

Copy link

commented Dec 28, 2018

@KerimG in this case, I think the Vue docs are pretty good, and get you most of the way there:
Vue API Docs: vm.$mount()

From the docs:

If a Vue instance didn’t receive the el option at instantiation, it will be in “unmounted” state, without an associated DOM element. vm.$mount() can be used to manually start the mounting of an unmounted Vue instance.

If elementOrSelector argument is not provided, the template will be rendered as an off-document element, and you will have to use native DOM API to insert it into the document yourself.

Similar to render(), createElement(), and use of h() as an alias, mount() has its roots in the vocabulary of vdom. More specifically, the functions that turn javascript into html ("hyperscript").

Here is a pretty cool video where a vdom is created from scratch (43 min, but worth it). You should see some familiar naming conventions:

YouTube: Building a Simple Virtual DOM from Scratch

To your point, I think the Vue docs could benefit from more information / education around VDOM, and how code goes from a SFC (single file component) to HTML. There are hints of it (eg. the section on reactivity), but the dots don't quite connect (IMO).

@KerimG

This comment has been minimized.

Copy link

commented Dec 29, 2018

@bjunc Thanks a lot. Will check out the video ASAP. Much appreciated!

I half-agree with you. The docs do make it sound like $mount does the same as providing the el option but doesn't really explain what the benefit of using $mount, except maybe being able to manually mount your instance. I had no idea it was because of eslint.

@DevPlus31

This comment has been minimized.

Copy link

commented May 18, 2019

Is it possible to update the render function dynamically?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.