關於vue3默認把全部`onSomething`看成`v-on`事件綁定的思考

最近在從新看vue3的rfcs,發現一個細節,原話以下:vue

  • props that start with on are handled as v-on bindings, with everything after on being converted to all-lowercase as the event name (more on this below)

也就是說,之後若是你在傳遞props的時候,以on開頭的props,若是在組件上沒有作props的聲明,那麼會被看成事件綁定到組件的根節點上。node

究其緣由,我大體歸納了兩點:react

  • 兼容vue2中的v-on.native
  • vue3的vnode聲明把props拍平了,爲了區分事件和其餘props,就統一把全部的on開通的props默認做爲事件綁定

爲此,我開了一個issue來討論這個問題,issue地址。我關心的主要有兩點:git

  • 這是對functional component的嚴重限制
  • 是否會致使一些使人括困惑的誤解

先講第一點

vue3中能夠直接經過function() {}來聲明函數組件了,這是一個便利性的很是大的提高。在之前,你要聲明組件,你必需要:github

{
    functinal: true,
    props: {},
    render() {}
}
複製代碼

這最大的提高來自不須要聲明props,爲何說這是提高,由於這讓咱們開發HOC變得更方便了。如今咱們能夠經過...rest的方式把HOC不關心的props直接向下傳遞了。數組

可是如今由於這個默認限制,咱們不得不在HOC中聲明全部可能的他要擴展的組件以on開頭的props。舉個例子,咱們有以下組件:bash

{
    props: {
        name: String,
        onChange: Function
    }
}
複製代碼

而咱們的HOC的功能是在name前面加上prefix,對於這個HOC咱們須要關心的只是name和他本身的props: prefix。因此他的聲明應該以下:app

{
    props: {
        name: String,
        prefix: String
    }
}
複製代碼

而後在render中他能夠這麼作:函數

{
    render() {
        const {name, prefix, ...rest} = props
        return <WrapperedComponent name={`${prefix}-${name}`} {...rest} /> } } 複製代碼

也就是對於HOC來講,他是不須要關心他擴展的組件其餘的props的,可是在這種狀況下,若是咱們不在HOC中聲明,那麼在使用的時候傳入的onChange會自動綁定到root節點,而不是做爲props傳遞下去。測試

第二點:使人困惑的使用

舉個例子,若是我有一個組件:

{
    props: {
        onChange: Function
    },
    methods: {
        handleInput() {
            // do someting
            // 而且根據狀況觸發`onChange`
        }  
    },
    render() {
        return <input onInput={this.handleInput} /> } } 複製代碼

很顯然我是想要封裝input的變化,在知足某些條件的時候纔對外拋出新的value。可是若是這個時候有人就是不看文檔,直接傳遞了onInput,那麼這時候input事件會直接綁定到節點上,那麼這也是能夠觸發的。

若是咱們的測試用例太少或者不仔細,極可能反應不過來他們的區別。這顯然是做爲組件開發者的咱們不但願出現的,但咱們又沒法限制這種行爲。

總結

不得不說,我在考慮這兩個問題的時候是有必定的 React思惟 在裏面的。由於我的來講我是比較喜歡React的API設計的,很是的簡潔,其對於組件的使用也更趨於極致,就是一切皆組件(連redirect這樣的行爲都定義成了組件)。

而vue是一直在跟隨react的,相信這點你們也不會否定。vue3更新的hooks(Composition)API,Suspense等明顯是借鑑的React的概念。

但同時我又是很看好vue3的,我一直以爲vue2這樣的API設計以及.vue文件的開發模式都是爲了吸引中低級用戶而準備的,甚至捨棄了一些高級API特性(好比HOC在vue中就很難實現,而且普及率至關低)。

而vue3的hooks API以及其對JSX的更好支持,還有更純粹的functional component,讓我一度看到了vue在工程方面更激進的變化。

可是v-on的默認行爲,卻又是一次那麼明顯的替用戶作決定的行爲。其實要解決這個問題很簡單,能夠徹底不考慮v-on,把全部傳遞的參數做爲props,若是組件開發者真的要在根節點上綁定事件,他能夠實現的時候綁定,咱們不該該在使用組件的場景下須要考慮在組件內部的節點上作一些事情,這樣作的反作用實在太大了。

雖然目前看來尤老師會聽取個人意見的可能性是很是小的,但我仍是抱有一點簡單的指望吧。

相關文章
相關標籤/搜索