VUE中render函數h的理解


render函數在使用中經常遇到類似以下用法:

 component: { render: h => h("router-view") },

語法解釋如下:

render: function (createElement) {
    return createElement(App);
}

ES6中:

render (createElement) {
    return createElement(App);
}

此處,官網文檔中有描述,內容如下:

將 h 作為 createElement 的別名是 Vue 生態系統中的一個通用慣例,實際上也是 JSX 所要求的。從 Vue 的 Babel 插件的 3.4.0 版本開始,我們會在以 ES2015 語法聲明的含有 JSX 的任何方法和 getter 中 (不是函數或箭頭函數中) 自動注入 const h = this.$createElement,這樣你就可以去掉 (h) 參數了。對於更早版本的插件,如果 h 在當前作用域中不可用,應用會拋錯。

寫法變更為:

render (h) {
    return h(App);
}

改寫為箭頭函數:

render: h => h(App);

以下引自官方文檔

函數式組件

之前創建的錨點標題組件是比較簡單,沒有管理任何狀態,也沒有監聽任何傳遞給它的狀態,也沒有生命周期方法。實際上,它只是一個接受一些 prop 的函數。
在這樣的場景下,我們可以將組件標記為 functional,這意味它無狀態 (沒有響應式數據),也沒有實例 (沒有 this 上下文)。
一個函數式組件就像這樣:

 Vue.component('my-component', {
  functional: true,
  // Props 是可選的
  props: {
    // ...
  },
  // 為了彌補缺少的實例
  // 提供第二個參數作為上下文
  render: function (createElement, context) {
    // ...
  }
})

在 2.5.0 及以上版本中,如果你使用了單文件組件,那么基於模板的函數式組件可以這樣聲明:

<template functional>
</template>

組件需要的一切都是通過 context 參數傳遞,它是一個包括如下字段的對象:

  • props:提供所有 prop 的對象
  • children: VNode 子節點的數組
  • slots: 一個函數,返回了包含所有插槽的對象
  • scopedSlots: (2.6.0+) 一個暴露傳入的作用域插槽的對象。也以函數形式暴露普通插槽。
  • data:傳遞給組件的整個數據對象,作為 createElement 的第二個參數傳入組件
  • parent:對父組件的引用
  • listeners: (2.3.0+) 一個包含了所有父組件為當前組件注冊的事件監聽器的對象。這是 data.on 的一個別名。
  • injections: (2.3.0+) 如果使用了 inject 選項,則該對象包含了應當被注入的屬性。

在添加 functional: true 之后,需要更新我們的錨點標題組件的渲染函數,為其增加 context 參數,並將 this.$slots.default 更新為 context.children,然后將 this.level 更新為 context.props.level。

因為函數式組件只是函數,所以渲染開銷也低很多。

在作為包裝組件時它們也同樣非常有用。比如,當你需要做這些時:

  • 程序化地在多個組件中選擇一個來代為渲染;
  • 在將 children、props、data 傳遞給子組件之前操作它們。

下面是一個 smart-list 組件的例子,它能根據傳入 prop 的值來代為渲染更具體的組件:

var EmptyList = { /* ... */ }
var TableList = { /* ... */ }
var OrderedList = { /* ... */ }
var UnorderedList = { /* ... */ }

Vue.component('smart-list', {
  functional: true,
  props: {
    items: {
      type: Array,
      required: true
    },
    isOrdered: Boolean
  },
  render: function (createElement, context) {
    function appropriateListComponent () {
      var items = context.props.items

      if (items.length === 0)           return EmptyList
      if (typeof items[0] === 'object') return TableList
      if (context.props.isOrdered)      return OrderedList

      return UnorderedList
    }

    return createElement(
      appropriateListComponent(),
      context.data,
      context.children
    )
  }
})


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM