Vue核心知识-Vue的组件之render函数

2018-09-08  本文已影响0人  王童孟

render function

组件中的 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)
      ]

等等

总结

写组件的方式

上一篇 下一篇

猜你喜欢

热点阅读