顯示具有 前端 標籤的文章。 顯示所有文章
顯示具有 前端 標籤的文章。 顯示所有文章

2026年3月13日 星期五

V8引擎運作原理與垃圾回收機制

🚀 深入 V8:從編譯原理到記憶體回收的效能實戰

今天在面試中踢到了鐵板。原本以為只要會寫 JS、會處理資料就好,沒想到面試官直接往底層挖,問我 「V8 引擎怎麼運作」 以及 「記憶體洩漏如何精確定位」

當下沒答好,回頭翻了資料才發現,這不只是理論,這跟我們在高併發情境下寫出的程式碼品質息息相關。這份紀錄將 V8 的運作機制與監控實戰整理出來,當作以後的防守指南。

一、 V8 引擎運作流程:從原始碼到機器碼

V8 引擎(Chrome 與 Node.js 的核心)不只是一個直譯器,它是一個強大的 JIT (Just-In-Time) 編譯器。

  1. 解析 (Parsing):將 JavaScript 原始碼轉化為 AST (抽象語法樹)

  2. 解釋 (Ignition):解釋器將 AST 轉為較低階的 Bytecode (位元組碼) 並立即執行。這保證了程式碼能快速啟動。

  3. 編譯優化 (TurboFan):監控程式碼運行(Profiling),如果某段函式被頻繁呼叫(熱點程式碼),編譯器會將其轉換為優化過的 機器碼 (Machine Code),效能直接噴發。

  4. 去優化 (Deoptimization):這是效能損耗的元兇。如果你原本傳入 Int,後來突然變成 String,V8 會發現之前的優化作廢,被迫拋棄機器碼,退回到位元組碼。

    💡 心法:盡量維持變數型別的穩定(Monormorphic),能幫助 V8 保持優化狀態。


二、 V8 垃圾回收機制 (Garbage Collection)

V8 將記憶體分為 新生代老生代,就像是公司的「實習生」與「資深員工」,管理制度完全不同。

1. 新生代:Scavenge 演算法

  • 特性:存活時間短、回收極其頻繁。

  • 機制:空間平分為 FromTo。新物件先放 From,回收時將還活著的物件複製到 To,然後清空 From 並將兩者角色對調(翻轉)。

  • 晉升 (Promotion):撐過兩次回收還沒死的物件,會被升遷到「老生代」。

2. 老生代:Mark-Sweep & Mark-Compact

  • 特性:存活長、空間大。

  • 機制

    • 標記 (Marking):從根節點(如 window)出發,標記所有還有人用的物件。

    • 清除 (Sweeping):把沒標記到的「垃圾」清掉。

    • 整理 (Compacting):把分散的物件推擠到一起,清出連續空間,避免「記憶體碎片」導致大物件放不進來。


三、 記憶體洩漏 (Memory Leak) 診斷實戰

當物件不再需要,卻仍被「根節點」間接引用,就會導致 GC 無法回收。在高併發系統中,這會演變成災難。

1. 常見的洩漏殺手

  • 意外的全域變數window.data = [...]

  • 被遺忘的計時器setInterval 沒清掉,裡面的閉包會一直抓著外部變數不放。

  • 脫離文件的 DOM:JS 變數存了某個按鈕,但該按鈕已經從網頁刪除了,這顆按鈕就成了「殭屍節點」。

2. 實戰定位:三點定位法

當你感覺頁面越來越卡時,請打開 Chrome DevTools:

  1. 快照 A:初始狀態。

  2. 快照 B:執行操作(例如重複開啟彈窗 10 次)。

  3. 快照 C:再次執行操作。

重點:使用 Comparison 模式比較 B 與 C。如果某個物件在 B 到 C 之間持續增加且沒消失,那 99% 就是洩漏點。


四、 程式碼優化建議:寫出對 GC 友善的 Code

  • 優先使用弱引用:如果只是想關聯資料,請用 WeakMapWeakSet,這不會阻止 GC 回收該物件。

  • 手動斷開引用:處理大型數據(如 5MB 的 JSON)後,用完記得 data = null

  • 生命週期清理:在 React 的 useEffect return 或 Vue 的 onUnmounted 中,養成習慣清除 Event Listener 和 Timer。


結語

面試官問這些,其實是在考你:「當系統在高載壓下效能下降,你有沒有科學的方法去排查?」

雖然平常寫 Code 不一定會天天看 AST,但了解 「去優化 (Deoptimization)」「記憶體碎片化」 的概念,能讓我們從寫出「會動的程式碼」,進化成寫出「高效的程式碼」。

前端高併發情境範例

🛑 前端甘我事?高併發情境下的前端防禦指南

今天面試被問到一題:「高併發你怎麼處理?

當下我心裡的 OS 是:「高併發不是後端要處理的嗎?」結果講完後對方顯然不滿意。事後回想才發現,面試官要的不是背誦技術名詞,而是情境設計能力

雖然這些東西真的遇到時,查一下文件半小時就能寫出來,但為了應付那些「愛問」的公司,我們還是得把這套「前端流量削峰術」內化成自己的邏輯。這份指南紀錄了前端在高併發情境下的核心任務:流量削峰壓力隔離


🎯 核心設計原則:別讓請求直達資料庫

在高併發情境下,前端的目標不再只是把畫面畫出來,而是要當一個聰明的「過濾器」,透過以下原則防止後端崩潰:

  1. 動靜分離:不常變動的 HTML/JS/CSS 與素材(圖片、影片)通通丟給 CDN,別讓這些請求去佔用應用伺服器的頻寬。

  2. 請求削峰:利用緩衝、延遲或合併請求,把尖峰流量「平滑化」。

  3. 客戶端降級:系統快不行時,主動關掉非核心功能(例如:自動補完搜尋、即時進度更新)。


🛠 三大代表性情境範例

1. 電商秒殺/搶購系統 (Rush Sale)

挑戰:數百萬用戶在同一秒瘋狂點擊按鈕。

  • 按鈕防抖與置灰:點擊後立即禁用按鈕,防止使用者因為焦慮而產生重複請求。

  • 靜態資源預熱:活動開始前,利用 Service Worker 預先下載好活動頁所需的資源。

  • 排隊等待機制:發送請求後進入輪詢或 WebSocket 狀態,顯示「排隊中」而非直接報錯,安撫用戶情緒。

  • 驗證碼與異步化:透過驗證碼強制拉長操作路徑,人為分散瞬間的請求壓力。

2. 大數據流與無限捲動 (Infinite Scroll)

挑戰:快速滑動產生大量 API 請求,且大量 DOM 節點導致瀏覽器卡頓。

  • 虛擬列表 (Virtual List):只渲染可見視窗內的節點。即使有 10 萬筆資料,DOM 永遠只維持 10-20 個,保證瀏覽器不崩潰。

  • 分頁請求與預加載:設定滑動閾值,在快滑到底前才拿下一頁。

  • 請求取消 (AbortController):當用戶切換分類或滑太快時,果斷取消過時的舊請求。

