render function & createComponent
https://vuejs.org/v2/guide/render-function.html
https://cn.vuejs.org/v2/guide/render-function.html
Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接近编译器。
render: h => h(App) 这行初始化代码很常见到,它是下面内容的缩写:
render: function (createElement) {
return createElement(App);
}
缩写形式有以下3种(ES6 语法):
render (createElement) {
return createElement(App);
}
render (h){
return h(App);
}
render: h => h(App);
其中 根据 Vue.js 作者 Even You 的回复,h 的含义如下:
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".
它来自单词 hyperscript,这个单词通常用在 virtual-dom 的实现中。Hyperscript 本身是指生成HTML 结构的 script 脚本,因为 HTML 是 hyper-text markup language 的缩写(超文本标记语言)。个人理解:createElement 函数是用来生成 HTML DOM 元素的,也就是上文中的 generate HTML structures,也就是 Hyperscript,这样作者才把 createElement 简写成 h。
下面这个列子展示了 render 函数和 createElemnt 函数结合来动态生成模板,这种使用脚本生成的组件称为函数式组件。
<div id="app">
<child v-bind:level="2">Hello world!</child>
</div>
<script type="text/javascript">
Vue.component('child', {
render: function (createElement) {
return createElement(
'h' + this.level, // tag name 标签名称 h1,h2,h3...
this.$slots.default // 子组件中的阵列
)
},
props: {
level: {
type: Number,
required: true
}
}
})
new Vue({
el: "#app"
})
</script>
关于createElement方法,他是通过render函数的参数传递进来的。它更准确的名字可能是 createNodeDescription,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,及其子节点。我们把这样的节点描述为“虚拟节点 (Virtual Node)”,也常简写它为“VNode”。VDOM是由 Vue 组件树建立起来的整个 VNode 树的称呼。这个方法有三个参数:
- 第一个参数(字符串、对象或函数)
主要用于提供dom的html内容。比如传入 "div" 就是创建一个 <div>标签 - 第二个参数(类型是对象)
主要用于设置这个dom的一些样式、属性、传的组件的参数、绑定事件之类,具体可以参考官方文档 - 第三个参数(类型是数组,数组元素类型是VNode)
主要用于说是该结点下有其他结点的话,就放在这里。
比如说,有需要分发的标签 <slot>,则通过 this.$slots.default 来获得,或许还有其他组件之类,可能需要被使用的,应该也是放在这里。
Vue 的模板实际是编译成了 render 函数。这是一个实现细节,通常不需要关心,但如果你想看看模板的功能是怎样被编译的,你会发现会非常有趣。下面是官方文档展示一个使用 Vue.compile 来实时编译模板字符串的简单 demo:
<div>
<header> <h1>I'm a template!</h1> </header>
<p v-if="message"> {{ message }} </p>
<p v-else> No message. </p>
</div>
Vue 编译后产生的 render,可以猜测这个 "c" 就是 createElement 的缩写:
function anonymous() {
with(this){return _c('div',[_m(0),(message)?_c('p',[_v(_s(message))]):_c('p',[_v("No message.")])])}
}
_m(0): function anonymous() {
with(this){return _c('header',[_c('h1',[_v("I'm a template!")])])}
}
网友评论