vuejs-templates / webpack-simple

A simple Webpack + vue-loader setup for quick prototyping.
2.27k stars 893 forks source link

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

Closed kaihendry closed 8 years ago

kaihendry commented 8 years ago

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

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

LinusBorg commented 8 years ago

https://vuejs.org/guide/render-function.html

kaihendry commented 8 years ago

It's the h I was puzzled about.

chrisvfritz commented 8 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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

render: function(createElement) {
    return createElement(App);
}
bjunc commented 7 years ago

@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 commented 6 years ago

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

Jet12138 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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)

rupesh-terase commented 6 years ago

https://forum.vuejs.org/t/vue-js-tag-which-dont-render-as-html-tag-but-works-after-template-tag-as-wrapper/36808

still unanswered :(

katerlouis commented 6 years ago

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 commented 6 years ago

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

katerlouis commented 6 years ago

What is eslint-disableno-new?

Too bad that we have to guess this :D

pfeiferbit commented 6 years ago

@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.

SkyforFee commented 6 years ago

It's ES6 function

dvelitchkov commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

@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 commented 5 years ago

@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 commented 5 years ago

Is it possible to update the render function dynamically?

DiazRock commented 4 years ago

I enter to this page in February 2020, and this is the first page that appears to me when I googled for an explanation about render...$mount(). So, it looks like there are not yet a popular documentation about it.

redfox05 commented 4 years ago

I enter this page in May 2020 😄, and really glad that people are not prevented from commenting further on this issue as the explanations have been fantastic, even though this is off-topic for the bugfix.

I arrived here via a Google search nothing to do with vuejs-templates, but found exactly what I was looking for in the excellently explained answers from people here on the h => h shorthands, and how it breaks down. Extra thanks to @bjunc there, and the mount explanations from several people.

THANK YOU! :D

Jet12138 commented 4 years ago

HaHa,you are welcome

---Original--- From: "Redfox05"<notifications@github.com> Date: Fri, May 22, 2020 00:59 AM To: "vuejs-templates/webpack-simple"<webpack-simple@noreply.github.com>; Cc: "Jet"<390715001@qq.com>;"Comment"<comment@noreply.github.com>; Subject: Re: [vuejs-templates/webpack-simple] Explanation for render: h =&gt; h(App) please (#29)

Really glad that people are not prevented from commenting further on this issue, as even though this is off-topic for the bugfix, I arrived here via a Google search nothing to do with vuejs-templates, but found exactly what I was looking for in the excellently explained answers from people here on the h => h shorthands, and how it breaks down. Extra thanks to @bjunc there, and the mount explanations from several people.

THANK YOU! :D

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.