Vue.js渲染函数介绍

来自菜鸟教程
跳转至:导航、​搜索

Vue.js 模板非常强大,几乎可以完成您在应用程序中需要的所有内容。 但是,有一些用例,通常涉及基于输入或槽值的动态组件创建,渲染函数更好地服务。

那些来自 React 世界的人可能对渲染函数非常熟悉。 React 组件是用它们构建的,通常通过 JSX。 虽然 Vue 渲染函数也可以使用 JSX 编写,但我们将坚持使用原始 JS,以便您可以更轻松地了解 Vue 组件系统的基础。

值得注意的是,Vue.js 的模板实际上会在构建时编译为渲染函数。 模板只是在渲染函数之上提供了一种方便且熟悉的语法糖。 尽管渲染功能更强大,但在可读性方面经常受到影响。


创建组件

具有 渲染功能 的组件没有模板标记或属性。 相反,他们定义了一个名为 render 的函数,该函数接收 createElement(renderElement: String | Component, definition: Object, children: String | Array) 参数(通常别名为 h[ X209X],出于某种原因,归咎于 JSX)并返回使用该函数创建的元素。 其他一切都保持不变。

ExampleComponent.vue

export default {
  data() {
    return {
      isRed: true
    }
  },

  /*
   * Same as
   * <template>
   *   <div :class="{'is-red': isRed}">
   *     <p>Example Text</p>
   *   </div>
   * </template>
   */
  render(h) {
    return h('div', {
      'class': {
        'is-red': this.isRed
      }
    }, [
      h('p', 'Example Text')
    ])
  }
}

替换速记指令

Vue 模板带有各种方便的功能,以便为模板添加基本逻辑和绑定功能。 渲染函数无权访问这些。 相反,它们必须用纯 Javascript 实现,对于大多数指令来说,这相当简单。

v-如果

这很容易。 不要使用 v-if,只需在 createElement 调用周围使用普通的 Javascript if (expr) 语句即可。

v-for

v-for 可以使用许多 Javascript 迭代方法中的任何一种来实现,for、for-of、Array.map、Array.filter 等 。 您可以以非常有趣的方式将这些组合起来以实现过滤或状态切片,而无需计算属性。

例如,您可以替换

<template>
  <ul>
    <li v-for="pea of pod">
      {{pea.name}}
    </li>
  </ul>
</template>

render(h) {
  return h('ul', this.pod.map(pea => h('li', pea.name)));
}

v型

要记住的一件好事是,v-model 只是将属性绑定到 value 并在触发 input 事件时设置数据属性的简写. 不幸的是,渲染函数没有这样的简写。 您必须自己实现它,如下所示。

render(h) {
  return h('input', {
    domProps: {
      value: this.myBoundProperty
    },
    on: {
      input: e => {
        this.myBoundProperty = e.target.value
      }
    }
  })
}

这相当于:

<template>
  <input :value="myBoundProperty" @input="myBoundProperty = $event.target.value"/>
</template>

或者

<template>
  <input v-model="myBoundProperty"/>
</template>

v-绑定

属性和属性绑定放在元素定义中,如 arttrspropsdomProps(类似 value内部HTML )。

render(h) {
  return h('div', {
    attrs: {
      // <div :id="myCustomId">
      id: this.myCustomId
    },

    props: {
      // <div :someProp="someonePutSomethingHere">
      someProp: this.someonePutSomethingHere
    },

    domProps: {
       // <div :value="somethingElse">
      value: this.somethingElse
    }
  });
}

附带说明一下,类和样式绑定直接在定义的根处处理,而不是作为 attrs、props 或 domProps

render(h) {
  return h('div', {
    // "class" is a reserved keyword in JS, so you have to quote it.
    'class': {
      myClass: true,
      theirClass: false
    },

    style: {
      backgroundColor: 'green'
    }
  });
}

开启

事件处理程序也直接添加到元素定义中,在 on (或 nativeOn 中,与组件的 v-on.native 具有相同的效果)。 )

render(h) {
  return h('div', {
    on: {
      click(e) {
        console.log('I got clickeded!')
      }
    }
  });
}

修饰符可以在处理程序内部实现:

  • .stop -> e.stopPropagation()
  • .prevent -> e.preventDefault()
  • .self -> if (e.target !== e.currentTarget) 返回

键盘修饰符

  • .[TARGET_KEY_CODE] -> if (event.keyCode !== TARGET_KEY_CODE) 返回
  • .[MODIFIER] -> if (!event.MODIFIERKey) 返回

特殊属性

Slots 可以通过 this.$slots 作为 createElement() 节点的数组来访问。

作用域插槽存储在 this.$scopedSlots[scope](props: object) 作为返回 createElement() 节点数组的函数。

享受渲染功能赋予您的新的、无限的力量! 请小心谨慎使用。