3. 直播間海量彈幕 (Live Streaming Chat)

挑戰:數萬人同時發言,頻繁的 DOM 更新與網路通訊會讓頁面直接當掉。

  • 彈幕池緩衝 (Buffer):不要收到一則就畫一次。建立緩衝池,每 500ms 批量渲染一次。

  • 頻率限制與過濾:前端根據等級篩選訊息,或限制本地發言頻率。

  • Canvas 渲染:針對海量彈幕,放棄 DOM,改用 Canvas 繪製以追求更高的幀數(FPS)。


💡 技術手段總結清單

技術手段解決的問題應用範例
CDN / Edge減少伺服器頻寬壓力全域靜態檔案分發
Service Worker離線快取與預加載秒殺頁面預熱
Debounce / Throttle過度頻繁的觸發搜尋框、視窗縮放
Request Batching減少 HTTP 請求數量點讚數合併計算

📝 結語

繞了一圈才發現,前端在高併發裡的角色,說穿了就是:「想盡辦法防止伺服器爆炸」

透過在前端攔截無效請求、合併必要請求、優化渲染效率,我們可以把原本會壓垮後端的「海嘯」,變成一波波平緩的「浪潮」。早說嗎,原來前端也要當保全啊!==


希望這份紀錄對下次面試有幫助。如果你有遇過更奇葩的情境,歡迎跟我分享!

2026年2月24日 星期二

HD鬼故事N+6最終章

看標題應該想得到,只是沒想到來得這麼快。


就在過完年的第一天,小弟我就被火了。這故事怎麼開始的呢?就讓我娓娓道來。


這次故事接著第五集的後面開始。那位新進(要取代我的)工程師(後面就叫他新主管吧),在大概 review 完當時的專案之後,向公司提出他需要一個半月來改善目前的狀況。


我得知這個消息時,心中還暗自嘲笑:以公司高層那種急躁的程度,應該不會接受這一個半月的空窗期吧?但沒想到小丑竟然是我自己。上面不但答應了,而且這一個半月真的沒有任何動作,就安心地讓他們慢慢看、慢慢修。這期間幾乎看不到有任何程式碼上版,整個專案就這樣放空了一個半月。


在這個同時,我也沒有閒著,我因為長時間處裡這新專案,導致舊專案累積了大量的工作,另外兩位負責的同事加我協助處裡。我同時還要到處支援其他專案(沒錯,我們公司還有很多其他的小專案,也就是從那位逛街被 fire 的學姊那繼承下來的)


至於這個重構專案,就交由那兩位新進工程師主要負責,看著他們就這樣爽過了一個半月。而且最聰明的一點是:那位新主管,在這一個半月當中就會剛好通過試用期。這幾乎是保證他能通過試用的條款。


這一個半月基本上很快就過去了,也沒見他們提交什麼成果。我想他們做的最大貢獻,就是把整個專案進行細小功能的拆分上trello。這一個半月幾乎沒什麼建樹,UI一樣被開一大堆,BUG 一樣被開一大堆啊......


最後還是回歸到之前的開發模式:

1. 工程師負責修理

2. 進行測試、測試、再測試

3. 產生並返回 bug

4. 工程師再繼續修復

......


一樣啊,只是因為卡片變小了,所以不會有為什麼被開這麼多bug的錯覺,但這問題應該要算PM頭上啊!!!!!然後這個新主管通過試用期時,公司竟然完全沒有詢問過我這個現任主管的意見!!!!!唉~算了,反正這就是他們想要的結果。

這個事情一直到大概一月中的時候,我那邊的專案忙到一個程度了。這時候發生了一件事情:


這個新主管突然生了一場大病。其實我們身為工程師,看卡片(Task card)和程式碼大概都感覺得出來,他到後期有點疲倦,甚至開始擺爛。我是怎麼看出端倪的呢?他禮拜三請病假,禮拜四沒請假,禮拜五又請病假,說他真的撐不下去了。


我想說如果你禮拜五嚴重到沒辦法工作,那禮拜四肯定也沒辦法,那你禮拜四不是白嫖嗎;再回去看他上傳的內容(Commit log),那個禮拜他沒上任何 Code,等於擺爛了一週,白嫖一週薪水。我想,專案不能順利完成總不能怪到我頭上吧?再者是他擺爛成這樣,公司都看不到嗎?


在這個時間點,因為原本一月底專案要趕著上線,PM 終於意識到進度真的不行,就請我回來支援重構專案(啊人員是你們親自調度的,這也應該算PM的鍋啊)。其實早已在一月初,我手邊的兩位同仁已經有足夠能力應付舊專案的功能開發,當時我反而沒事做。


而我一直去詢問那位新進主管,問他重構專案有沒有需要幫忙的地方。一連問了兩個禮拜,他都回答「沒有」,所以我那段時間等於放空了兩個禮拜。


之後發生了一件更搞笑的事情,那位 PM 到處去問人知不知道我在幹嘛。他問遍了所有人,甚至問到財務都來問我底下的工程師。但問來問去就是不來問我本人。


我組員也反問他:「為什麼不直接去問本人?」


結果那位 PM 回覆:「這是我個人想要了解他在做什麼,好安排進度,不是上面的意思,我怕直接問他,他會多想。」


你知道嗎,我此刻信以為真了。


總之一月初,我被要求要開始支援專案,我跟另外兩位同仁把舊專案的任務全部完成,就投入這一個專案中。記得當時有新增 10 個任務,我們五個人,想說一人一張2run,肯定可以在月底就跑完,但最後結果是我一個人就完成了 6 張。而且 bug 超少。我想說這應該也是我的加分項。論規模,致少也是其他人的三倍


接著,事情來到了二月初。二月初的時候,這位新進的工程師打電話給我。他跟我說,其實早在一月中時,PM 就曾問他:「要讓他(指我)留到什麼時候?」


我聽了覺得超級傻眼。這位新主管現在明顯在擺爛,難道你們都看不出來嗎?竟然還反過來問他要讓我留到什麼時候。


當時那位新主管跟我說,這幾個月運作下來,他也知道這間公司很有問題,所以他不太想接主管。我聽完後表示理解,但基於保護團隊的立場,我建議他要跟 PM 講清楚,一方面也是為了保護我自己,你大不了是一走,但一次走兩個人對團隊很傷。


我的私心是:如果他真的不想接,或許我就可以留下來繼續接手。(但我事後驗證他根本沒有說,但也沒有差了,後面會講),接著事情就發生了。


   因為他當時也不想善後,所以希望讓我留得越久越好。當時開出的日期是一月底,但他跟我提這件事時已經是二月初了,我就想說這一關應該是過了,公司應該有看到我的努力。


   接著開心過尾牙,然後接著過年。那過完年,最大的轉折就開始了。開工第一天,早上我還在處理自己的私事,正中午想說要開始辦正事了,就接到財務的訊息說要通電話,時間還挑得真好。我當下就警覺到似乎不太妙,果然是收到要資遣的消息。


對方還詢問我知不知道被資遣的原因。我當然不能說是因為我知道上面很討厭我,所以只回說不知道。他接著說:「你去年出了很多包巴拉巴拉,所以公司找了人要來取代你。公司當然也想過要不要給你機會轉為一般工程師,但你自己想想,公司給了你多少次機會,你都沒有好好把握。」


我心裡的 OS 是:我一個人單刷六張卡。先不說主管到底要不要寫 code,光是效率,我就不知道你們到底有什麼好說嘴的,而且我一直有去要工作啊,是他(新主管)不給,幹又算我的了。但,既然木已成舟,我覺得也沒必要跟財務爭辯,畢竟他也只是傳話的,並非決策層,就想說算了、接受吧。


理所應當我就把手上的所有任務和資料全部交接出去,想說應該就沒我的事了。


但我想到我的假還剩下一大堆,而且他通知我只做到月底。要知道那天已經是 2 月 23 號中午了,這個月只剩下四個上班日,等於我只剩下三天半的時間可以找工作,不然就會進入待業狀態。


我覺得這件事真的很扯。他說老闆是為了不破壞我過年的心情所以才現在講,但當年那個台灣主管被 fire 時,至少還給了一個月的時間交接並讓他找工作。現在他媽的只給我三天半,我真的不知道能幹嘛。我想說好聚好散,接下來三天也不打算跟公司請好請滿,就意思意思請了一天假。趁著這一天,我跟老婆約好去看電影。順帶額外推薦一下,《陽光女子合唱團》真的大推,絕對能治好乾眼症。


回到主線,在我去看電影的時候,手機訊息就開始狂跳。在關靜音之前,我看到他們決定在這個時間點讓專案上線。


.....本來想說點什麼,但算了,反正他們也沒打算尊重我。我身為這個專案最初的創作者與主管,負責整個前端維運的部分,他們卻完全不不在意專案的穩定度了。既然如此,我也沒什麼好說的,就讓他們自己去處理。


我把通訊軟體全部設為靜音,過了一整天舒爽的日子。直到 2 月 25 號,也就是今天,通訊軟體裡的訊息依樣狂跳。我仔細看了一下,原來不知道是怎麼上版,舊專案與新專案竟然同時並存。老闆一開始開到舊專案,還在群組裡罵人,質疑為什麼跟測試機不一樣,開始標罵。


這是維運的部分,前端工程師的他們都沒處裡過。我想說畢竟還是多年戰友,就小小幫了他們一下。接著更讓我傻眼的是,線上被開了多達 18 個 bug。我想說這件事情你們測試測了這麼多天,營運也測了這麼多天都測不出來,一定要等到上線之後才噴出 18 個 bug?我覺得這件事真的他媽的有夠掉詭。


然後那位不想接主管的新主管呢?繼續神隱,沒有大咖CUE他就不干他的事~


我前一天晚上還跟同樣被 fire 的一個 PM 聊天,他就說在這間公司發生這種事一點都不意外。


在這樣一間營運至上的公司裡面,他們根本不了解技術的價值,甚至連維持專案穩定度都不在乎。如果覺得薪水發太多,你 fire 新人也就算了,居然連主管都 fire。只能說這一切的發生都不意外,也確實反映了這間公司那些大佬的主觀感受,反正在這間公司:


1. 軟體操作問題:

   當他們正在操作某個軟體,只要出問題了,肯定都是系統創作者,也就是前端要負責。

   (a) 網站突然掛了,是前端要負責

   (b) 資料跑不出來,是前端要負責

   (c) 跟UI團隊溝通不良或溝通激烈或照著做出事,只要有前端在,就是前端的錯


2. 測試與品質問題:

   如果測試人員自己測太慢、測不完,也會說是前端丟出來的程式碼品質不好、沒有經過自測,最後還是前端的錯。

3. 開發速度與討論參與:

   (a) 如果程式寫太快,肯定是因為功能給得太簡單,這被認為是應該且正常的。

   (b) 參與討論時,如果你給太多建議,就你意見最多、都是你的毛;但如果你不講話全盤皆收,又會覺得你絕對都沒在做事情。


總而言之,千錯萬錯都是前端的錯。我覺得也差不多夠了。

這些事情之後都與我無關了。「HD 鬼故事」也不會再連載,因為我也畢業了。感謝大家長時間以來的支持,HD 的故事就在此落幕,謝謝大家。


補充一件事,我原本以為他們會忘記我的電腦是公司提供的,我就可以繼續爽用。想當初在要電腦時我還跟PM開玩笑說可不可以兩年後電腦送我,他也回答應該可以吧,殊不知.....


在今天下午財務理所當然他詢問了我要收回電腦的事情,問說什麼時候可以來跟我拿電腦。因為這台電腦平時也是我的日常機在使用,我就想問她說能不能再緩個幾天讓我備份一下資料。結果他就開始訓話模式說:「為什麼公司的電腦裡會有你的資料?你知不知道公司電腦是不能私用的......」;啊是說後來CEO也沒啥意見,他就沒說什麼了


關於這位財務,記然講到這份上了,就補充完整吧

就在去年員工旅遊時,我突然覺得他對我特別冷淡。原本還想說是不是我的錯覺,但我發現公司所有帶小孩的家庭中,他是會去主動關心小孩,跟小孩玩的,但唯獨不會跟我們家小孩主動互動,通常都是不小心同桌或對到的時候,才會有那麼一點點必要性互動。

而且在平常與公司的相處中,只要我們受到公司好處,例如聚餐,發薪水,他就會私底下提醒我們要謝恩、要感謝公司。這導致我們公司產生了一個很獨特的文化:收到薪水後,要在群組裡面發「感謝公司」文。

他真的是一個非常會做人的人。可能這就是他得寵,人緣好到成為情報集中站,且跟大老走這麼進還可以活到現在的原因吧。或許去年員工旅遊時,他早就接到不少關於我的消息,知道我已經被公司討厭了,所以對我的態度才變得冷淡吧。

當然這純屬我的個人猜測。我自認應該沒有得罪他什麼,剛進公司時,常跟他抱怨,但也不是真的有意要吐槽他,我吐槽的是公司制度。可能是我第一次員工旅遊時,因為他沒搭上飛機,最後請他幫忙改機票、改行程,然後他幫我買伴手禮(お土産),主動補貼我費用,我竟然都真的接受了,且沒有任何表示,因此得罪他吧?不知道。

