render function

  • 类型(createElement: () => VNode) => VNode

  • 详细

    字符串模板的代替方案,允许你发挥 JavaScript 最大的编程能力。该渲染函数接收一个 createElement 方法作为第一个参数用来创建 VNode

    如果组件是一个函数组件,渲染函数还会接收一个额外的 context 参数,为没有实例的函数组件提供上下文信息。

    Vue 选项中的 render 函数若存在,则 Vue 构造函数不会从 template 选项或通过 el 选项指定的挂载元素中提取出的 HTML 模板编译渲染函数

组件中的 template 会被编译成 render function。

下例中,直接用 render function 代替 template,结果相同。

import Vue from 'vue'

const component = {
  name: 'comp',
  // template: `
  //   <div :style="style">
  //     <slot></slot>
  //   </div>
  // `,
  render (createElement) {
    return createElement('div', {
      style: this.style
    }, this.$slots.default)
  },
  data () {
    return {
      style: {
        width: '200px',
        height: '200px',
        border: '1px solid #aaa'
      },
      value: 'component value'
    }
  }
}

new Vue({
  components: {
    CompOne: component
  },
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp, this.$refs.span, this.$refs.comp.value)
  },
  template: `
    <div>
      <comp-one ref="comp">
        <span ref="span">{{value}}</span>
      </comp-one>
    </div>
  `,
  render (createElement) {
    return createElement(
      'comp-one',
      {
        ref: 'comp'
      },
      [
        createElement('span', {
          ref: 'span'
        }, this.value)
      ])
  }
})

createElement

createElement,是 vue 虚拟 DOM 的概念,创建出来的并不是 html 节点,而是 VNode 的一个类,类似 DOM 结构的一个结构,并存在内存中,它会和真正的 DOM 进行对比,若发现需要更新的 DOM,才会去转换这部分 DOM 内容,并填到真正的 DOM 中,从而提高性能

createElement 可使用的属性

指令

传值 props

render (createElement) {
    return createElement(
      'comp-one',
      {
        ref: 'comp',
        props: { // props 传值
          props1: this.value
        }
      },
      [
        createElement('span', {
          ref: 'span'
        }, this.value)
      ])
  }

绑定事件

on
render (createElement) {
    return createElement(
      'comp-one',
      {
        ref: 'comp',
        on: { // 事件监听(一),这里是组件上监听,需要 $emit
          click: this.handleClick
        },
      },
      [
        createElement('span', {
          ref: 'span'
        }, this.value)
      ])
  }
nativeOn
render (createElement) {
    return createElement(
      'comp-one',
      {
        ref: 'comp',
        nativeOn: {
          click: this.handleClick
        }
      },
      [
        createElement('span', {
          ref: 'span'
        }, this.value)
      ])
  }
nativeOn 与 on 的区别

nativeOn 也是绑定到组件上,但是不需要组件发 $emit,它会自动绑定到这个组件的根节点的原生 DOM 上,如果本身就是原生 DOM,直接绑定。

slot

// 组件中
render (createElement) {
    return createElement('div', {
      style: this.style,
      on: {
        click: () => { this.$emit('click') }
      }
    }, [
      this.$slots.header, // 通过 $slot拿到 header,如果没命名就是 default
      this.props1
    ])
  }
// new Vue()
[
    createElement('span', {
        ref: 'span',
        slot: 'header' // 指定具名插槽
    }, this.value)
]

domProps

类似原生 DOM 操作,把 span 覆盖掉了。

[
        createElement('span', {
          ref: 'span',
          slot: 'header',
          domProps: {
            innerHTML: '<span>345</span>'
          }
        }, this.value)
      ]

attrs

给 span 加一个 id。

[
        createElement('span', {
          ref: 'span',
          slot: 'header',
          // domProps: {
          //   innerHTML: '<span>345</span>'
          // }
          attrs: {
            id: 'test-id'
          }
        }, this.value)
      ]

等等

总结

写组件的方式

  • template
  • render function
  • jsx
Logo

前往低代码交流专区

更多推荐