後端自學兩個小時前端,究竟能做出什麼東西?

語言: CN / TW / HK

theme: vuepress

本文為稀土掘金技術社群首發簽約文章,14天內禁止轉載,14天后未獲授權禁止轉載,侵權必究!

又來給大家更文了,今天是微服務閘道器實戰的第六篇。

今天的內容比較偏前端一點,主要是給大家換換口味,畢竟學一個東西學久了就想學點新東西休息一點,俗稱換換腦子。

其實早就想學學前端看了,不過礙於工作繁忙,也可能是懶癌發作一直沒有成行,直到在做OKR的時候有些東西需要前端的支援,而我們又沒有多餘前端的時候,我就知道,我需要開始學前端了~

在往下講之前,我忽然想起來我有一位前端網友,在我們之前都還特貧窮的時候(現在升級到貧窮),時常會在一塊討論問題,有時候我會說你們前端怎麼怎麼樣,他就會非常反感,因為他覺得自己不是 front 而是 developer

雖然我被懟了,但是從心底我是同意他的說法的,開發者不應該給自己受限,我們大家都只是在做前端 or 後端這份工作而已,畢竟有的人招進來的時候是前端,現在連運維的活都幹呢,你說是吧?@CookieBoty

所以,本文的內容會夾雜前端和後端,前端的可以看看後端內容,後端的可以看看前端內容,換換腦子嘛~

1. Vue

我還依稀記得,三四年前剛學 Java 的時候還要學 CSS、HTML和JS三板斧,做後端工作三年後,我連怎麼操作 DOM 都忘記了,可能許多後端小夥伴也和我一樣,除了會 HTML 的一點標籤,其他前端相關的知識早就忘完了,這也是很多後端遲遲不願意接觸前端的原因,太費心力了。

所以在我決定開始學習前端的第一個問題就是,我應該先學什麼?

在我略微思考了三分鐘之後,我得出一個結論:我應該先學一個前端框架。

我知道任何一門語言的技術棧都是有一個龐大的生態在支撐的,前端所涉及的東西除了前端框架之外還有打包工具,依賴管理工具,ES6新特性(可能它已經老了,對我來說是新的),卷的狠的再來點拆入拆解瀏覽器等等等。

這些八股文和 Java 有的一拼,但是我知道我不需要學這些的所有東西,我要學的時候只有一個:用一個工具幫我做成一個東西。

所以,雖然我連解構賦值、和操作DOM都不會,但是這不妨礙我學前端,我要先選中一個前端框架進行熟悉,然後利用這個框架的生態幫我做東西。

扯遠了,說回正題,在兩三年前的時候,前端還是 Vue、React 和 Angular 三足鼎立,但是到今年 Angular 除了外企似乎已經用的不多了,所以我的學習目標就放在 Vue 和 React 這兩個身上了。

怎麼選,其實我是糾結的,最終我聽從好大哥@CookieBoty和眾多網友的建議,學了 Vue。

網上很多人都說 Vue 上手好、文件全,我感覺完美符合我的預期,再加上火影完結之後我就開始追海賊王了,尤大的 onepiece 起名方式甚合我意,所以我就開始學起來了 Vue3。

怎麼學呢?我想到了程式設計師的夢工廠某課網,找了一個教程來看,上面先教了我模板語法,又教了我單頁元件,最後又學了 Vue 路由系統,前後花費一個多小時,看了十幾節影片,我覺得我行了,就開始實踐了~

最終,三天沒寫完一個頁面。

2. React

Vue3 的難度讓我有點觸不及防,可能也是因為我沒有拋棄後端的程式碼習慣。

我習慣用 TS 定義好資料結構去接收值和處理值,但是我發現 Vue3 中的所有物件都是一個代理物件,當我嘗試將一個 Map 資料直接轉換為一個 JSON 字串的時候我發現不行,我也無法理解一個 Map 為啥不能在轉 JSON 的時候把裡面的 KV 帶上,還需要我手動轉換成一個物件然後再轉一次,我很苦惱。

我更苦惱的是,當我嘗試用一個數組物件迴圈生成某段模板的時候,我發現很麻煩,我感覺這不是我想要的前端,作為一個後端,我學了指令碼語言,但是它卻讓我感覺到很多的枷鎖在身上,這比我寫 Java 還困難。

此時我意識到,Vue3的上手難度和Vue2不是一樣的,這是一個成熟的前端框架了,它需要一個成熟的前端來操作,而不是我這種玩完就扔的二流開發。

當然,Vue 還是有很多好處的,從我可以看見的一點來說就是,ele-plus 這個元件庫是真的漂亮。

Vue3 玩不轉了,我就想換 React 了,再次來到某課網,找了個 React17 的影片來看,又花了我一個多小時,好在我已經有一些前置知識了,吸收起來還是蠻快的,學習的過程中,我覺得 React 給了我想要的東西:自由,指令碼語言寫起來的自由感。