先說我沒有不喜歡他,反倒很感謝他的照顧,不管是出於義務或是自願,我都領受他不少照顧。

.......總之就是⋯⋯

讀者以後找工作如果公司讀音是HD開頭的,特別你應徵的是前端,請三思~


DLC

就在我歸還 Mac 的時候,詢問了一下我原本的組員,問他有沒有在公司聽到什麼傳聞。他說沒有,只是暫時沒有前端主管。


我接著問說,那原本要取代我的那位前端主管呢?他說對方似乎前一陣子被投訴了,公司應該也不會再讓他擔任主管。

恩.....果然是這樣,就算沒有要升他,但也絕對沒打算要留我。


我之前有去聯繫一位剛過試用期就被資遣的前員工,詢問他有沒有領到資遣費。他說有,領了兩天。

今天我也領到薪水了,然後確實比平常多出一些金額,算了一下,也大概是我兩天左右的薪水。

重點是:
1. 他才剛過試用期,就能領到這個數字。
2. 我在這邊可是做了快三年啊。

暨給三天半找工作期限後,這個資遣費真的是廢到讓我笑出來。

話說這兩天我開前公司專案看到新的 commit,發現前同事還在三更半夜上 code。

我突然想到,當初在我接主管的時候,有一個口頭條款:我跟我的組員不進行非必要的加班。

也確實這段時間加班情況銳減,也或許就是因為這一條,讓他們最終決定要把我砍掉。

恩,沒啥幫助,就是想講講~

DLC2-遣散費的真相

一週之後,前同事來關心我找工作狀況,我順便吃了點瓜,接著講到遣散費,然後他給了我一個驚人的事實

所以多出來的280U,是發薪當天匯率剛好突破0.145,所以平常薪水乘以0.14,這個月變成乘以0.15.....就這樣,所以根本不是遣散,是人人都有的匯率紅利啊......好吧,所以要砍我的原因又多了一個,成本上升了!!

後來想想,大家平常對這間公司幹得要死,但偏偏流動率又超低,這算不算是一種有毒的關係呢....

2024年7月15日 星期一

HD鬼故事N+2集

今天故事比較短,但也是挺魔幻的

我們都知道祖國人沒有休假概念,所以假日來找你碴也是正常發揮,更何況前端又是個吃虧的單位,畢竟資料出不來,前端的錯!操作卡卡的,前端的錯!今天眼袋怎麼這麼腫,O的一定又是前端的錯!

事情發生在週日傍晚,一個本來好好的三方遊戲突然就會報錯(會說本來是因為工程師後來發現這段code已經有8個月沒動過了,至於8個月前是否是好的,那可能是另一個更魔幻的故事,你不要知道太多,對你人生比較好)

經過工程檢查後,因為api pending超過四秒連線被切斷了,在跟其他相同功能的專案交叉檢查,結果發現一個驚人的事實,兩個站打的api竟然不同支,這就很玄了喔!

於是工程師在群組裡回報了這件事,無論是api pending跟不同支api這兩件都需要後端協助查詢。

搞笑的來了,運營也不知是不是想幫後端說話,他說:想必是兩個站線路不同,因此需要打不同api吧!

半個多小時後,後端才慢慢打字回覆:我不確定

運營:....

(我默默覺得有人臉很腫)

然後......然後就隔天上班了!甚至都隔天下班了,這件事還沒有下文,我你個去!當前端好欺負是吧!!前端出事就要馬上處理,後端出事就可以讓人拖了又拖拖了又拖的嗎!保安!

2023年12月9日 星期六

針對某公司前端面試做個紀錄

前言

我絕對不會說我去面試K什麼M什麼體什麼X的公司,整體面試感受不太好
HR不夠積極跟友善,面試前一小時臨時改面試時間,面試開始前八分鐘才叫我提前五分鐘到,結果面試官也是準點進來,然後面試官整場用我不熟悉的語法(純粹大陸用語跟台灣用語不同)來問問題,所以很多問題我也只能重複進行確認,然後問完話也沒有要讓我提問,說沒有問題了匆匆結束會議,然後也沒有打算讓我跟HR二面,就在你問我答,足足問了22分鐘結束面試....好吧,非常有效率給你一個讚!

內文

針對被問幾個我印象比較深刻或回答沒這麼好的問題進行一次紀錄

1. 輸入網址到畫面渲染,中間過程如何....
又是這種沒有標準答案的鳥問題

2.vue v-for跟v-if可以一起用嗎?
我回答可以,對方接著問誰先誰後,我說太久沒用我忘了,試過就知道(但對方顯然對這答案不買單)
最近去翻筆記,確實是可以,然後在底層v-for會先執行再執行v-if

3.js的垃圾回收機制是什麼?
老實說我會寫不會記憶體洩漏的程式,所以從來沒想過這問題,所以我去查一下
答案是沒有被引用的物件會被瀏覽器回收,所以如果有物件相互引用就會造成記憶體洩漏(memory leaks)

4.Promise的狀態有什麼?
又是一題會寫但不知道答案的問題,我用這麼久還沒遇過有人問這問題,去查一下答案是
pending執行中
reject操作失敗
resolve操作成功

5.react useRef可以用來幹嘛
記錄變數,指向DOM

6.react useState, useRef,當state更新但畫面沒有更新,可以透過ref回復到先前狀態嗎?
我回答:理論上是可以啊。對方突然很驚訝回我:可以!那要怎麼做。我:就看你邏輯怎麼寫吧...他的回答讓我感覺我的回答是錯的,這就是沒有程式碼在那邊盲問的缺點,另外我倒是很想問你是怎麼做到更新state然後畫面沒有更新

小結

其實他還問了很多,但大多我都會答,應該是都對拉,雖然最後我被打上T3的等級(對方要T4),然後被大砍期待薪資,不過貴公司996的工作時數我就算沒被砍我也大概率不會進去(是真的996),然後工時打在JD上我以為是常識,只能說我真的孤陋寡聞,還是在我面試完後拼命追問HR才告訴我。只能說這間公司除了遠端,其他沒有任何一點吸引我的地方

2016年10月20日 星期四

前端最近到底在紅些什麼??

前言:

這篇文章我希望可以快速帶大家了解一下近幾年前端發生的變化,那怕只有一點點,希望大家可以整理出一些頭緒,因為小編真的很不會教學= =

這篇文章全程將以Vue2.0(以下簡稱Vue)做為開發範例,依照之前我跟團隊提起這個名詞的經驗,很多人會問說這是啥洨,為什麼等問題,這很正常,小編會一一跟大家做解答。不過小編所學有限,大家想要有更詳細的了解,還是自行上網google一下比較好

在本文的一開始,必須重申,本篇的重點不是要教會大家一門技術,是希望帶給大家一些觀念,告訴大家現在前端正在流行的開發方式,只是藉由 Vue這個框架來達成這個目的。因為小編在摸完這麼多框架後發現,概念是一樣的,只是用的方法與語言不一樣。那既然是這幾年的新技術,那不免俗地有一拖拉庫的名詞必須解釋,那我們開始吧。


究竟什麼是Vue呢?

Vue(讀音聽起來像是view),這是一套前端JS的微型框架,比起有名的React & Angular算是後起之秀,他的開發者 尤雨溪,沒錯,看到這名子就知道他是個非常牛逼的中國人,他在美國讀研究所,畢業後曾任職於GOOGLE,不過現在已經離職(推測他的年紀好像跟小編差不多就是了),整個框架主打輕量化,所以每個套件都各司其職,因為程式全部由他一個人開發,所以修BUG也非常快,檔案非常小,相對加載速度也就快,且沒有相依。據官方數據,Vue在render的效能上是遠超過React跟NG2的(僅限2.0)。

隨著日漸穩定,也推出了 VueRouter(Router) & Vuex(Flux),甚至是 Vux(針對ui進行操作的涵式庫) 等套件,Vue日前幾乎跟NG2差不多時間推出了2.0,但不同於NG>NG2幾乎就是個打掉重寫的工程,兩個版本相似程度高達90%,甚至推出了升級工具 "Vue migration helper",裝完套件後,只要下一行指令,就可以照著他給你的提示一一做出修改,實在時非常便利。

小編之所以選擇 Vue的原因,是因為它開發模式偏向於NG(注重model),但他入門程度甚至比React還要低,而且非常低耦合,跟任何框架在一起都可以運作,也可以在專案開發中隨時導入,不一定要侷限於SPA或模塊式的開發。然後對於model的控制,你可以隨時改變model,甚至用第三方程式去改變都可以(例:jQuery ajax),自由度相當高。所以小編用完有點回不了頭。

Vue還有個最大的優點,因為作者是中國人,所以文件都是中文版!!!!(我葳葳中華,堂堂炎黃子孫,憑什麼叫我去學番邦語言!!),不過作者還是會先推出英文文件,才會逐漸翻譯成中文就是了。(人家畢竟在GOOGLE待過咩~是有世界觀的男人~)

官方說法,有基礎的工程師都可以在三天之後駕馭這套框架大半,可見這個框架真的不難,本篇重點是希望藉由這套框架讓大家知道這些年前端流行的開發趨勢,所以在環境架設開始之前,還有幾個技術名詞要了解一下

二話不說先附上官網


為什麼不選React or Angular2?

針對這三套框架的比較網路上文章一大堆,硬是要講原因就是

第一:vue夠簡單,隨時可以上手,輔助套件也相當充足穩定了現在

第二:相較React的learn once, write anywhere的jsx語法,專注於model的vue跟ng2寫法上算相當直覺

第三:它夠快,網路上也有很多效能比較的數據,大家可以自己GOOGLE看看。

第四:相依性超級低,我寫不下去的時候隨時可以回到jQuery繼續開發,等我哪天心情爽了之後再改回來。

 第五:更新速度也夠快,因為程式全部是作者一個人包,所以他承諾修BUG速度絕對比GOOGLE團隊修BUG速度快上許多(大家使用上有問題也可以去github上面反映issue,作者曾嗆angular2上面的 issue太多且很難關閉,另外,事實上有個團隊在維護拉,所以大家不用怕尤大如果萬一怎麼辦之類的事情發生)
 

它唯一的缺點:社群依然不夠龐大,使用者相較下是比較少的,在我今天介紹之前有人有聽過Vue的嗎?光看FB上 ReactJS .vs. Angular JS User Group Taiwan .vs. Vue.js台灣 三個社群人數比例是8000:5000:2000,React支持者一大堆我也不知道為什麼,明明就很難寫啊!!人數多少的影響應該是提問得到答案的速度,我初估大概差了五倍吧,不過都會在一天之內得到答案,所以都還可以接受。而且 Vue社群人數少,所以很團結跟友好,你有問題都會非常熱心回答(好吧~小編曾在ng社群提問被直接忽視= =)。另外你上百度發問還時不時會遇到作者出來幫你做專業的解答,作者在身邊,感覺就好像志玲姊姊坐在你隔壁上班,好像很厲害!(從小編撰寫這篇文章,人數只有1500至今短短兩個月,人數已上升了500,不塊是未來的新星)

就算你上面幾點通通都不認同,也沒有關係,小編就是愛用 Vue,你可以咬我,或者右上角有叉叉,君子請自重阿~~


那會碰到那些技術名詞呢?

Component:

大家可以把網頁上的任何一個tag都視為是一個元件(包含內部的其他子tag),至於這個元件要大到多大,要小到多小,並沒有明文規範,需要開發者憑經驗去判斷這個元件有沒有"必要"被寫成元件而已。
大家可以用mvc的技術去想像,這就像view裡面的layout一樣。

另外,在 Vue裡面的component跟ng2的component很像,有自己的html, css, js,只是它全部都寫在一起,並給予它副檔名為.vue的檔案,你會說這是什麼沒看過, 沒關係,你看不看得懂無所謂,不過webpack看得懂就好了。在檔案數量上,小編也比較喜歡 Vue的編制,不然ng2一個comonent就三個檔案,加上測試檔就四個了,這還讓不讓人生存阿。


模塊式開發:

為了避免所有程式碼都寫在同一頁,所以可以藉由 import 或 required 把原本要開發的程式拆成許多小塊(component, store.....)後引入,但browser 是看不懂 import 的,所以需要藉由 Browserify or systemJS or webpack or 百度的fis 和 支付寶的spm ......等套件做預處理,所謂預處理就是在borwser 讀取頁面之前,先做的處理。

開始體會到什麼叫做到名詞地獄了吧。就是很多的套件都在做相同的事情,不過雖然做的事情類似,卻還是有些許的不同,但那等我們有用到再討論吧,這種情況我們一般我們會選用最大宗去做,雖然不保證它不會被取代,但至少確保它會持續地更新,所以小編推薦使用webpack 做預處理工具。

 webpack 非常強大,我覺得可以再寫一篇文章專門在介紹這套工具了,大家可以把他理解成為一套 打包 與 編譯 的工具就可以了(剛剛提到的.vue或是.css .sass .less或是ES6的js等檔案也是在這裡做重新編譯),他可以把入口檔開始所import的所有檔案,包含CSS跟圖片檔,通通打包成 "1" 個JS檔,最後使用者只須要引入這個JS檔,網站就會開始運作了~是不是很利害呢。讓大家可以只專注在js的開發。

 依照個人需求,webpack也可以把所有引入的css另外合併成一個css,不過必須透過外掛處理,預設式全部寫在js中的。


