Vue中的render函數

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)
      ]


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章