vue-12-渲染函数 & JSX

时间:2021-04-19 20:11:52

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="">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: }).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 altKeyshiftKey, 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={}>
<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.+) 一个包含了组件上所注册的 v-on 侦听器的对象。这只是一个指向 data.on 的别名。
injections: (2.3.+) 如果使用了 inject 选项,则该对象包含了应当被注入的属性
this.$slots.default 更新为 context.children,之后this.level 更新为 context.props.level