Router:

有開發過.NET的人,應該對這個名詞不陌生,就是藉由網址路徑導道不同的controller & action 去引入不同的View,在前端也是一樣的,不過不是導到不同的Controller,而是在指定的tag中引入不同的Component,且頁面不會重新刷新面。

ps. 大家在裝 "vue-router" 的時候記得不要打成 "vue-route",這是完全不同的套件,小編曾經因為這個r卡了一整天。

一般在前端也有router的狀態下會建議前後端拆開,但就真的沒有預算或專案沒這麼大不需要拆開的狀況,遇到後端的router跟前端的router衝突怎麼辦呢?小編也還在研究,不多說直接附上網址


SPA:

我也很喜歡洗SPA,那寫SPA呢? SPA全文(Single Page Application),單頁應用程式,就是藉由Router引入不同的子頁面,達到不刷新頁面而局部更新的效果,以達到省流量,快速,還有局部開發的優勢。看一下示意圖


Flux:

關於這個名詞最早是由FB為了處理React資料流所提出來的一個設計模式。後來被廣泛開發成一許多套件,在Vue之中落實Flux設計模式的套件就叫做Vuex,大家可以直接理解為Vue之於Vuex就好像React之於Redux,一樣很多人會問Flux是做什麼的用的呢?大家想像一個三角形,每個節點都想像成一個Component,每個Component都有自己template, model, style, sub component.......,那元件之間該如何溝通呢? 答案就是藉由發射器 $emit,這個名詞有開發過nodejs的人應該不陌生,父層可以藉由屬性可以把物件或字串數值傳給sub component,而sub component可以藉由$emit可以把值再向上傳給父層,在vue之中還可以特別透過BusEvent物件,大家可以想像它就像個廣播器,讓這專案下的component都可以接收到事件觸發。只是如果component越來越多,或頁面一多,事件的處理就越來越繁瑣,所以最好的方法就是統一交由Store管理,每個component需要資料時統一跟Store存取,要變更資料時也統一直接對Store變更,接收到變更後,Store就會主動去通知所有有用到這個欄位的component更新顯示。

大家把剛剛的三角形壓成平面,把原本需要上上下下傳遞的事件全部弄成平面,這樣資料在傳遞上似乎就通暢多了。就好像員工電腦壞掉大家不用藉由MAIL向上司報告上司再向部門主管報告........這樣傳遞下去非常消耗時間成本。所以最好就是有位專員負責處理這些大小事務,員工(component) 直接去請(dispatch) IT(store) 來維修電腦(model),修好之後員工就可以直接用更新後的電腦上班了,這樣不是很棒嗎?


小結:

每個語言及框架,沒有對錯,只有其適合與不適合的地方,例如用傳統的寫法搭配jQuery不是沒辦法做到SPA,也不是沒辦法做到render跟two-way-binding,但就是撰寫起來會非常繁瑣,要綁定許多事件,外加問題可能會存在非常多,還有無論是開發或是渲染速度都會相對上較慢。

另外這邊要來小小澄清一下,React & NG2 也是可以做到非SPA的開發,只是因為撰寫語言或框架太大關係,要進入個人覺得綁手綁腳,所以儘管小編是先接觸這兩個技術,卻也還沒完全研究成功~

網路上曾經看過一篇文章,作者只是想要寫個AJAX,卻必須學會一拖拉庫的技術,就因為現在是2016年,用 jQuery已經是非常不潮的行為了。所以必須花上大把時間,學習一堆技術,最後達成我想要AJAX的這個需求。當然,這是個笑話,如果你只是想要個 ajax當然用 jQuery是最快的,但這也是個不爭的事實,確實,好的工程師必須要可以用最小的舉動達成最終的目的,但不懂得考量團隊合作與日後可維護性的工程師只是個自私的渾蛋,這也就是為什麼前端技術一直推出新技術,難道真的是吃飽沒事幹嗎? 當然是為了開發速度,效能,好維護,關注點分離,等因素被創造出來的。所以小編不希望各位看完這篇文章只是為了去寫個AJAX功能出來,而是希望各位抱持著擁抱學習,提升自己的想法看完這篇文章。

當然小編也不認為 jQuery已死,也不認為他在短時之內會死,你大可繼續使用你苦練了好幾年的技術繼續開發,只是現在前端的世界進步很快,沒有拋頭顱灑熱血的決心真的不適合待在這裡,據傳每18個月,技術就會困難一倍,所以不再是不進則退,進步得太慢也是退步!而且當我告訴你,學完這些技術之後你月薪起碼可以提升5000塊,儘管學習曲線陡峭,那你學不學呢?

不過很殘酷的是,用新技術開發完,就是開發者自己心裡覺得很屌,老闆覺得省了很多人事成本而已,就使用者的體驗上,並不會差太多,當然這是在 0 BUG的情況下比較。

FYI 連尤大也推薦的非同步套件axios

環境架設:

相信我,這絕對是所有語言都會到遇到,且是最麻煩的部分,這也是讓許多人不得其門而入的高牆,很多人學完 npm後打開 package.json看到一大堆沒看過的套件就繳械了,所以在外圍觀望了很久,小編就是個活生生的例子,但相信我,只要你勇敢踏出一步,你會發現其實沒有這麼難,很多東西只要配置好就可以一路順暢開發無阻礙,而且官方還推出 vue-cli或 angular2-cli之類的命令式語法,更加降低建置環境與開發的困難度。

不過我剛剛也說了 vue可以做到隨時導入,就算只學一點點也可以開發出簡易的data-flow,所以我這邊有兩種開發方式可以任君選擇,一種是無痛開發,另外一種是先苦後甘開發,大家可以依需求選擇


無痛開發:

只需要引用這麼一行,就可以開始寫vue程式了

優點:不需要經過太多手續,用傳統的方式引入library即可,對於要即時導入data-flow的專案有非常大的效果

缺點:如果引入的檔案過多效能差,且須留意引入順序,會在專案開發過程綁手綁腳,專案越大越明顯


先苦後甘開發:

附上我已經寫好的程式,各位只需要做好下面幾個步驟專案就可以運作了。

step1.

git clone https://github.com/lu7766lu7766/vue_practice.git

step2.

cd vue_practice

step3.

npm install

step4.

npm start

step5.

開啟瀏覽器輸入http://127.0.0.1:3000

裡面有個非常陽春的畫面,雖然是練習用,卻包含了上面我所陳述的所有技術,而且這個專案是我從無到全部有自己建置的,所以不會用到什麼深不可測的技術跟配置,畢竟小編也是魯蛇一條,所以一定很好懂,不懂也一定GOOGLE得到。


大家也可以直接透過vue-cli建置專案,免去環境建置的麻煩。

setp1.

