render()
Vue.component('anchored-heading', { render: function (createElement) { return createElement(//VNode,虚拟dom 'h' + this.level, // tag name 标签名称 this.$slots.default // 子组件中的阵列 ) }, props: { level: { type: Number, required: true } } })
<anchored-heading :level="1">Hello world!</anchored-heading>
// @returns {VNode} createElement( // {String | Object | Function} // 一个 HTML 标签字符串,组件选项对象,或者一个返回值类型为 String/Object 的函数,必要参数 'div', { // {Object} // 一个包含模板相关属性的数据对象 // 这样,您可以在 template 中使用这些属性。可选参数。 }, // {String | Array} // 子节点 (VNodes),由 `createElement()` 构建而成, // 或使用字符串来生成“文本节点”。可选参数。 [ '先写一些文字', createElement('h1', '一则头条'), createElement(MyComponent, { props: { someProp: 'foobar' } }) ] )
组件树中的所有 VNodes 必须是唯一的,如果需要重复
render: function (createElement) { return createElement('div', Array.apply(null, { length: 20 }).map(function () { return createElement('p', 'hi') }) ) }
render中 不能用模板中可以使用的v-for,v-if,v-model而是用原生JS实现
v-model在render中的实现: render: function (createElement) { var self = this return createElement('input', { domProps: { value: self.value }, on: { input: function (event) { self.value = event.target.value self.$emit('input', event.target.value) } } }) }
事件修饰符
Modifier(s) | Prefix |
.passive | & |
.capture | ! |
.once | ~ |
.capture.once | ~! |
.once.capture | ~! |
对于其他的修饰符,前缀不是很重要,因为你可以在事件处理函数中使用事件方法:
Modifier(s) | Equivalent in Handler |
---|---|
.stop |
event.stopPropagation() |
.prevent |
event.preventDefault() |
.self |
if (event.target !== event.currentTarget) return |
Keys:.enter , .13 |
if (event.keyCode !== 13) return (change 13 to another key code for other key modifiers) |
Modifiers Keys:.ctrl , .alt , .shift , .meta |
if (!event.ctrlKey) return (change ctrlKey to altKey , shiftKey , or metaKey , respectively) |
插槽
render: function (createElement) { // `<div><slot></slot></div>` return createElement('div', this.$slots.default)//静态内容 }
render: function (createElement) { // `<div><slot :text="msg"></slot></div>` return createElement('div', [ this.$scopedSlots.default({//用作函数 text: this.msg }) ]) }
向子组件传递 render (createElement) { return createElement('div', [ createElement('child', { // pass `scopedSlots` in the data object // in the form of { name: props => VNode | Array<VNode> } scopedSlots: { default: function (props) { return createElement('span', props.text) } } }) ]) }
jsx:
import AnchoredHeading from './AnchoredHeading.vue' new Vue({ el: '#demo', render (h) {//将h
作为createElement
的别名 return ( <AnchoredHeading level={1}> <span>Hello</span> world! </AnchoredHeading> ) } })
函数式组件:标记组件为 functional
,这意味它是无状态 (没有 data
),无实例
Vue.component('my-component', { functional: true, // 为了弥补缺少的实例 // 提供第二个参数作为上下文 render: function (createElement, context) { // ... }, // Props 可选 props: { // ... } })
函数式组件需要的一切都是通过上下文传递,包括: props:提供 props 的对象 children: VNode 子节点的数组 slots: slots 对象 data:传递给组件的 data 对象 parent:对父组件的引用 listeners: (2.3.0+) 一个包含了组件上所注册的 v-on 侦听器的对象。这只是一个指向 data.on 的别名。 injections: (2.3.0+) 如果使用了 inject 选项,则该对象包含了应当被注入的属性this.$slots.default
更新为context.children
,之后this.level
更新为context.props.level