Vue有20樣寫法,你知道么?
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
引入打開 Vue3 的官方文檔,它首先會告訴你,Vue 的組件可以按兩種不同的風格書寫:選項式 API 和組合式 API。文檔為我們提供一系列兩種風格的代碼參考,供我們按照偏好進行選擇。 實際上,Vue3 組件可不止兩種寫法,而是多達十幾種!然而,不管是什么寫法,它們都是基于同一個底層系統實現的,概念之間也是彼此相通的,只是使用的接口不同。在實際開發中,我們也不會同時使用到那么多種寫法,但是這并不意味著我們不需要去了解這些寫法! 如果你仔細閱讀 Vue3 的文檔,會發現一些示例或者 api 看起來模棱兩可,不知道這些 api 到底有什么用,或者閱讀 Vue 的源碼時,總是能發現一些對于我們來說意圖不明的邏輯,那么,你可能先要了解一些 Vue 的寫法。先了解一個東西怎么用,再去分析它是怎么實現的。 看完本文章,你會收獲到:
本文章遵從循序漸進的寫作順序,從易到難,輕松上手! setup 語法糖setup 語法糖應該是最常用的寫法了。在 Vue3 中,我們想封裝一個組件,最習慣的做法還是新建一個 Vue 文件,并將組件代碼寫在文件中。具體是:頁面結構寫在 template 中,頁面邏輯寫在 script 中,頁面樣式寫在 style 中。 總之,我們將與該組件相關的代碼都寫在一起、放在一個文件中單獨維護,在需要該組件的地方引入使用。 這里我們使用了 setup 語法糖,直接在 script 中書寫我們的 setup 內部的邏輯。
在 App. vue 中引入并使用:
注:后續寫法盡管形式不同,但它們最終的目的都是導出一個組件,所以對于組件使用方來說(這里是 App. vue),怎么使用這個組件的代碼都是不變的,所以將不再重復此代碼。 Vue2 選項式寫法Vue2 經典寫法這種寫法也是比較經典的。和 setup 語法糖寫法類似。我們需要新建一個 vue 文件來存儲我們的組件代碼,然后在需要使用該組件的地方對其進行引入。區別在于,我們需要在 script 中導出一個 Vue 實例。 這里我們導出的其實是一個普通對象,該對象包含 data、methods 等屬性。這個對象的屬性都是可選的,即 option,翻譯回來即“選項”。
defineComponent 輔助函數盡管我們在 script 語言塊中導出的默認對象會被 vue 編譯器當成 vue 實例,但不管怎么看,它依舊只是一個 plain object。在定義組件實例方面,vue 提供了一個名為 defineComponent 輔助接口。
盡管這個接口也不能改變我們導出的是一個普通對象的事實,但是它可以為我們的實例提供強大的類型推導。我們可以把它看成是一個返回 vue 實例的工廠函數,讓我們的代碼看起來更加規范。 Vue3 選項式寫法在 Vue3 中,官方引入了新的選項 setup,這是 Vue3 選項式寫法和 Vue2 寫法的主要區別。setup 選項的意義在于它允許我們在選項式的寫法中引用和使用組合式的 api,比如 onMounted、ref、reactive 等。但對于我們來說,它對于我們有益的地方還是基于它封裝起來的 setup 語法糖用起來很方便。
使用 defineComponent 時,它能夠提示我們 setup 將會接收到什么參數:
以上寫法我們都是在 template 上書寫我們的頁面結構,這也是最常見的幾種寫法,下面我們來介紹幾種了解 vue 底層必不可少的寫法,渲染函數。 手寫渲染函數template 模板語法本質上也可以算是一種語法糖。在 vue 編譯器上,template 中的內容最終會被翻譯為渲染函數,掛載到 vue 實例的 render 屬性上。當需要渲染組件時,vue 就執行一次 render,得到對應的虛擬節點樹,最后再轉變為真實 dom。 Vue 允許我們脫離 template,直接自己書寫渲染函數。位置就在導出實例的 render 選項上:
在 template 中,我們使用類似 html 的模板語法來描述我們的視圖,在 render 函數中又如何描述呢?vue 提供了兩個 api:createVnode 和 h。二者沒有區別,h 函數只是 createVnode 的縮寫。有了 render 函數,我們就不需要寫 template 了。
在上面的示例中,我們使用 h 函數生成了一個 vNode,并 return 出去,作為本組件最終在被使用時渲染出來的效果。 在 template 中我們可以使用 v-if、v-for、slot 等模板語法,在 h 函數中這些概念也是支持的,只是形式不同,這方面官方文檔有具體的示例。總之,template 模板和 render 選項是可以相互替代的。 setup 返回渲染函數setup 返回 render 方法一般來說,在選項式語法中,setup 方法返回一個對象,該對象暴露給 template,供 template 使用,具體參考第三個例子(vue3 選項式寫法)。如果我們不使用 template,也就沒有返回對象的必要了。 在 Vue3 中,還有另外一種不使用 template 的寫法,就是在 setup 方法中返回一個 render 方法。
注意:
defineComponent 傳入setup就注意中的第一點,我們可以采用下面這種寫法:直接在 defineComponent 中書寫 setup 函數(如果再省一點就是 setup 語法糖的寫法了)。
以上就是渲染函數的寫法,是不是有點感覺了呢,一下子就學會了兩個 api!后面會提到的 Jsx 寫法其實也應該歸為渲染函數寫法的一種(只要不是 template,而是用 JavaScript 表達頁面結構的,都是渲染函數),但是相對于 h 函數,jsx 并不是純粹的 js,所以我將它們分成了兩類。 Vue & Jsx在render 中使用 jsx有了前面兩類寫法介紹的鋪墊,接下來引入 jsx 語法就沒有什么難理解的點了。 jsx 在 vue 文件中是這樣寫的。在 render 渲染函數返回值處書寫 jsx 替代 h 函數。書寫純 JavaScript 的 h 函數描述結構還是比較繁冗的,jsx 就是簡化了的h 函數寫法。
在 setup 中使用jsxjsx 和 setup 配合食用更加。在選項式風格中使用 setup,在 setup 中使用組合式 api,并且返回 jsx 書寫的渲染函數。
defineComponent 簡寫這個其實就是前面介紹過的 「defineComponent 傳入 setup」 函數寫法:這里的區別只是使用 jsx 替代了 h 函數。
自行導出 vNode 對象我們也可以自己將 render 函數執行一遍,然后將得到的 jsx Element 導出,和上一個示例「defineComponent 簡寫」是十分相似。但是這段代碼的缺點非常致命,它不支持接收外部傳遞來的屬性參數。
不要使用這種寫法。這里會提到這樣寫,只是因為和后面的「函數式組件(其二)」 寫法有關聯。本寫法與其它寫法都不同,其它寫法導出的都是 JavaScript 對象或者 jsx 對象,而這里我們則是自己執行了一遍渲染函數并得到了虛擬節點,直接將虛擬節點導出去。既然都已經把虛擬節點創建出來了,那自然無法接收 props。 defineComponent 的第二個參數如果 defineComponent 的第一個參數是 setup 函數,那么它的第二個參數則可以為組件的定義添加需要的選項,但一般除了補充 props 選項,不會再需要其它選項了(組合式 api 和 setup 的入參可以完全替代其它選項)。
直接在 vue 中使用 jsx這里 jsx 不再只作為返回值,而是直接被某處使用。它可以是被直接導出,或者用在 template 上。 直接導出 jsx 對象直接將 jsx 對象導出使用。比前面的寫法更簡潔,做法就是把 setup 里面的內容提到外面。這里需要注意的是我們導出的是一段直接的 jsx 對象(jsx Element),而不是渲染函數。
直接用在 template 上這種寫法可以幫助你在自身的組件內復用一些顆粒度更小的組件,它和 setup 語法糖的寫法非常接近,只是 User 變量可以作為標簽直接使用。
函數式組件(其一)你還可以將 User 寫成函數式組件,在本頁面內使用。但它不會將連字符屬性轉換為小駝峰寫法。這和「直接用在 template 上」的內容都是一樣的,它們都是為了方便在組件本身復用一些常用的組件。
如果你經常使用 tailwind,你可能就會知道什么情況下會出現小顆粒度的可復用標簽,比如,一個加了一大堆類名的 div 標簽。 獨立的 Jsx 文件以上介紹的所有寫法,都是在 jsx 定義組件我們需要新建一個 jsx/tsx 文件,然后只要保證導出的仍然是一個組件就可以了。有了前面的鋪墊,我們不難發現,這不就是去掉 script 標簽的選項式寫法嗎?確實!這是因為我故意在前面安排了選項式寫法的例子,所以過渡到這里完全沒有壓力!
我還是推薦套上 defineComponent:
同樣地,前面對于 defineComponent 不同方式的使用這里也都可以的。比如導出普通對象并在 render 或者 setup 中使用 jsx 等等。從 vue 到 jsx,區別只是省下了 script 語法塊。 vue2 選項式寫法+jsx。
導出普通對象:
函數式組件(其二)Vue 中支持的最像函數式組件的寫法。
該例和前面的「自行導出 vNode 對象」非常接近,這也是為什么即使后者存在不能接收參數的缺陷我也會提出來,因為二者都是使用接近函數式組件的寫法來描述組件的,但是在 vue 文件中并沒有辦法直接導出這個函數組件,而是需要自行執行得到vNode。而在 jsx 文件中卻可以將其導出,并且支持接收參數。 如果你需要為其定義 props,也不需要使用 「defineComponent 的第二個參數」為你提供什么 props 選項,而是直接在函數式組件的 props 、emits 屬性上掛載對應的配置。
相信習慣了 React 的 fc 的小伙伴,看到這里一定感覺倍感親切。然而 Vue 的 Jsx 終究只是 Vue 的 Jsx,它并沒有像 React 一樣存在那么多強大的 Hooks 和內置組件,而是僅僅只是 h 函數的便捷寫法。在語法上也和 React Jsx 存在諸多區別。和 React Jsx 相比,Vue Jsx 其實和自家的 template 更接近。不過 Vue Jsx 寫法的靈活性還是要比 template 模板高,但官方更推薦使用 template。template 更容易上手且提供了更好的性能優化,除非你想完完全全掌控組件的每一個細節,才需要jsx。 小結盡管本文提到了很多種寫法,但大多數寫法在大多數時候都是不會派上用場的,也應該不被派上用場。之所以列舉那么多寫法,主要的目的還是為了循序漸進引入 jsx 文件寫法和函數式組件寫法。 可以看出,Vue 的寫法本質上是選項式的。Vue3 在 Vue2 的基礎上引入了 setup 選項和 setup 語法糖,結合組合式 api 后,開發者可以將組件的大部分邏輯都維護在 setup 中,而不是 vue2 中割裂了邏輯的 data+created+methods 選項。 在此基礎上,setup 語法糖支持自動導出組件功能,為我們日常開發帶來了很大的便利。 但是除了使用 template 來表達我們的結構,我們也可以自己使用 render 選項并借助 h 函數或者 jsx 的力量來手寫渲染函數。這些都是在 vue 文件中完成的。 既然都不需要 template 了,那么 vue 文件里就只剩下一個 script 了(我們先忽略 style)。在 jsx 文件中,就允許我們直接書寫導出對象(仍是選項式的寫法),忽略script。 最后是 Vue 的 jsx 文件獨有的特性。它允許我們導出一個函數作為組件,我們稱之為函數式組件(fc,function component),這是 vue 文件和以前所有寫法所不具備的,外形與 React 相近。 總的來說就一句話,「Vue 本身仍然是選項式的,但是它現在還額外支持了在 jsx 文件中書寫 fc。」 個人看法使用哪一種寫法,主要看個人偏好。每種寫法在特定場景下都有它的好處和壞處。選擇哪一種并不重要。但是我還是提幾點個人建議:
為什么不推薦函數式組件的寫法,因為它需要寫在 jsx 文件里。如果你只是想通過 jsx 為你的組件增強某些功能,直接改造 vue 文件更加方便,并且不需要修改你引入文件的后綴( 當然以上只是我個人的小小看法。如果覺得有用,不妨動動小手點贊和收藏吧! 看到這里,如果你也想試試在 Vue 中寫 jsx,不妨看看這篇文章,分享了怎么在 Vue 項目中配置 jsx 環境,充分發揮 jsx 的優勢! 傳送門:【Vue3】對el-form進行二次封裝后,我的開發效率提升了3倍 - 掘金 參考渲染函數 & JSX | Vue.js 該文章在 2024/10/19 12:27:24 編輯過 |
關鍵字查詢
相關文章
正在查詢... |