關(guān)于vue3默認(rèn)把所有onSomething當(dāng)作v-on事件綁定的思考
最近在重新看vue3的rfcs,發(fā)現(xiàn)一個細(xì)節(jié),原話如下:
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的聲明,那么會被當(dāng)作事件綁定到組件的根節(jié)點上。
究其原因,我大致概括了兩點:
- 兼容vue2中的v-on.native
- vue3的vnode聲明把props拍平了,為了區(qū)分事件和其他props,就統(tǒng)一把所有的on開通的props默認(rèn)作為事件綁定
為此,我開了一個issue來討論這個問題,issue地址 。我關(guān)心的主要有兩點:
- 這是對functional component的嚴(yán)重限制
- 是否會導(dǎo)致一些令人括困惑的誤解
先講第一點
vue3中可以直接通過 function() {} 來聲明函數(shù)組件了,這是一個便利性的非常大的提升。在以前,你要聲明組件,你必須要:
{ functinal: true, props: {}, render() {} }
這最大的提升來自不需要聲明props,為什么說這是提升,因為這讓我們開發(fā)HOC變得更方便了。現(xiàn)在我們可以通過 ...rest 的方式把HOC不關(guān)心的props直接向下傳遞了。
但是現(xiàn)在因為這個默認(rèn)限制,我們不得不在HOC中聲明所有可能的他要擴展的組件以 on 開頭的props。舉個例子,我們有如下組件:
{ props: { name: String, onChange: Function } }
而我們的HOC的功能是在 name 前面加上 prefix ,對于這個HOC我們需要關(guān)心的只是 name 和他自己的props: prefix 。所以他的聲明應(yīng)該如下:
{ props: { name: String, prefix: String } }
然后在render中他可以這么做:
{ render() { const {name, prefix, ...rest} = props return <WrapperedComponent name={`${prefix}-${name}`} {...rest} /> } }
也就是對于HOC來說,他是不需要關(guān)心他擴展的組件其他的props的,但是在這種情況下,如果我們不在HOC中聲明,那么在使用的時候傳入的 onChange 會自動綁定到root節(jié)點,而不是作為props傳遞下去。
第二點:令人困惑的使用
舉個例子,如果我有一個組件:
{ props: { onChange: Function }, methods: { handleInput() { // do someting // 并且根據(jù)情況觸發(fā)`onChange` } }, render() { return <input onInput={this.handleInput} /> } }
很顯然我是想要封裝 input 的變化,在滿足某些條件的時候才對外拋出新的value。但是如果這個時候有人就是不看文檔,直接傳遞了 onInput ,那么這時候 input 事件會直接綁定到節(jié)點上,那么這也是可以觸發(fā)的。
如果我們的測試用例太少或者不仔細(xì),很可能反應(yīng)不過來他們的區(qū)別。這顯然是作為組件開發(fā)者的我們不希望出現(xiàn)的,但我們又無法限制這種行為。
總結(jié)
不得不說,我在考慮這兩個問題的時候是有一定的 React思維 在里面的。因為個人來說我是比較喜歡React的API設(shè)計的,非常的簡潔,其對于組件的使用也更趨于極致,就是一切皆組件(連 redirect 這樣的行為都定義成了組件)。
而vue是一直在跟隨react的,相信這點大家也不會否認(rèn)。vue3更新的hooks(Composition)API,Suspense等明顯是借鑒的React的概念。
但同時我又是很看好vue3的,我一直覺得vue2這樣的API設(shè)計以及 .vue 文件的開發(fā)模式都是為了吸引中低級用戶而準(zhǔn)備的,甚至舍棄了一些高級API特性(比如HOC在vue中就很難實現(xiàn),并且普及率相當(dāng)?shù)停?/p>
而vue3的hooks API以及其對JSX的更好支持,還有更純粹的 functional component ,讓我一度看到了vue在工程方面更激進(jìn)的變化。
但是 v-on 的默認(rèn)行為,卻又是一次那么明顯的 替用戶做決定 的行為。其實要解決這個問題很簡單,可以完全不考慮 v-on ,把所有傳遞的參數(shù)作為props,如果組件開發(fā)者真的要在根節(jié)點上綁定事件,他可以實現(xiàn)的時候綁定,我們不應(yīng)該在使用組件的場景下需要考慮在組件內(nèi)部的節(jié)點上做一些事情,這樣做的副作用實在太大了。
雖然目前看來尤老師會聽取我的意見的可能性是非常小的,但我還是抱有一點簡單的期望吧。
到此這篇關(guān)于關(guān)于vue3默認(rèn)把所有onSomething當(dāng)作v-on事件綁定的思考的文章就介紹到這了,更多相關(guān)vue3 onSomething當(dāng)作v-on事件綁定內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue-admin-template?報Uncaught?(in?promise)?error問題及解決
這篇文章主要介紹了Vue-admin-template?報Uncaught?(in?promise)?error問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07vue3+高德地圖只展示指定市、區(qū)行政區(qū)域的地圖以及遮罩反向鏤空其他地區(qū)
vue大屏項目開發(fā),客戶覺得地圖上的文字標(biāo)注太多了,要求地圖上只顯示省市等主要城市的標(biāo)注,這篇文章主要給大家介紹了關(guān)于vue3+高德地圖只展示指定市、區(qū)行政區(qū)域的地圖以及遮罩反向鏤空其他地區(qū)的相關(guān)資料,需要的朋友可以參考下2024-02-02ElementUI 修改默認(rèn)樣式的幾種辦法(小結(jié))
這篇文章主要介紹了ElementUI 修改默認(rèn)樣式的幾種辦法(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07Vue-cli proxyTable 解決開發(fā)環(huán)境的跨域問題詳解
本篇文章主要介紹了Vue-cli proxyTable 解決開發(fā)環(huán)境的跨域問題詳解,非常具有實用價值,需要的朋友可以參考下2017-05-05Vue項目中new?Vue()和export?default{}的區(qū)別說明
這篇文章主要介紹了Vue項目中new?Vue()和export?default{}的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03淺談vue中使用編輯器vue-quill-editor踩過的坑
這篇文章主要介紹了淺談vue中使用編輯器vue-quill-editor踩過的坑,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08解決vue elementUI中table里數(shù)字、字母、中文混合排序問題
這篇文章主要介紹了vue elementUI中table里數(shù)字、字母、中文混合排序問題,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-01