在 React 中我不再拘泥於單頁元件,統統都是函式式元件,單向資料流也讓我更容易理解資料執行的方式,而且會 React 據說B格要比會 Vue 的高一點,這一切都讓我覺得轉 React 是正確的。

不過有利有弊,在我寫 React 的過程中,我發現我在用 Vue3 寫程式碼時候的問題就是 JS 獨有的問題,比如我前面提到過的 Map 轉 JSON 的問題,它不會因為某個框架就能讓我更舒服。

可能有的前端小夥伴會想:你為啥要用 Map?

因為 Map 更符合我這個後端的認知,某些不確定的多選引數我裝在一個容器裡面,然後序列化後給後端我覺得這是一件極其合理的事情,它符合我的心智模式,但是 JS 或者 TS 都沒有做到。

在使用 TS 的過程中,我幾乎沒有感覺到好處,TS 的型別檢查反而讓我覺得更不像指令碼語言了,這一點我覺得比後端 Kotlin 差很多。

雖然有種種限制,但是好在 React 這個框架並沒有讓我感覺到有什麼不適,反而是無縫銜接,我幾乎是上手就寫了。

最後總結一下我 React 都學了哪些東西才開始寫東西的:

  1. 使用腳手架安裝 react with ts。
  2. 宣告類元件和函式式元件:函式式元件是主流,類元件稍微看看就行,主要就是寫起來麻煩。
  3. 理解 render:render 其實就是通過執行元件程式碼生成一個HTML片段,然後掛載到DOM上面。
  4. CSS 模組化:通過 CSS 模組化,加樣式的時候會非常方便,懶癌患者直接在程式碼上加行內樣式也沒問題,玩的就是隨心所欲。
  5. State 和 props:state 是重點,它代表了元件中狀態,比如按鈕是否顯示之類的,props 則是不可變引數,由外部傳遞進來供元件使用。
  6. Hooks:Hooks 我一般只使用到 useState、useEffect、useContext這三個,它們分別代表了宣告狀態變數,宣告副作用鉤子和全域性資料傳遞。
  7. 路由:按照我的理解路由是通過佔位符和瀏覽器的錨點來完成的,通過錨點定位到指定程式碼,通過佔位符將元件程式碼生成到佔位符佔據的DOM處,當然這只是個人拙見,希望評論區大佬能給出更多細節。

學完上面幾項,我覺得你寫一個小的管理系統也是沒問題的,啊對了,說到管理系統,那必然要用到 http 相關的東西,雖然由 axios 珠玉在前,但是 fetch 用起來也還行。

最後,我覺得 React 的文件比 Vue 的文件強上不少,這句話希望 JYM 別噴我。

3. 元件庫

寫前端的過程中,想要提效,元件庫是必不可少的,我先後體驗了 Ant Design、Material UI、Semi Design、Arco Design。

最終在做專案的時候用了 Semi Design,因為它不用引入全域性樣式表就能按需載入,雖然我的好大哥告訴我 Ant Design 也可以做到這個效果,但是當時確實沒有實踐成功,還是我的功力太過薄弱。

從目前看來,我用過最舒服最方便的還是 ele-plus 可惜沒有 React 版本。

雖然元件庫是一個好東西,但是我覺得太過依賴元件庫是一件很糟糕的事情,當你要做的功能元件庫中有但是恰好達不到你要的效果時,就會很難受,怪不得很多人都要做一個自己的元件庫了~

比如 Semi Design,在我使用的過程中我其實很不喜歡它的按鈕效果,按鈕上面總要有一個底色:

image-20221109223738886

我想要一個無底色的圖示按鈕,但是 Semi Design 的圖示按鈕全部都是這樣的:

image-20221109224044778

可能這就是它獨有的設計風格問題吧,還有一些隨時可能遇到會違反自己的直覺的事情,讓我意識到,元件庫雖然不錯,但是過度依賴也為自己的擴充套件留下很多問題。

寫到這,突然就明白了為啥前端有時候會告訴我:” 這個效果我用的元件庫做不了 “,我心想你的頁面還不是你做主嗎,居然能讓元件庫把開發者給拿捏了,等我也被拿捏的時候,我彷彿理解了他當時的情況,原來我的頁面真不是我做主😟

4. 頁面效果

雖然我學前端只花了幾個小時,但是寫頁面卻花了好久的時間,大部分時間都在調一些樣式和排查錯誤,而且我還自己學了一手 Flex 佈局,做了整體的頁面佈局。

在有時候感覺元件效果不好的時候還自己寫了一下滑鼠懸浮的陰影之類的小效果:

image-20221109225102039

一套頁面做下來整體感覺還是不錯的,怪不得前端也被稱為互動體驗工程師了。

接下來給大家看一下整體效果,這是主頁面:

409866d6-104a-49d5-96fa-d06b14948022

我的這個閘道器控制檯總共分為兩個頁面:看板和路由表。

路由表就是上圖展示的這個,主要是把 Nacos 中的配置拉下來解析成陣列物件展示在表格裡面,然後在表格裡面可以進行編輯和新增,然後通過 openApi 同步到 Nacos 遠端去,這樣就不用手動去在一堆配置裡面改了。