npm install vue-cli -g

setp2.

vue init webpack project_name

step3.

cd project_name

step4.

npm run dev // dev是開發模式,待開發結束可以下npm run build就會產出最終檔案到 /dist資料夾,在把資料夾下的檔案放到伺服器即可執行

step5.

http://127.0.0.1:8080

既然有巨人的肩膀,就不要猶豫快站上去吧。當然如果大家想站在魯蛇的肩膀上也是可以拉。不過後面的範例說明都會用cli建立的專案說明喔。想要自學的人在用我建立的專案慢慢學習吧。

優點:可以真正達成模塊式開發,無須擔心引入的部分,速度快,適合團隊開發,落實關注點分離,適用於所有伺服器(但開發中仍是以nodejs為主),而且還有hot reload(熱加載,元件編輯完自動刷先新)

缺點:如果重頭開始件建置專案,第一次確實會頭很大,不過建置專案的重點都放在webpack即可,另外如果對建置環境不熟悉,就很難做到要從已開發專案中插入的需求,這也是為什麼一般人都會先選用無痛開發起步的原因

特別強調一下,為避免低級錯誤,用vue-cli建專案會引入 eslint, editorconfig套件,會特別強調撰寫風格,多一個空格少一個空格什麼的,這也會導致大家程式碼直接複製貼上卻run不出來的原因,沒關係大家改久就習慣了。或者大家可以自行修改 .editorconfig、.eslintrc.js 這兩個檔案,或直接刪掉。


程式開發:

下面程式所有的註解都是小編額外加上去的,如果有編譯失敗的情況記得要拿掉喔。

終於要進入我們的主題了,那主頁面index.html基本上我們只會動一行,程式碼如下

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>clitest</title>
    <script src="src/main.js"></script><!-- 加入入口檔案 -->
  </head>
  <body>
    <div id="app"></div><!-- built files will be auto injected -->
  </body>
</html>

我們來看一下主程式,小編會針對要講解的內容稍微做些簡化,未必會跟剛 init完的檔案一樣

/src/main.js
import Vue from 'vue'//引入/mode_modules/vue內的套件
import App from './App'//引入/src/App.vue檔案,因為webpack設定,附檔名可以省略
//import 'bootstrap/dist/css/bootstrap.css' //引入/mode_modules/bootstrap/dist/css/bootstrap.css,不過webpack也要做出相對應的設定才行
//下面就是Vue的宣告
new Vue({
  el: '#app',//指定id="app"的tag, selector的方法跟css一樣, id用#開頭
  template: '<App/>',//把template注入el所指定的element會被樣板取代變成 <div id="app"></div> => <App />
  components: { App }//宣告component and render,所以<App />就會被渲染過,至於渲染成什麼樣子,我們看App.vue這檔案
})

我們來看一下App component

/src/App.vue
<template> //開始宣告此component的template
  <div id="app">
    <img src="./assets/logo.png">
    <hello></hello>
  </div>
</template> //template宣告結束
<script> //開始宣告此component的vue物件
import Hello from './components/Hello'
export default {
  name: 'app',
  components: { //這裡可以在寫入sub component
    Hello
  }
}
</script> //vue物件宣告結束
<style> /*開始宣告css,這樣寫是否只有在此元件中才會吃到css,還是所有的子元件都會吃到,要試一下*/
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style> //cs宣告結束

跟ng2不太一樣的是,ng2會用一個資料夾去包 .html, .js, .css, .spec.js四個檔案,但這樣讓開發者看起來會很阿雜,所以保哥上課時就說開發者必須自行判斷元件有沒有必要被開發為元件,因為拆太細,檔案可是會一拖拉庫的,而在vue裡面,就只會有一個 .vue 檔案,就算你拆得比ng2細四倍,檔案也才一樣多而已,哼~

因為tag會自動被小寫化,所以命名規則,建議變數採駝峰式命名,tag採小寫,單字中間以"-"字號相連。如果和原本就有的 tag明相撞,那 component就不會產生作用,例如: header、footer,所以小編個人建議可以加上App後贅字,例如: HeaderApp,那tab就是<header-app></header-app>,這樣在render時就會辨識出sub component,並把component的template注入

因為SPA的開發,通常都會只有 一個入口,以這個專案來說就是 App component,你會發現它存在的位置跟其他component不太一樣,所以不會變動的 header, footer或 menu就可以放在這裡

接著我們來看一下Hello Component

/src/component/Hello.vue
<template>
  <div class="hello">
    <h1>{{ msg }}</h1><!-- 大家有沒有看到跟ng一樣的寫法, 這行render出來換變成 => <h1> Welcome to Your Vue.js App </h1>-->
      <input type="text" v-model="msg"/><!-- vue跟ng1&ng2一樣,也充滿了語法糖,v-model,是要做到雙向綁定的意思,就是修改的同時,msg變數也會修改,那上面的這行字也會跟著修改,這就是雙向綁定神奇的地方啊 -->
      <br>
      <a v-bind:href="href">google</a><!-- 又是個語法糖,也可以簡化為:href,作用是用來綁定屬性,也可以藉由綁定屬性,component可以藉由prop取得資料或物件 -->
      <!-- 這裡render完會變成 => <a href="www.google.com">google</a> ,也有人會寫<a href="{{href}}">google</a>這樣是也可以運作的,只是會有少部份情況會出現不是你希望看到的畫面,或是效果,待各位自行研究了-->
      <br>
      <button v-on:click="onHandleClick">+1</button><!-- 又是個語法糖,也可以簡化為@click,作用是用來綁定事件 -->
      <span v-text="count"></span><!-- 如果客戶非常龜毛,跟你反應頁面剛開起來會看到一堆{{adf}}之類的亂碼,可以透過這個語法糖,讓vue啟動之後再把變數render出來 -->
      <h2 v-if="count>0">Hello Component</h2><!-- 如果不符合條件,tag將會被刪除,不是隱藏喔,隱藏要用v-show -->
    <br>
      <select v-model="selector">
          <option v-for="(val,index) in [1,2,3]" :value="index" v-text="val"></option>
          <!-- 今天講我們最後一個要說的語法糖v-for,類似foreach的效果,是在show陣列或物件資料不可或缺的存在 -->
          <!-- render完會變成如下
          <option value="0">1</option>
          <option value="1">2</option>
          <option value="2">3</option>
          -->
      </select>
    <!-- 當然還有v-once(只渲染一次) v-html(輸出內容是html格式,必須要這個語法) v-else....很多語法糖有待各位自行發掘,這就不一一展示 -->
  </div>
