Vue3中不止composition-api,其餘的提案(RFC)也很精彩。

最近一段時間,Vue3帶來的新能力composition-api帶來了比較大的轟動,雖然是靈感是源React Hook,可是在不少方面卻超越了它。可是除了composition-api,其餘的改動卻比較少有人討論,本篇文章就由vuejs/rfcs 這個倉庫來看看其餘比較讓人振奮的RFC。html

RFC其實就是(Request For Comments)徵求修正意見書,它不表明這個api必定會正式經過,可是卻可讓社區知道vuejs團隊正在進行的一些工做,和一些新想法。vue

Vue的RFC分爲四個階段:node

  1. Pending:當RFC做爲PR提交時。react

  2. Active:當RFC PR正在合併時。git

  3. Landed:當RFC提出的更改在實際發行版中發佈時。github

  4. Rejected:關閉RFC PR而不合並時。segmentfault

本篇討論的RFC都在Active階段api

刪除filters的支持

<!-- before -->
{{ msg | format }}

<!-- after -->
{{ format(msg) }}
複製代碼

動機:app

  1. 過濾器的功能能夠輕鬆地經過方法調用或計算的屬性來複制,所以它主要提供語法而不是實用的價值。dom

  2. 過濾器須要一種自定義的微語法,該語法打破了表達式只是「 JavaScript」的假設-這增長了學習和實現成本。 實際上,它與JavaScript本身的按位或運算符(|)衝突,並使表達式解析更加複雜。

  3. 過濾器還會在模板IDE支持中增長額外的複雜性(因爲它們不是真正的JavaScript)。

替代:

  1. 能夠簡單的利用method替換filter的能力,統一語法,Vue.filter全局註冊的能力也能夠用Vue.prototype全局掛載方法來實現。

  2. 目前有一個stage-1的提案pipeline-operator 能夠優雅的實現方法組合。

let transformedMsg = msg |> uppercase |> reverse |> pluralize
複製代碼

render函數的改變

原文:
github.com/vuejs/rfcs/…

概覽:

  1. h如今已全局導入,而不是傳遞給渲染函數做爲參數

  2. 渲染函數參數已更改,並使stateful組件和functional組件之間保持一致

  3. VNode如今具備拉平的props結構

基本示例:

// globally imported `h`
import { h } from 'vue'

export default {
  render() {
    return h(
      'div',
      // flat data structure
      {
        id: 'app',
        onClick() {
          console.log('hello')
        }
      },
      [
        h('span', 'child')
      ]
    )
  }
}
複製代碼

動機: 在2.x中,VNode是特定於上下文的-這意味着建立的每一個VNode都綁定到建立它的組件實例(「上下文」),

在2.x中,這樣的一段代碼:

{
    render(h) {
        return h('div')
    }
}
複製代碼

h實際上是經過render中的形參傳入的,這是由於它須要關心是哪一個組件實例在調用它,在3.x中,文章中介紹說vnode將會成爲context free的,這意味着更加靈活的組件聲明位置(不止在.vue文件中,不須要處處傳遞h參數)。

而且若是context free真的實現,那麼在2.x中Vue高階組件的一些詬病也能夠一同解決掉了,若是對context帶來的高階組件的bug感興趣的話,能夠查看HcySunYang大大的這篇文章:
segmentfault.com/p/121000001…

另外本篇中還提到了一個vnode的屬性拉平,

// before
{
  class: ['foo', 'bar'],
  style: { color: 'red' },
  attrs: { id: 'foo' },
  domProps: { innerHTML: '' },
  on: { click: foo },
  key: 'foo'
}

// after
{
  class: ['foo', 'bar'],
  style: { color: 'red' },
  id: 'foo',
  innerHTML: '',
  onClick: foo,
  key: 'foo'
}
複製代碼

目前看來,因爲jsx最終會被編譯成生成vnode的方法,這個改動可能會讓vue中書寫jsx變得更加容易,如今的一些寫法能夠看我寫的這篇文章:
手把手教你用jsx封裝Vue中的複雜組件(網易雲音樂實戰項目需求)

在這篇文章中能夠看出,目前嵌套的vnode結構會讓jsx的書寫也變得很困難。

因爲render函數的一些另外的細微變更,Vue3中理想的functional component的書寫方式是這樣的:

import { inject } from 'vue'
import { themeSymbol } from './ThemeProvider'

const FunctionalComp = props => {
  const theme = inject(themeSymbol)
  return h('div', `Using theme ${theme}`)
}
複製代碼

是否是很像React,哈哈。

全局方法的導入方式

爲了更好的支持tree-shaking,Vue3把2.x中統一導出Vue的方式更改成分散導出,這樣只有項目中用到的方法會被打包進bundle中,有效的減小了包的大小。

import { nextTick, observable } from 'vue'

nextTick(() => {})

const obj = observable({})
複製代碼

簡單的來講,若是你項目中只用到了observablenextTick,那麼例如usereactive等這些另外的api就不會被打包進你的項目中。

關於tree-shaking,我特別喜歡的做者相學長有一篇文章能夠看一下:

zhuanlan.zhihu.com/p/32831172

總結

在這個倉庫中,還有一些提案你們也能夠自行去看一下,剩下的都是一些細節的優化,這些優化或多或少的會讓Vue3更好用一些,很是期待Vue3的到來。

另外因爲plugin的存在,我已經在2.x中用Vue3的composition-api作了一些嚐鮮,不得不說真香

Vue3 Composition-Api + TypeScript + 新型狀態管理模式探索

相關文章
相關標籤/搜索