這裡要小小的吐槽一下 Nacos 的 Api,它們的這種釋出配置居然是 Get 介面的,導致我要現在後端做一層包裝,不然資料量大了很容易被瀏覽器攔截掉,它們新版的 api 介面我也看了相關的程式碼,居然不是常用的 JSON 傳參,就此還和相關開發者對了一次線。

扯遠了,說回正題,我的編輯和新增頁面如下:

7bb8fc91-2926-4dd2-8eab-b64f598a30eb

看板則是使用閘道器做了一些流量指標的記錄,比如請求總量、日活總量、每小時線上人數、每小時請求人數之類的基礎指標,並且把它們做成了一個圖表的形式,有餅狀圖和折線圖:

4bfb2cdd-3c52-4711-af29-2d93d09908ed

當然,對我來說最重要的還是路由表的檢視頁面和新增編輯頁面,這幾個頁面花費了我最多的心力,而且頁面的資料結構比較複雜,做起來對我這個新手來說是有點吃力的。

值得一提的是,圖表是我做的最輕鬆的一個頁面,用的是螞蟻的圖示元件。

5. 後端

最後,簡簡單單說一下後端我都做了什麼吧。

由於這是後臺系統,所以我將它和閘道器分開,新建了一個 admin 專案來處理相關請求,但是呢?加上前端那我的閘道器整體就要有三個部署的服務了:閘道器 API、閘道器控制檯前端、閘道器控制檯後端。

為了節省資源,我通過外掛的方式把前端輸出的程式碼copy到閘道器後端這個應用裡面來,這樣閘道器後端和前端的程式碼就可以打包在一個應用裡面了。

其具體做法主要就是在後端應用編譯打包的時候用外掛先編譯前端,然後對前端資源進行復制,具體外掛如下:

<build>        <plugins>                 <!-- 呼叫npm命令外掛 -->                <plugin>                    <groupId>org.codehaus.mojo</groupId>                    <artifactId>exec-maven-plugin</artifactId>                    <version>3.0.0</version>                    <executions>                        <!-- 先執行前端依賴下載 -->                        <execution>                            <id>exec-npm-install</id>                            <phase>package</phase>                            <goals>                                <goal>exec</goal>                            </goals>                            <configuration>                                <executable>npm</executable>                                <arguments>                                    <argumnet>install</argumnet>                                </arguments>                                <workingDirectory>../admin-ui/</workingDirectory>                            </configuration>                        </execution> ​                        <!-- npm打包 -->                        <execution>                            <id>exec-npm-run-build</id>                            <phase>package</phase>                            <goals>                                <goal>exec</goal>                            </goals>                            <configuration>                                <executable>npm</executable>                                <arguments>                                    <argumnet>run</argumnet>                                    <argumnet>build</argumnet>                                </arguments>                                <workingDirectory>../admin-ui/</workingDirectory>                            </configuration>                        </execution>                    </executions>                </plugin> ​            <!-- 把 react 編譯後的 dist目錄下的所有檔案拷貝到resource目錄下 -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-resources-plugin</artifactId>                <executions>                    <execution>                        <id>copy-static</id>                        <phase>validate</phase>                        <goals>                            <goal>copy-resources</goal>                        </goals>                        <configuration>                            <outputDirectory>src/main/resources/static</outputDirectory>                            <overwrite>true</overwrite>                            <resources>                                <resource>                                    <!-- 因為react打包目錄在專案根目錄,所以從這裡複製 -->                                    <directory>../admin-ui/build</directory>                                </resource>                            </resources>                        </configuration>                    </execution>                </executions>            </plugin>        </plugins>    </build>

平時除錯和開發的時候依然可以像前後端分離那樣,啟動一個後端服務和一個前端服務,只在最終打包的時候打包在一塊,所以這種方式哪怕是讓一個專職前端來幫你寫頁面,對他來說也是無感知的,不需要關心後端幹了啥。

6. 最後

好了,今天的文章就是以上這些內容了,本篇主要內容沒有涉及到太多技術(當然也分享了一個前後端聯合打包技巧),主要是分享了我自己在為專案寫一些前端程式碼的心路歷程,相信現在有很多工程師都對全棧很有興趣,我也是想借此告訴大家,其實前端並沒有太難學,幾個小時完全可以上手寫頁面了。

Just do it.

最後,如果大家覺得本文還不錯的話就可以點贊以示支援,對前端這塊內容有更好的建議和說法也可以在評論區留言,我會積極對線的,下篇見。

本系列其他文章:

「微服務閘道器實戰一」SCG 和 APISIX 該怎麼選?

「微服務閘道器實戰二」SCG + Nacos 動態感知上下線

「微服務閘道器實戰三」詳細理解 SCG 路由、斷言與過濾器

「微服務閘道器實戰四」隨意擴充套件定製的分散式限流,看看我怎麼做

「微服務閘道器實戰五」做網關係統, 99% 會被問到這個功能