Closed kaihendry closed 8 years ago
It's the h
I was puzzled about.
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.
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?
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.
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.
@bjunc I think a more "accurate" paraphrase is:
render: function(createElement) {
return createElement(App);
}
@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.
@bjunc Thank you for breaking it down... Now I know how it got to the aliased + ES6 version.
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 '
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.
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)
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.
I suspect .$mount('#app')
is used instead of el: "#app"
is to avoid the need for /* eslint-disable no-new */
What is eslint-disableno-new
?
Too bad that we have to guess this :D
@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.
It's ES6 function
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.
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.
@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. \ IfelementOrSelector
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).
@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.
Is it possible to update the render function dynamically?
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.
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
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 => 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.
https://github.com/vuejs-templates/webpack-simple/blob/master/template/src/main.js
What does
render: h => h(App)
mean?