Vue.js 模板非常强大,可以实现您在应用程序中所需的一切,但有一些用例,通常涉及基于输入或插槽值的动态组件创建,这些功能通过渲染更好地提供服务。
那些来自React世界的人可能对渲染函数非常熟悉。React组件是用它们构建的,通常是通过JSX,而Vue渲染函数也可以用JSX写,但我们会坚持原始JS,以便您更容易理解Vue组件系统的支撑。
<$>[注] 值得注意的是,Vue.js 的模板实际上是在构建时编译以渲染函数。 模板只是在渲染函数上提供一个方便而熟悉的语法糖。
创建一个组件
具有渲染函数的组件没有模板标签或属性。相反,它们定义了一个名为渲染的函数,该函数接收一个createElement(renderElement: Stringimmo Component,定义:对象,孩子:Stringimmo Array)参数(通常为h,出于某种原因,责怪JSX),并返回一个与该函数创建的元素。
1[label ExampleComponent.vue]
2export default {
3 data() {
4 return {
5 isRed: true
6 }
7 },
8
9 /*
10 * Same as
11 * <template>
12 * <div :class="{'is-red': isRed}">
13 * <p>Example Text</p>
14 * </div>
15 * </template>
16 */
17 render(h) {
18 return h('div', {
19 'class': {
20 'is-red': this.isRed
21 }
22 }, [
23 h('p', 'Example Text')
24 ])
25 }
26}
取代短期指令
视图模板配备了各种方便的功能,以便为模板添加基本的逻辑和约束功能. 渲染函数无法访问这些功能. 相反,它们必须在简单的JavaScript中实现,这对于大多数指令来说相当简单。
五、如果
这个很简单,而不是使用v-if,只需在你的createElement呼叫周围使用正常的JavaScript如果(expr)声明。
v 為
v-for 可以与许多 JavaScript 迭代方法,for、for-of、Array.map、Array.filter 等进行实现,您可以以非常有趣的方式将这些方法相结合,实现过滤或状态切割,而无需计算属性。
例如,你可以取代
1<template>
2 <ul>
3 <li v-for="pea of pod">
4 {{pea.name}}
5 </li>
6 </ul>
7</template>
与
1render(h) {
2 return h('ul', this.pod.map(pea => h('li', pea.name)));
3}
v 模型
要记住的一件好事是,v 模型只是一个强制性属性的缩写,以便在输入事件启动时评估和设置数据属性。
1render(h) {
2 return h('input', {
3 domProps: {
4 value: this.myBoundProperty
5 },
6 on: {
7 input: e => {
8 this.myBoundProperty = e.target.value
9 }
10 }
11 })
12}
这相当于:
1<template>
2 <input :value="myBoundProperty" @input="myBoundProperty = $event.target.value"/>
3</template>
或
1<template>
2 <input v-model="myBoundProperty"/>
3</template>
V 连接
属性和属性绑定被放置在元素定义中,如 arttrs、props 和 domProps(如值和 innerHTML)。
1render(h) {
2 return h('div', {
3 attrs: {
4 // <div :id="myCustomId">
5 id: this.myCustomId
6 },
7
8 props: {
9 // <div :someProp="someonePutSomethingHere">
10 someProp: this.someonePutSomethingHere
11 },
12
13 domProps: {
14 // <div :value="somethingElse">
15 value: this.somethingElse
16 }
17 });
18}
作为一个侧面的注意事项,类和风格绑定被直接处理在定义的根源,而不是作为 attrs,props,或domProps。
1render(h) {
2 return h('div', {
3 // "class" is a reserved keyword in JS, so you have to quote it.
4 'class': {
5 myClass: true,
6 theirClass: false
7 },
8
9 style: {
10 backgroundColor: 'green'
11 }
12 });
13}
《V》
事件处理器也被直接添加到元素定义中,在 on (或 nativeOn 中,它对组件具有与 v-on.native 相同的效果。
1render(h) {
2 return h('div', {
3 on: {
4 click(e) {
5 console.log('I got clickeded!')
6 }
7 }
8 });
9}
修改器可以在处理器内部实现:
*.stop -> e.stopPropagation() *.prevent -> e.preventDefault() *.self -> 如果 (e.target!== e.currentTarget) 返回
键盘修改器
*.[TARGET_KEY_CODE] -> 如果 (event.keyCode!== TARGET_KEY_CODE) 返回 *.[MODIFIER] -> 如果 (!event.MODIFIERKey) 返回
特殊财产
Slots可以通过 this.$slots 作为 createElement() 节点的数组访问。
Scoped 插槽存储在 this.$scopedSlotsscope中,作为返回数组 createElement()节点的函数。
享受通过渲染功能赋予您新的无限权力!只需谨慎使用。