</template>
<script>
export default {
  name: 'hello',
  data () { // 這就是vue的model,各位當然也可以用ajax調回資料後,在一次把整包資料塞進來
    return {
      msg: 'Welcome to Your Vue.js App',
      href: 'http://www.google.com',
      count: 0
    }
  },
  methods: {//事件,function都寫在這裡
    onHandleClick () {
      this.count++ //this就可以直接指定到model
    }
  },
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped> /*開始宣告此component的css,只有在此元件中才會吃到css,官方都這樣說了*/
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

Vue 的撰寫風格,有寫過 ng的人說應該會很熟悉,都是在 html語法中寫入一堆語法糖。

Vue預設是one-way-binding的,當然也可以透過v-model來達到two-way-binding的效果,可以自由選擇,他不像react一樣,沒有綁成two-way-binding,input就不能進行修改。對新手來說感覺很差。

資料綁定跟畫面的花俏一點關係都沒有,只是讓大家可以把注意力放在model上面,以大幅減少data被複製出太多份,捉錯,或忘記render等 bug出現,所以這類框架就不適合形象網站,如果要動畫飛來飛去的你還是去找jQuery吧,不過如果你要寫的是系統,列表,後台,或是component會不斷重複利用的網站,例如社群網站,倒是會如魚得水。

這裡比起原始檔案,改了很多東西,因為我想把vue的基礎語法都在這裡說完。基礎就說到這了,接著我們來談談 router吧。


VueRouter

最直覺的想法就是router要寫在入口頁,也就是App component裡,那我們就來看一下要怎麼改吧。(下面的程式就完全都不一樣了,讀者可以參照著文章修改或加檔案)

首先在要在上層的 main.js Vue物件中增加 router設定,讓所有的 component都可以有自己的 router-view


/src/main.js
import Vue from 'vue'
import App from './App'
import router from './router' //    引入router設定檔
/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App />',
  components: { App },
  router //same with router:router
})


/src/App.vue
<template>
  <div id="app">
    <router-link to="/">Hello</router-link> <!-- 會被編譯成為<a....> -->
    <router-link to="/bar/123">Go to Bar</router-link>
    <img src="./assets/logo.png">
    <router-view></router-view> <!-- router完的component就會被丟到這裡 -->
  </div>
</template>
<script>
export default {
  name: 'app'
}
</script>
<style>.......</style>

這裡應該只有一個檔案有問題,就是router這個檔案,我們來看一下,設定檔怎麼寫吧


/src/route.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Hello from 'component/Hello'
const Bar = {
  template: `<div>bar {{ $route.params.id }}</div>` //取得路由參數
}
const routes = [
  { path: '/', component: Hello }, //預設就是Hello物件
  { path: '/bar/:id', component: Bar }
]
Vue.use(VueRouter)
const router = new VueRouter({
  routes // same with routes: routes
})
export default router

在這樣就可以達成router了喔,且裡面也可以丟參數,可藉由$route.params取得,是不是很簡單呢 ~

router學完接著我們來學flux,那我們會用到vuex套件,沒有的人一樣,記得裝一下,裝完記得重新run專案。

另外來小小解釋一下 ` (模板字符 原文:template string)。這是ES6特有的符號 ,可以在裡面寫入多行的字串,不需要傳統的傳統的 結束字串符號,然後相加,然後在第二行.....,甚至可以寫入變數,(例如: var a=100; str = `a = ${a}` => b =  "a = 100";) ,程式會經過 babel轉譯成 ES5 (傳統的雙引號字串相加),另外小編推薦用VSCode開發也不會出現令人惱怒的紅色蝌蚪,所以各位可以不用顧慮,大方使用。

VSCode裡面也有許多好用的套件,可以加速大家開發的速度與激情便利性,等待大家去發掘喔~


Vuex

因為我們層數沒有很多,那我們資料就從最上層的App component塞,然後從Hello component取吧,來看一下程式該怎麼改。 

一樣要在最上層的main.js加入vuex設定,確保所有的 component都可以吃到 store


/src/main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App />',
  components: { App },
  router,
  store
})

/src/App.vue
<template>
  <div id="app">
    .....
    <button @click="countAdd">+1</button>
  </div>
</template>
<script>
......
export default {
  name: 'app',
  methods:{
    countAdd:function(){ // 會增加存在於store的count變數
      this.$store.dispatch({ // 有沒有跟redux很像
        type: 'incrementAsync'
      })
    }
  }
  ......
}
</script>
<style>.......</style>

 那我們來看一下該怎麼接資料呢

/src/component/Hello.vue
<template>
  <div class="hello">
    <h1>{{ count }}</h1>
  </div>
</template>
<script>
export default {
  name: 'hello',
  computed: { //vue中的計算屬性,功能等同於.net當中的get{......}
    count () { // 因為store.state.count並不屬於此component,所以必須藉由這樣轉傳
      return this.$store.state.count // 直接回傳即可,當然想*2或加些料什麼的也是可以
    }
  }
}
</script>
<style scoped> ......</style>

跟React最大不同就是vue跟ng2都會有自己component的model,當template再取值的時候沒辦法直接取store中的值,必須靠計算屬性轉一手。

最後我們來看一下最重要的store怎麼設計


/src/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    incrementAsync ({commit, state}, payload) {
      // setTimeout(() => {
      //   commit('increment',payload.amount)
      // }, 1000)
      commit('increment')
    }
  }
})

大家應該一樣沒然為什麼這裡也要經過 action commit再到 mutations之後才去更新count,依據官方的說法,mutations才有資格去更改state的值,但是mutations是同步處裡的,所以如果需要異步處裡的功能需要藉由action來做到,這也就是為什麼我留了個setTimeout給大家參考的原因。

 

當然ditpatch也是可以待參數的。另外如果有接觸過redux的人也可能會問,有沒有類似 reducer的東西可以用,不然專案越來越大,會越來越亂,有!你要什麼都有!不過在vuex不叫 reducer,而叫 module,或者一個畫面想要兩個路由 component,或 router裡面還要有router可以嗎?可以!至於怎麼用呢?

這又是另外一個故事了(遠目~),不難拉 ~ 自己去查 ~


總結:以上就是vue的所有基礎知識,以及前端目前流行的開發方式,對各位來說可能會是個知識爆炸的一天,沒關係,小編也是過來人,I got you ~~ 不過程式這種東西還是要自己實做過一次,才就懂每一行程式到底都在做些什麼,特別是前端 JS,不經過自己手上實做出來,並看到變化,實在抽象到難以想像。沒關係大家可以慢慢消化,大家還有18個月再去迎接更難的程式。希望今天的課程內容可以帶著大家從 網站設計師 朝向 前端攻城屍 之路向前邁進一步!剩下的大家就自行研究了,希望大家可以享受開發的過程,有不懂的地方,或想要更加深入了解的地方,也歡迎隨時提問或直接敲我討論,以上謝謝大家。


終於打完了~比我以前寫的小說還長~好想哭阿~~~~