🔍 搜尋結果:css

🔍 搜尋結果:css

經營個人頻道,改變了我的軟體工程師生涯

大家好,我想鼓勵一些想要開始當工程師,但很難找到第一份工作的人。還有那些因為懷疑自己的能力而難以開始/完成專案的人(冒牌者症候群)。我將告訴你我自己的旅程,以及我一路上學到的東西來,希望你能有動力繼續你的旅程。 原文出處:https://dev.to/chaoocharles/how-creating-content-as-a-developer-changed-my-life-270e 我叫查爾斯,來自非洲肯亞。我早在 2016 年就開始了我的編碼之旅,當時我進入大學,在 BTECH I.T 尋求職業生涯。在此之前,我對電腦了解不多,我只知道它們很酷,我想研究它們。在高中時,我是一名表現最好的學生,我的英語老師(也是副手,哈哈)認為我想做一些像計算機這樣簡單的事情而不是像工程、醫學、飛行員等更專業、更有前途的職業,這是愚蠢的,你說出它們的名字。好訊息是我沒有聽,而是去做了我想要的事情,而且我不會為此感到後悔。事實是,IT 領域的任何職業都是當今世界上最好的職業之一,世界頂級公司之所以能處於領先地位,是因為程式碼。看看 Netflix、亞馬遜、微軟、Facebook、Airbnb 或 Uber。所有這些公司都透過程式碼賺了數十億美元,因此不要讓任何人欺騙您,讓您認為您走在錯誤的道路上。我來這裡是為了告訴你,你正走在最好的道路上。 回想2016年剛入職第一年的時候,由於出身卑微,擁有一台筆記型電腦對我來說是非常困難的,即使是一台簡單的筆記型電腦,甚至是二手的筆記型電腦。如果我要做 I.T,那麼擁有一個對我來說也是強制性的。擁有一部像樣的智慧型手機也是一個問題,但幸運的是,我有一個三星口袋(那些小三星手機,如果你還記得的話),並在說服朋友用它與我交換一些錢和一部按鍵手機後。這款手機在這個故事中很重要,因為它是我用來開始學習程式設計的手機。在學校裡,我們被教導如何編碼,是的,但這還不夠,它主要是理論。關於編碼的事情是你必須_練習_、_練習_、再_練習_。於是,我從同學那裡了解到了一個名為sololearn的應用程式。我在那裡開始學習 Web 開發,包括 html、css、javascript、php、sql,我想還有一點 jquery。這個應用程式教會了我有關這些主題的所有基礎知識,並且在完成每節課後它都有有趣的挑戰和徽章。唯一的問題是我不會透過手機進行完整的專案編碼。但重點是,當您等待購買筆記型電腦時,您絕對可以開始透過智慧型手機學習程式設計。因此,不要因為沒有筆記型電腦而高枕無憂。你越早意識到沒有人來拯救你越好。 我繼續從我的三星口袋裡學習了一個月,後來在內羅畢街頭(有很多扒手)它被神秘地偷走了。學校的朋友送了我一部HTC手機,螢幕碎了,有些地方根本碰不著,我得旋轉螢幕多次才能碰到地方😂,不過乞丐不挑食,我就繼續用了以便在本學期剩下的時間裡學習更多有關編碼的知識。 第二學期,現在是2017年,我收到了學生貸款。我的一些朋友/同學用他們的貸款去聚會、喝酒以及在俱樂部與女孩們玩耍。嗯,就我而言,我知道自己從哪裡來,也知道自己要去哪裡。於是,我拿了一些錢,立刻買了一台筆記型電腦。剩下的錢用來付學費和一點生活費。這對我的案例來說是一個巨大的進步,因為我現在可以了解更多資訊並開始從筆記型電腦上處理專案。因此,如果您有錢,請停止考慮參加聚會和購買昂貴的東西,而是考慮如何用這筆錢讓您的生活變得更好。 2017年至2019年期間,沒有太大變化。我只是在學習和做學校作業等。我想我還用 HTML 和 CSS 製作了兩個網站,我為這些工作獲得了一些報酬。我探索了更多關於編碼的知識,包括學習Java 中的OOP(物件導向程式設計),也用Java 進行了一些Android 應用程式開發,我的筆記型電腦無法處理android studio 😂,所以我又回到了Web 開發。我探索了 WordPress 以及如何用它製作博客等,並建立了一個 WordPress 博客,並以幾美分的價格出售。 2019年底,我正在讀三年級第三學期(這在我們大學被稱為內部工業實習),大約在這個時候,我被敲響了警鐘。我意識到我一直在學習編碼,但除了簡單的 html、css 和 WordPress 網站之外,我仍然無法建立一個完整的專案。我對任何一種程式語言都沒有足夠的信心。另外,畢業的要求是在第四年完成一個編碼專案。我也開始對未知產生恐懼,例如放學後要做的事情,因為只剩下一年了。我開始做很多研究如何建立一個完整的網絡應用程式,因為我已經了解了 javascript 的基礎知識,並且出現了一件我不知道的事情,即 javascript 框架,目前最流行的是 Angular、Vue並做出反應。當時我就知道我必須學習這些框架之一,而且很難決定選擇哪一個,但我最終選擇了 React,因為它是所有框架中最受歡迎、最有前途的工作,而且我仍然使用 React 進行編碼這點。 我嘗試從sololearn學習React,但進展並不順利。我嘗試了 youtube 並發現了 @thenetninja 頻道:https://www.youtube.com/@NetNinja 它非常有益健康,這就是我對 React 的很好的介紹。後來我從 Udemy 學習了兩門完整的 React 課程,一門由 _Stephen Grider_ 教授,另一門由 _Maximilian Schwarzmüller_ 教授。順便問一下,我沒有完成它們,誰完成了 udemy 課程? 😂 但這兩門課程教會了我更多關於 React 的高級知識。 在學習 React 的過程中,我也很好奇如何在放學後或還在學校的時候透過程式碼賺錢,我發現了幾個選擇,找工作、自由工作、建立內容(這可以是寫部落格或 YouTube 頻道) )、開始播客、寫書、建立像udemy 這樣的課程等等。由於我還在上學,我知道找工作很難處理,所以我決定嘗試自由工作和內容創作。還是在 2019 年,我開設了 YouTube 頻道:https://www.youtube.com/c/chaoocharles 來教授編碼,也開設了一個 upwork 帳號來從事自由專案的編碼。 我知道我不是一個好的作家,正如你從這篇文章中絕對可以看出的那樣,所以我嘗試了影片而不是博客。這是另一個挑戰,因為我必須學習如何製作影片、學習錄製和編輯軟體等等。但我還是堅持了下來,並從同學那裡得到了我的前 100 個訂閱。我的影片一開始就很糟糕,而且我做了很多工作,甚至沒有得到一分錢。但從正面的角度來看,製作影片讓我更理解編碼概念。就像,對我來說,要解釋我必須先理解的東西。我主要用 html、css 和 React 建立了很多影片,做得越多,我對建立影片和編碼就越有信心。 2020 年,我有很多時間來做這一切,因為我們因新冠疫情關閉了學校近一年,經過一年的努力,我終於獲得了 1000 名替補,這對我來說是一個巨大的勝利。 2020 年中期,我取得了兩場重大勝利,在 YouTube 上達到了 1k,並且在 Upwork 上找到了我的第一個客戶。我需要 1000 訂閱者和 4000 小時的觀看時間,YouTube 才會開始向我付費。我距離 4k 觀看時間還很遠,但至少我已經達到了其中一項要求。 Upwork 也很難找到第一個客戶,我申請工作卻無濟於事,但這第一個客戶改變了遊戲規則。我讓他相信我知道如何編碼,並用我的 YouTube 教程證明了這一點。你看,在製作 YouTube 教學的同時,我也在為自己建立一個作品集,我也在我的 github 上發布了多個專案。這麼說吧,我的投資組合目前看起來非常好,這位客戶毫不猶豫地給了我一份合約。如果你碰巧教了一些東西,人們就會開始將你視為專家(即使你正在努力教那件事😂)這可以通過影片或博客,我認為你應該嘗試一下。我在 upwork 專案上做得很好,這個客戶在那一年和接下來的一年裡繼續給我更多的專案。我做了他的大約 8 個專案,在 upwork 上獲得了上升人才徽章,後來又獲得了頂級徽章,這讓我贏得了更多客戶。 ![Upwork](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jut1tydubsj4mwlmnt3h.png) 是的,我知道我現在的工作成功分數很差,但你明白了,哈哈😂 在製作YouTube 影片和Upwork 專案時,我也在做我的最後一年專案,因為我現在已經是第四年了,但這些是我自從2020 年因新冠疫情在家以來所做的唯一事情。雖然在2020 年底,我們回去上學期,做了考試並展示了專案。 快轉到 2021 年,我現在正在做附件。這是我畢業的必要條件。我透過在 Facebook 和網路上尋找肯亞的網路開發公司,輕鬆獲得了這一點。評論他們的帖子並解釋我的 IT 背景。我從某家新創公司的 CEO 那裡得到了 DM,並且以前端開發人員的身份加入了那裡。我試圖就報酬進行談判,但最好的結果只是維持交通和午餐,每週去辦公室三天,並承諾在實習後獲得一份長期工作。作為一名學生,這已經足夠好了,所以我就這麼做了。 在這家公司,我的 CSS 和 React 技能給他們留下了深刻的印象。我改造了他們公司的網站,並在我在那裡的5個月期間又做了2個網站。學校對我進行了評估,後來公司給了我工作機會。我覺得每個月的收入對我的技能來說不夠好,因為我可以在一兩週內輕鬆地做同樣的自由職業,而且我在那裡的時候我的 YouTube 也得到了貨幣化。我只是拒絕了這個提議,並決定專注於我的自由職業和內容創作之旅。如果他們允許我在處理其他事情的同時遠端處理他們的專案,也許我會接受這個提議,但這不在他們的公司政策中。我不想滿足於更少。你看,過去幾年我所做的一切都給了我選擇,也讓我不再急於找到工作,並擁有競爭優勢。 2021 年年中,我以二等高年級畢業,我保證如果不是我用 YouTube 和 upwork 分散自己的注意力,我會獲得一等,第四年我表現最差。但我後悔嗎?不。問題是,我從來沒有用過那個學位,它仍然鎖在家裡的某個地方,沾滿了灰塵。好處是,技能和經驗是這個編碼和程式設計領域最重要的。只有少數公司可能會要求學位,但大多數公司不會。他們會詢問您過去的經驗、您從事過的專案,並希望您通過程式設計面試。因此,如果你正在尋找一份程式設計工作,並因為沒有獲得學位而指責自己沒有學位,那麼你應該停下來。我們大多數擁有學位的人甚至沒有使用它們。也許我們唯一的優勢是我們在學校建立的聯繫或從那裡獲得的技能。但說實話,我所知道的大部分內容都是我自學的,我相信每個程式設計師都是自學的程式設計師,無論他們是否上過學。你必須親自動手。光靠論文並沒有太大幫助。 畢業後,我開始從 YouTube 獲得專案邀請,以及報酬豐厚的專案。我也開始利用 YouTube 和 GitHub 來在 Upwork 上獲得更好的付費專案,透過分享我的個人資料連結來告訴客戶我所取得的成就。所以,所有這些加起來就很不錯了。現在,我僅透過內容創作來支付所有帳單,並透過在工作和外部工作專案上工作來獲得更多收入。我的時間也很靈活,在家工作,這很棒。 2022 年我只做了一份全職工作。雖然位置偏遠,但完全值得。 我的觀點是,如果你正在努力尋找一份工作或一個專案,你可以透過為自己建立一些東西來改變一切。建立部落格、建立播客、建立頻道、建立公司、建立課程、寫書、公開建置(啟動一個大型專案並在此處和 Twitter 上分享您的進度),只需在這裡展示您的技能即可您能做什麼,遲早你會開始從事高薪專案。停止追逐工作,而只是吸引他們。 正如你從我的旅程中可以看出的,這不是一天的成就,直到一年多我才得到一分錢的內容創作報酬,直到一年多我才得到一個客戶的工作。我不是一天就能學會程式設計的,我是從一部手機開始的,後來又是用學校貸款買的一台低階筆記型電腦(我甚至還沒付)。所有這些成功的人士和公司都是從某個地方開始的,您今天就可以開始改變您的生活。開始親自動手,兩三年後你甚至不會相信自己來自哪裡。 這是我的故事,我希望你學到了一兩件事✌️

新手寫前端應該避免的一些壞習慣

原文出處:https://dev.to/lucasm/frontend-best-practices-guide-or-dont-do-it-on-frontend-32n4 ### console.log 請刪掉。 刪除 production 程式碼中的 console.log 以防止敏感資訊洩漏。 ### 控制台錯誤和警告 調查並修復。 解決 production 程式碼中的控制台錯誤對於保持流暢且無錯誤的使用者體驗非常重要。 ### TypeScript 中的 any 請使用準確的型別。 應盡量減少在 TypeScript 中使用“any”,轉而使用明確類型,以增強程式碼的可靠性和可維護性。 ### 註解未使用的程式碼 請刪掉。 註解掉未使用的程式碼是一種不好的做法,因為它會使程式碼變得混亂,妨礙維護,並可能導致註解資訊過時。 ### 超級元件和功能 如果您的元件很大,那麼就該將其分成更小的元件了。 想想 SOLID 的古老原則「單一職責」。 無論您是編寫函數程式碼還是類別程式碼。 ### 多次重寫CSS 不要重複重寫顏色、字體和大小,使用設計標記來發揮自己的優勢,建立全域 CSS 變數或使用函式庫。 與您的團隊討論使用設計令牌的優勢。 ### Linter 的標誌 修復你的程式碼。 範例:使用 `/* eslint-disable @typescript-eslint/no-unused-vars */` 不要傳送帶有 linter 錯誤的 Pull 請求。 如果您確實需要忽略,請仔細考慮可以忽略哪些 linter 警告。 ### 重新渲染和循環消耗大量資源或崩潰 範例:JavaScript 循環函數或 React 中的 useEffect 應用不佳。 這可能會導致 API 呼叫或值無限重複,從而導致記憶體溢出並導致應用程式崩潰。 修正你的邏輯。 * 注意:您的應用程式在瀏覽器中執行並消耗有限的用戶記憶體資源。 ### 前端的商業邏輯 請勿放置。 人們普遍認為,任何前端應用程式都不能有業務規則,只有使用者介面固有的規則,用於互動和使用者的成功旅程。 前端是客戶端,不是伺服器。 大公司和企業級應用程式採用的做法是不將業務規則和資料處理暴露在前端,而將其放在後端。 * 注意:對於簡單的無伺服器 Web 應用程式或參考第三方 API 的應用程式,可能有必要在前端放置一些業務規則 - 小心不要向客戶端暴露敏感或成本高昂的動作。 ### 不測試 在您的程式碼庫上進行測試。沒有程式碼是完美的。 單元、整合、安全性、使用者體驗、效能和可存取性測試。使用測試工具產生錯誤報告和改進以糾正您的應用程式。 範例:部署管道中的 Cypress、Lighthouse、SAST 等。 與使用者體驗、品質保證和網路安全/滲透測試團隊合作(如果您公司有)。 ### 恐懼溝通 當您遇到困難時,請致電其他開發人員或技術主管來分享您面臨的問題。 透過 pair programming 和共同思考,可以更快解決問題! 請記住:他們曾經處於您的位置並且會提供幫助! 希望你喜歡!😃✌🏻

React 生態系 2024 年推薦總整理

2024 年,React 將慶祝其成立 11 週年,值得期待 React 生態系統中令人興奮的發展。在本部落格中,我們將基於 2023 年發生的情況以及來年的預期,探討生態系統的各個面向。 原文出處:https://dev.to/avinashvagh/react-ecosystem-in-2024-418k ## 1. 路由 路由一直是Web開發的關鍵部分,在2023年,我們看到了各種各樣的路由解決方案。讓我們看看2024年會發生什麼: - **React Router:** React Router 仍然是 React 應用程式中處理路由的基本選擇。憑藉其廣泛的文件和活躍的社區,它仍然是應用程式中聲明式路由的可靠選擇。 - **React Query:** Tanstack 的 React Query 在 2023 年流行的基礎上,旨在增強資料擷取和狀態管理。它簡化了 React 應用程式中管理、快取和同步資料的過程。 - **Next.js:** Next.js 是一個建立在 React 之上的框架,預計將保持其作為具有靈活路由選項的伺服器渲染 React 應用程式首選的地位。它的官方文件是 Next.js 應用程式中路由的寶貴資源。 2024 年,React 充滿活力的生態系統將繼續蓬勃發展,為開發人員提供豐富的工具和函式庫。請繼續關注 React 世界的更多更新和進步。 ## 2. 客戶端狀態管理 客戶端狀態管理是現代 Web 開發的一個重要方面,可以在前端應用程式中實現高效的資料處理。 Redux Toolkit 和 Zustand 是兩種流行的用戶端狀態管理解決方案。以下是兩者的簡要概述: ### 1. **Redux Toolkit** - **網址:** [Redux Toolkit](https://redux-toolkit.js.org/) Redux Toolkit 是一個建立在 Redux 之上的綜合狀態管理函式庫,Redux 是 React 應用程式中成熟的狀態管理函式庫。它提供了一組工具和最佳實踐,以可預測且高效的方式簡化狀態管理流程。 Redux Toolkit 的結構化方法(包括 actions、reducer 和 store)非常適合複雜的大型專案。它提倡採用集中式和聲明式的狀態管理方法。 ### 2. ** Zustand** - **示範:** [Zustand Demo](https://state-demo.pmnd.rs/) Zustand 是一個輕量級且靈活的狀態管理庫,專為小型專案或喜歡更簡單解決方案的開發人員而設計。它簡化了狀態管理,無需複雜的設定和概念。 Zustand 以其簡單性和易用性而聞名,這使其成為小型應用程式和重視更輕量級方法的人的絕佳選擇。 在 Redux Toolkit 和 Zustand 之間進行選擇時,請考慮專案的複雜性以及您對 Redux 的熟悉程度。 Redux Toolkit 是大型、結構化應用程式的絕佳選擇,而 Zustand 則非常適合需要快速、簡單的狀態管理解決方案的小型專案。 ## 3.伺服器狀態管理 伺服器狀態管理是 Web 開發的一個重要方面,特別是對於跨客戶端和伺服器的應用程式。以下是兩個可以幫助您有效管理伺服器狀態的關鍵庫: ### 1. **TanStack Query** - **文件:** [TanStack Query](https://tanstack.com/query/latest) TanStack Query 是一個強大且靈活的狀態管理庫,用於處理應用程式中的伺服器狀態。它允許您輕鬆地從伺服器獲取、快取和更新資料。該程式庫提供自動快取、高效資料擷取以及自訂 API 端點的功能等功能。對於需要即時資料更新和高效資料同步的應用程式來說,它是管理伺服器狀態的絕佳選擇。 ### 2. **Redux 工具包 - RTK Query** - **文件:** [Redux 工具包 - RTK 查詢](https://redux-toolkit.js.org/rtk-query/overview) RTK Query 是 Redux Toolkit 生態系統的一部分,提供管理伺服器狀態的全面解決方案。它以可預測且高效的方式簡化了發出 API 請求、快取資料和更新狀態的過程。 RTK Query 與 Redux 無縫集成,對於使用 Redux 進行狀態管理的應用程式來說是一個絕佳的選擇。它提倡最佳實踐並提供結構化方法來處理伺服器狀態。 選擇伺服器狀態管理庫時,請考慮您的專案需求、資料擷取需求的複雜性以及您對 Redux 的熟悉程度(如果您選擇 RTK 查詢)。這兩個庫都提供了用於管理應用程式中的伺服器狀態的強大解決方案。 ## 4. 表單處理 表單處理是建立 Web 應用程式的關鍵部分,尤其是在 React 中。用於表單處理的兩個流行的程式庫是 Formik 和 React Hook Form。概述如下: ### 1. ** Formik** - **網址:** [Formik](https://formik.org/) Formik 是在 React 中建立表單最常用的函式庫。它提供了一組實用程式和元件,可以輕鬆管理表單狀態、驗證和提交。雖然它是一個流行的選擇,但截至最新訊息,Formik 並未得到積極維護,這可能會影響其與未來 React 更新和不斷發展的最佳實踐的兼容性。使用 Formik 的唯一缺點是它不被維護。 Formik 文件/網站甚至不鼓勵在新專案中使用 Formik。 ### 2. **React Hook Form** - **網址:** [React Hook 表單](https://www.react-hook-form.com/) React Hook Form 是一個現代表單函式庫,它利用 React hooks 來有效地處理表單狀態和驗證。它得到積極維護,並提供輕量級且直觀的 API。 React Hook Form 以其效能和靈活性而聞名,使其成為在 React 應用程式中處理表單的絕佳選擇。 在 Formik 和 React Hook Form 之間進行選擇時,請考慮維護和專案的特定要求等因素。根據最新訊息,React Hook Form 因其積極的開發和現代的表單處理方法而成為推薦選擇。 ## 5. 測試 測試是軟體開發過程的關鍵部分,有各種工具和程式庫可協助開發人員編寫有效的測試。以下是一些用於測試的資源和工具: ### 1. **ViTest** - **網址:** [ViTest](https://vitest.dev/) ViTest 是一個由 vite 支援的單元測試框架。它提供了一種為 React、Vue、Svelte 等應用程式編寫單元測試、元件測試和端到端測試的簡單方法。如果您使用 React,ViTest 可以透過全面的測試來幫助您確保程式碼的可靠性和品質。 ### 2. **React 測試函式庫** - **文件:** [React 測試庫](https://testing-library.com/docs/react-testing-library/intro/) React 測試庫是 React 應用程式的熱門測試庫。它專注於編寫模擬使用者互動的測試,幫助您確保元件從使用者的角度按照預期執行。該程式庫鼓勵測試 React 元件的最佳實踐。 ### 3. ** Playwright** - **網址:** [Playwright](https://playwright.dev/) Playwright 是一個端對端測試框架,支援多種瀏覽器,包括 Chromium、Firefox 和 WebKit。它為瀏覽器自動化提供了統一的 API,並允許您編寫測試來驗證 Web 應用程式在不同瀏覽器上的功能。 Playwright 是確保跨瀏覽器相容性的強大工具。 這些資源和工具可以幫助您涵蓋測試的各個方面,從單元測試到端到端測試,具體取決於您的專案需求和您正在使用的技術。請務必進一步探索它們,以選擇最適合您要求的一種。 ## 6. 樣式 當談到 Web 開發中的樣式時,有幾種流行的工具和庫可供選擇。以下是三個值得注意的選項: ### 1. **Tailwind CSS** - **網址:** [Tailwind CSS](https://tailwindcss.com/) Tailwind CSS 是一個實用程式優先的 CSS 框架,它提供了一組預先建立的原子 CSS 類別來設計您的 Web 應用程式。它旨在透過在 HTML 中編寫實用程式類別來幫助您快速建立響應式且高度可自訂的設計。 Tailwind CSS 以其靈活性而聞名,對於想要實用程式驅動的樣式設計方法的開發人員來說是一個絕佳的選擇。 ### 2. **樣式元件** - **網址:** [樣式元件](https://styled-components.com/) Styled Components 是一個 CSS-in-JS 函式庫,用於設計 React 元件的樣式。它允許您透過使用標記模板文字定義樣式元件來直接在 JavaScript 檔案中編寫 CSS。這種方法使您能夠將樣式封裝在元件中,從而更輕鬆地管理和維護 CSS。樣式化元件在 React 生態系統中特別受歡迎。 ### 3. ** Emotion** - **文件:** [Emotion](https://emotion.sh/docs/introduction) Emotion 是另一個 CSS-in-JS 函式庫,重點是效能和靈活性。它提供了多種方法來定義樣式並將其應用到 React 元件,包括字串和物件樣式。 Emotion 以其可預測性和適合使用 JavaScript 編寫不同 CSS 樣式而聞名。它提供了一種與框架無關的方法,使其適用於各種 JavaScript 框架。 這些工具中的每一個都有自己的優勢,並且適合不同的用例。 Tailwind CSS 擅長使用實用程式類別進行快速 UI 開發。 Styled Components 和 Emotion 是 React 應用程式中元件級樣式的理想選擇。您的選擇將取決於您的專案要求和個人喜好。 ## 7.UI元件庫 用於在 2023 年建立使用者介面的 UI 元件庫,並將在 2024 年繼續使用。 ### 1. ** Material-UI** - **網址:** [Material-UI](https://mui.com/) Material-UI 是一個受歡迎且維護良好的 React UI 框架。它基於 Google 的 Material Design 指南,並提供廣泛的元件來建立現代且具有視覺吸引力的使用者介面。 ### 2. ** Mantine** - **網址:** [Mantine](https://mantine.dev/) Mantine 是一個現代 React 元件庫,專注於提供高品質的元件和鉤子。它提供了各種 UI 元素和工具來簡化您的開發流程。 ### 3. ** Ant Design** - **網址:** [Ant Design](https://ant.design/) Ant Design 是一個用於建立企業級 React 應用程式的綜合設計系統和元件庫。它以其豐富的元件和強調自然清晰的設計理念而聞名。 ### 4. ** Chakra UI** - **網址:** [Chakra UI](https://chakra-ui.com/) Chakra UI 是在 React 中建立可存取且高度可自訂的使用者介面的熱門選擇。它提供了一組可組合元件和一個樣式道具系統,用於靈活的樣式設定。 ### 5. ** Headless UI(Tailwind CSS 框架)** - **網址:** [Headless UI](https://headlessui.com/) Headless UI 是一組完全可存取、無樣式的 UI 元件,旨在與 Tailwind CSS 無縫協作。它允許您建立可存取的介面,同時保留對樣式的完全控制。 ### 6. **DaisyUI(Tailwind CSS 框架)** - **網址:** [DaisyUI](https://daisyui.com/) DaisyUI 是 Tailwind CSS 的擴展,它帶來了額外的元件和實用程式來增強您的開發體驗。如果您已經在使用 Tailwind CSS,它會特別有用。 ### 7.**Shadcn UI(Tailwind CSS 框架)** - **網址:** [Shadcn UI](https://ui.shadcn.com/) Shadcn UI 是另一個基於 Tailwind CSS 的 UI 元件庫,它提供了一系列元件和實用程序,用於快速有效地建立 Web 應用程式。 這些程式庫提供了各種元件和工具,可協助您在 React 應用程式中建立響應靈敏且具有視覺吸引力的使用者介面。庫的選擇取決於您的專案的要求和您的個人喜好。 ## 8. 動畫 如果您對 React 動畫庫感興趣,兩個流行的選擇是: 1. **React Spring** - 您可以在 React Spring 的官方網站 [react-spring.dev](https://www.react-spring.dev/) 上找到有關 React Spring 的更多資訊和文件。 React Spring 是一個功能豐富的動畫庫,它利用基於實體的動畫在 React 中建立流暢的互動式動畫。 2. **Framer Motion** - 另一個出色的選擇是 Framer Motion,您可以在 [framer.com/motion](https://www.framer.com/motion/) 進一步探索它。 Framer Motion 因是專為 React 設計的功能豐富的動畫庫而聞名。它提供了靈活性,非常適合在 React 應用程式中建立流暢的動畫。 這兩個庫都有其優點,它們之間的選擇可能取決於您的特定專案要求和個人喜好。 React Spring 提供基於實體的動畫和豐富的功能集,而 Framer Motion 以其易用性和靈活性而聞名。最好對兩者進行探索,看看哪一個更符合您的動畫需求。 請隨意參考各自的網站以獲取詳細的文件和範例,以便做出明智的選擇。 ## 9. 資料視覺化 當涉及 React 中的資料視覺化時,有幾個函式庫可以幫助您建立互動式且資訊豐富的圖表和圖形。以下是三個流行的選項: 1. **Victory** - 您可以在 [formidable.com/open-source/victory/docs](https://formidable.com/open-source/victory/docs) 中瀏覽 Victory 的文件 Victory 是一個強大的 React 資料視覺化函式庫,提供廣泛的圖表類型和自訂選項。它旨在輕鬆建立具有視覺吸引力的互動式資料視覺化。 2. **React Chartjs 2** - 造訪 [react-chartjs-2.js.org](https://react-chartjs-2.js.org/) 以了解更多資訊。 React Chartjs 2 是 Chart.js(一個流行的 JavaScript 圖表庫)的 React 包裝器。它提供了一種將 Chart.js 整合到 React 應用程式中的簡單方法,可讓您使用 Chart.js 的底層功能建立各種圖表和圖形。 3. **Recharts** - 有關Recharts的詳細訊息,您可以參考[recharts.org/en-US/](https://recharts.org/en-US/)。 Recharts 是一個使用 React 建立的可組合圖表庫。它提供了一個簡單而靈活的 API 來建立各種類型的圖表,非常適合將資料視覺化加入到您的 React 專案中。 每個庫都有自己的一組功能和優點,因此選擇將取決於您的特定專案要求和個人喜好。您可以存取他們各自的文件以了解更多資訊並開始使用 React 中的資料視覺化。 ## 10. 表 如果您正在尋找有關 React 中表格的訊息,可以在 [tanstack.com/table/v8](https://tanstack.com/table/v8) 上瀏覽版本 8 的 TanStack Table 文件。 TanStack Table 是一個無頭 UI 庫,可讓您在 TS/JS、React、Vue、Solid 和 Svelte 等各種框架中建立強大的表格和資料網格,同時保留對標記和樣式的控制。該文件將為您提供有關如何使用 TanStack Table 和配置表的詳細訊息,包括選項和 API 屬性。 無論您使用 TypeScript 還是 JavaScript 以及使用受支援的框架之一,TanStack Table v8 都提供了一種靈活的解決方案,用於在 Web 應用程式中建立表格和資料網格。該文件將引導您完成整個過程,並幫助您充分利用該庫來滿足您的特定需求。 ## 11. 國際化(i18n) 當涉及 React 應用程式中的國際化 (i18n) 時,有多個程式庫和工具可協助您管理翻譯和在地化。 React 中 i18n 的兩個突出選項是: 1. **i18next** - 您可以在 [react.i18next.com](https://react.i18next.com/) 找到使用 i18next 的文件和資源。 i18next 是一個流行的 JavaScript 國際化框架,包括 React。它提供了處理翻譯、格式化等的全面解決方案。 2. **React-Intl (Format.js)** - React-Intl 的文件是 Format.js 專案的一部分,可以在 [formatjs.io/docs/react-intl](https://formatjs.io/docs/react-intl)。 React-Intl 是一個函式庫,提供用於在 React 應用程式中格式化和處理國際化文字的工具。 這兩個函式庫都有活躍的社群、豐富的文件,並且在 React 生態系統中廣泛使用。您可以探索這些資源,以確定哪一個最適合您的 React 應用程式國際化需求。 ## 12. 開發工具 DevTools 對於偵錯和改進 Web 應用程式的開發工作流程至關重要。以下是一些流行的 React 開發工具和相關函式庫: 1. **React 開發者工具** - 該工具可作為 Chrome 擴充功能使用。它允許您檢查 React 元件層次結構、查看元件的狀態和 props,甚至更改元件的狀態以進行測試。您可以從 [Chrome Web Store](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) 安裝它。 2. **Redux DevTools** - Redux DevTools 是另一個 Chrome 擴展,可以增強 Redux 開發工作流程。它提供了對 Redux 儲存的深入了解,讓您可以檢查操作和狀態變更、倒回和重播操作等。您可以從 [Chrome Web Store](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd) 安裝它。 3. **Testing Playground** - Test Playground 是一個 Chrome 擴展,可以簡化 React 元件的測試。它提供了一個用於試驗元件及其道具的視覺環境。您可以在 [Chrome 線上應用程式商店](https://chrome.google.com/webstore/detail/testing-playground/hejbmebodbijjdhflfknehhcgaklhano) 上找到它。 4. **React Hook Form DevTools** - 對於使用 React Hook Form 的用戶,可以使用 DevTools 來協助偵錯表單行為。您可以在 [React Hook Form 網站](https://www.react-hook-form.com/dev-tools/) 上存取它們。 5. **TanStack Query DevTools** - TanStack Query 是 React 的資料擷取庫,它提供用於偵錯和檢查查詢和突變的 DevTools。您可以參考[官方文件](https://tanstack.com/query/v4/docs/react/devtools)以了解更多資訊。 這些開發工具可協助開發人員簡化開發和偵錯流程,從而更輕鬆地建置和維護 Web 應用程式。 ## 13. 文件 文件對於任何軟體專案都至關重要。以下是用於建立文件的兩種流行工具: 1. **Docusaurus** - Docusaurus 是一種廣泛採用的用於建立文件網站的工具。它是一個開源框架,為建立和維護文件提供了乾淨且用戶友好的介面。 Docusaurus 具有高度可自訂性,許多專案和組織都使用它來建立文件網站。您可以在 Docusaurus 的[官方網站](https://docusaurus.io/)上了解更多並開始使用 Docusaurus。 2. **Nextra** - Nextra 是建立文件網站的另一種選擇。雖然 Nextra 可能不像 Docusaurus 那樣出名,但它提供了一種現代且簡約的方法來建立文件。它的設計是輕量級且用戶友好的,對於那些喜歡簡單乾淨的文件風格的人來說是一個不錯的選擇。您可以在 Nextra 的[官方網站](https://nextra.site/) 上探索有關 Nextra 的更多資訊。 Docusaurus 和 Nextra 都有各自的優勢,它們之間的選擇取決於您的特定需求和偏好。您可以存取他們各自的網站以了解更多資訊、存取文件並確定哪一個最適合您的專案。 ## 14. 元件開發環境 元件開發環境 (Dev Env) 對於有效建置和測試 UI 元件至關重要。用於為 UI 元件建立開發環境的廣泛使用的工具之一是 [Storybook](https://storybook.js.org/)。 Storybook 是業界標準的元件瀏覽器,可讓開發人員獨立開發 UI 元件。當處理設計系統或元件庫時,它特別有價值。以下是 Storybook 如何協助建立 UI 元件的開發環境: 1. **目錄 UI 元件**:Storybook 提供了用於編目和顯示 UI 元件的專用環境。開發人員可以單獨查看每個元件的外觀和行為。 2. **將元件變體儲存為故事**:在 Storybook 中,開發人員可以為每個元件建立「故事」。這些故事代表元件的不同變體或用例。這是記錄和展示元件行為的絕佳方式。 3. **開發人員體驗工具**:Storybook 提供了一系列開發人員體驗工具,包括熱模組重新加載,以簡化元件開發流程。 透過使用 Storybook,您可以有效率地開發、測試和記錄 UI 元件。它在設計系統時特別有用,因為它允許您專注於單個元件及其互動。您可以在 Storybook 的[官方網站](https://storybook.js.org/) 上了解更多並開始使用。 它是一種多功能工具,可以根據專案的特定需求進行定制,使其成為元件開發環境的寶貴資產。 ## 15. 類型檢查 TypeScript 是 Microsoft 開發的一種程式語言,透過新增靜態類型來擴充 JavaScript。它提供全面的類型檢查和強大的類型系統,以捕獲開發過程中的錯誤並提高程式碼品質。以下是 TypeScript 中類型檢查的一些關鍵方面: 1. **靜態型別系統**:TypeScript 引進了靜態型別系統,這表示在編譯時檢查類型。這有助於在執行程式碼之前辨識與類型相關的錯誤。 2. **型別註解**:開發者可以使用型別註解來指定變數、函數參數和傳回值的型別。這提供了清晰度並確保變數的使用一致。 3. **推斷**:TypeScript 可以根據指派給變數的值推斷類型。這減少了對顯式類型註解的需求並提高了程式碼簡潔性。 4. **類型聲明**:TypeScript支援自訂類型的聲明,例如介面和枚舉,以定義資料結構的形狀並增強程式碼的可維護性。 5. **類型相容性**:TypeScript 有一個檢查類型相容性的系統,這確保你不能將不相容的類型指派給變數。這有助於防止常見的執行時錯誤。 6. **對 JavaScript 文件進行類型檢查**:TypeScript 還可以檢查 JavaScript 文件,讓您可以逐步將 TypeScript 引入現有的 JavaScript 專案中。 透過將 TypeScript 合併到您的開發工作流程中,您可以從這些類型檢查功能中受益,從而儘早發現錯誤、增強程式碼可維護性並提高程式碼的整體品質。您可以在[官方 TypeScript 網站](https://www.typescriptlang.org/) 上了解有關 TypeScript 及其類型檢查功能的更多資訊。 ## 16. 行動應用程式 如果您想要開發行動應用程式,特別是 Android 和 iOS 的行動應用程式,React Native 是一個值得考慮的有價值的框架。 React Native 是一個開源框架,可讓您使用 JavaScript 和 React 建立行動應用程式。這就是 React Native 成為行動應用程式開發的熱門選擇的原因: 1. **跨平台開發**:React Native 使您能夠使用單一程式碼庫開發適用於 Android 和 iOS 的應用程式。這種方法可以顯著減少開發時間和工作量。 2. **可重複使用元件**:您可以建立跨平台工作的可重複使用 UI 元件,幫助您在應用程式中保持一致的外觀和感覺。 3. **熱重載**:React Native 支援熱重載,這意味著您可以立即看到程式碼變更的結果,而無需重新編譯整個應用程式。這加快了開發速度。 4. **大型社區**:React Native 擁有龐大且活躍的社區,這意味著您可以找到豐富的資源、庫以及常見問題的解決方案。 5. **本機效能**:React Native 應用程式具有接近本機的效能,因為它們使用本機元件進行渲染。這確保了流暢的用戶體驗。 6. **成本效益**:透過在 Android 和 iOS 之間共用程式碼庫,您可以降低開發成本。 要開始使用 React Native,您可以造訪官方網站 [React Native](https://reactnative.dev/) 以取得全面的文件、教學和資源。無論您是初學者還是經驗豐富的開發人員,React Native 都是行動應用程式開發的強大選擇。 ## 17. 為 React 開發人員提供的很棒的函式庫 很高興看到您對 React 開發人員的優秀庫感興趣。以下是一些非常有用的程式庫,可用於 React 開發中的各種功能: ### 1. **用於拖放功能的 DND 套件** - 網址:[DND Kit](https://dndkit.com/) DND Kit 是一個強大的庫,用於為 React 應用程式加入拖放功能。它提供了一種簡單且可自訂的方法來實現拖放功能,以便在使用者介面中重新排序、重新排列或組織元素。 ### 2. **React Dropzone 用於檔案上傳** - 網址:[React Dropzone](https://react-dropzone.js.org/) React Dropzone 是一個流行的程式庫,用於在 React 應用程式中處理檔案上傳。它提供了一個用戶友好且高度可自訂的 dropzone 元件,簡化了上傳文件的過程,使其成為任何需要文件上傳的專案的有價值的補充。 ### 3. **Firebase 用於身份驗證** - 網址:[Firebase](https://firebase.google.com/) Firebase 由 Google 開發,是一個用於建立 Web 和行動應用程式的綜合平台。它提供廣泛的服務,包括用戶身份驗證。透過 Firebase 驗證,您可以輕鬆地將安全的使用者註冊和登入功能新增到您的 React 應用程式中。 ### 4. **Supabase 用於身份驗證** - 網址:[Supabase](https://supabase.com/) Supabase 是 Firebase 的開源替代品,提供一套用於建立應用程式的服務,包括身份驗證。它提供了可以無縫整合到您的 React 專案中的用戶身份驗證功能。 這些程式庫涵蓋了 React 開發的基本面,包括拖放功能、檔案上傳和使用者身份驗證。根據您的專案要求,您可以利用這些程式庫來增強您的 React 應用程式。 **免責聲明:**“本文是在人工智慧的幫助下建立的”

JS教學-文章縮圖預覽,夢幻連動的腳本教學!

## 前情提要 常常寫文章的時候都會運用到圖文並茂, 如果可以設定文章的圖片封面就是一個很棒的設計。 今天的JS腳本教學已經夢幻連動! 原本IT幫的文章與codeLove像是平行宇宙,只有偶爾轉載,現在, 教學內容直接來針對codelove來寫一個小小有趣小功能XD ## 目標設計 今天以codelove這個論壇為例, 讓我們來手動創造一個小腳本:分析文章內容,以正則去匹配圖片網址, 然後透過create的API寫出div,並且監聽事件, 當點擊圖片的時候,把圖片網址放到封面圖片的input欄位。 ## 效果 會根據textArea change的時候來匹配出網址。 並且創建div與img元素去放入網頁。 ![](https://i.imgur.com/sHcMDU8.png) 點圖片後會把圖片網址丟入。 ![](https://i.imgur.com/MWhkOB7.png) ## 程式碼內容 ``` // 獲取textarea元素 var textarea = document.querySelector("body > div.container.px-0 > div > div.col-12.col-lg-9 > div > div > form > textarea"); var featuredImageInput = document.querySelector('input[name="featured_image"]'); textarea.addEventListener('change', function(event) { // 檢查是否存在imgBox元素 let imgBoxCheck = document.querySelector('.imgBox'); if (imgBoxCheck) { // 如果存在,則刪除imgBox元素 imgBoxCheck.parentNode.removeChild(imgBoxCheck); } // 獲取文本框的內容 var ContentText = textarea.value; // 創建一個空數組來存儲圖片鏈接 var imgArray = []; // 使用正則表達式查找圖片鏈接 var urlRegex = /https?:\/\/[^\s/$.?#].[^\s]*/gi; // 匹配以http或https開頭的鏈接 var matches = ContentText.match(urlRegex); if (matches) { // 疊代所有匹配項並篩選出以.png或.jpg結尾的鏈接 for (var i = 0; i < matches.length; i++) { if (matches[i].match(/\.(png|jpg)$/i)) { imgArray.push(matches[i]); } } } // 使用正則表達式匹配鏈接部分 var regex = /!\[\]\(([^)]+)\)/g; var match; while ((match = regex.exec(ContentText)) !== null) { imgArray.push(match[1]); } // 創建一個包含圖片的容器div(imgBox)並設置為display: flex let imgBox = document.createElement('div'); imgBox.className = 'imgBox'; // 添加類名 imgBox.style.display = 'flex'; // 平均分配圖片大小 var imageSize = 100 / imgArray.length; // 假設100%寬度,根據圖片數量計算每張圖片的寬度 // 將圖片鏈接轉換為img元素並插入到imgBox imgArray.forEach(function (imgUrl) { var imgDiv = document.createElement('div'); var img = document.createElement('img'); img.src = imgUrl; img.className = 'imgCover'; img.addEventListener('click', function () { // 設置name="featured_image"的輸入框的值為被點擊圖片的src屬性 featuredImageInput.value = img.src; }); // 設置img的寬度為100% img.style.width = '100%'; img.style.height = '100%'; imgDiv.appendChild(img); imgBox.appendChild(imgDiv); }); // 將imgBox插入到textarea後面 h5.insertAdjacentElement('afterend', imgBox); textarea.style.overflow = 'auto'; imgBox.style.border="5px solid gray" imgBox.style.marginTop="5px" }); // 創建一個包含CSS規則的<style>元素 var style = document.createElement('style'); style.type = 'text/css'; style.textContent = '.imgBox:hover .imgCover:not(:hover) { filter: grayscale(100%); opacity: 0.75; }'; // 將<style>元素添加到<head>中 document.head.appendChild(style); h5= document.createElement('h5') h5.innerText='請選擇你的文章縮圖:' h5.style.marginTop="50px" h5.style.fontSize="16px" textarea.insertAdjacentElement('afterend', h5); ``` ## 觀念筆記 這次的腳本內容其實沒有太多新的知識點,算是一個很好的複習。 querySelector addEventListener insertAdjacentElement forEach 以及正則表達式的使用。 ## 心得後記 網頁上的功能,其實就是這些基礎的運用配合起來!(°ཀ°) 所以不用擔心前端沒有東西練習,其實點子四處都有,練習也都很實用。 而不是每次都在重複輪迴相同的東西、感到疲倦! 這次的前端小試身手就帶來一個回鍋菜,下次敬請期待更有趣的變化。 喜歡記得追蹤或留言唷。 還沒挑戰過此系列其他內容的,可以試著去挑戰看看◑ω◐

前端可以這樣玩??JS腳本-IMG複製大師,懶人專用小腳本

## 轉載自 https://ithelp.ithome.com.tw/articles/10338052 ## 前情提要 有時候我們需要使用一些圖片,勢必需要圖片的網址,這時候, 也許你可以本機上傳,然後去把網址抓好, 又或者你可以找到網路上別人的圖片,右鍵開啟新分頁,再複製網址; 又或者直接打開檢查(F12)找到src的網址去複製。 光聽這個流程我就覺得,心累。 這時候前端大師,就會寫一套簡單的小腳本來完成這個白爛的工作。 ## 腳本下載 ![](https://i.imgur.com/D1s1kxi.png) https://greasyfork.org/zh-TW/scripts/477141-img%E8%A4%87%E8%A3%BD%E5%A4%A7%E5%B8%AB ## JS程式碼 ``` // ==UserScript== // @name IMG複製大師 // @namespace http://tampermonkey.net/ // @version 0.1 // @description 針對網頁上圖片,點擊就複製其網址 // @author You // @match *://*/* // @icon https://www.highcharts.com/demo/highcharts/spline-plot-bands // @grant none // ==/UserScript== let isEventActive = false; // 用於跟蹤事件的狀態 // 創建一個鏈接元素並設置其屬性 const toastrCssLink = document.createElement('link'); toastrCssLink.rel = 'stylesheet'; toastrCssLink.href = 'https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css'; // 創建一個腳本元素並設置其屬性 const toastrScript = document.createElement('script'); toastrScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'; // 創建另一個腳本元素並設置其屬性 const toastrScript2 = document.createElement('script'); toastrScript2.src = 'https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js'; // 將鏈接元素和腳本元素添加到文檔頭部 document.head.appendChild(toastrCssLink); document.head.appendChild(toastrScript); document.head.appendChild(toastrScript2); // 獲取頁面上的所有img元素 const images = document.querySelectorAll('img'); function removeClickHandler(image) { image.removeEventListener('click', clickHandler); } function toggleEvent() { if (isEventActive) { // 如果事件已經激活,則關閉事件 console.log('IMG複製大師關閉ꐦ°᷄д°᷅'); // 解除事件監聽 images.forEach(removeClickHandler); isEventActive = false; } else { // 如果事件尚未激活,則打開事件 console.log('IMG複製大師啟動ฅ^•ﻌ•^ฅ'); // 遍歷所有img元素 images.forEach((image) => { // 檢查圖像是否已加載 if (image.complete) { // 圖像已加載,直接添加點擊事件處理程序 addClickHandler(image); } else { // 圖像尚未加載,等待加載完成後再添加點擊事件處理程序 image.addEventListener('load', () => { addClickHandler(image); }); } }); isEventActive = true; } } document.addEventListener('keydown', (event) => { if ((event.key === 'q' && event.ctrlKey) || event.key === 'F8') { toggleEvent(); // 切換事件的狀態 } }); function transformImageUrl(url) { // 使用正則表達式匹配URL中的目標部分 const regex = /https:\/\/cache.ptt.cc\/c\/https\/i.imgur.com\/([^?]+)/; const match = url.match(regex); if (match) { // 如果匹配成功,構建新的URL const imgurId = match[1]; return `https://i.imgur.com/${imgurId}`; } else { // 如果沒有匹配到目標部分,返回原始URL return url; } } // 創建一個函數,用於添加點擊事件處理程序並處理圖像的src function addClickHandler(image) { image.addEventListener('click', clickHandler); } // 創建一個函數,用於處理點擊事件 function clickHandler() { let src = this.src; src = transformImageUrl(src); const textArea = document.createElement('textarea'); textArea.value = src; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); // 使用 toastr 進行通知 toastr.success('網址複製完成: ' + src); } ``` ## 觀念筆記 這個小腳本總共使用了大概三種觀念, 第一種就是toast的套件使用, 第二個是監聽鍵盤做開關, 第三個則是程式本身對於img的監聽,把src複製到剪貼簿。 ### 第一部分:套件 使用套件在於腳本,必須利用appendChild,先使用create的API製作出放置CDN的link元素, 再把它append到網頁上,則可以使用其套件。 ### 第二部分:監聽鍵盤 這腳本啟動與關閉是透過監聽鍵盤的,ctrl+q或F8這部分就是純粹監聽。 ``` document.addEventListener('keydown', (event) => { if ((event.key === 'q' && event.ctrlKey) || event.key === 'F8') { toggleEvent(); // 切換事件的狀態 } }); ``` 裡面寫了一個toggleEvent是因為想要設定可以開開關關。 ### 第三部分:程式本身 這邊有一點小技巧是複製到剪貼簿,其實以前文章也有寫過教學,是個常見實用的招數: ``` const textArea = document.createElement('textarea'); textArea.value = src; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); ``` 再來就是針對網頁上全部的img元素,去監聽點擊事件、移除事件這兩個。 ``` const images = document.querySelectorAll('img'); function addClickHandler(image) { image.addEventListener('click', clickHandler); } function removeClickHandler(image) { image.removeEventListener('click', clickHandler); } ``` 之後這兩個事件要寫在toggle裡面,當開啟的條件就執行新增事件;關閉就執行解除綁定 開啟也就是: ``` images.forEach((image) => { // 檢查圖像是否已加載 if (image.complete) { // 圖像已加載,直接添加點擊事件處理程序 addClickHandler(image); } else { // 圖像尚未加載,等待加載完成後再添加點擊事件處理程序 image.addEventListener('load', () => { addClickHandler(image); }); ``` 關閉則是: `images.forEach(removeClickHandler);` ## 心得 這次的小腳本功能非常簡單,寫起來邏輯也是很清晰透明,沒有什麼彎曲。 雖然簡單,但是寫起來功能非常實用! 這就是針對懶人專用的! 其實沒有人規定前端這種東西要寫得多大,多了不起/ᐠ。ꞈ。ᐟ\ 好像你很屌、很懂前端、框架,那個是一回事,能夠完成自己的需求也很美好。 很久沒更新了,這次的酷酷小腳本應該很爽⁽⁽٩(๑˃̶͈̀ ᗨ ˂̶͈́)۶⁾⁾ 好好的來玩前端吧,未來還有更大的宇宙!

回答網友提問:雲科碩畢,上班中,考慮轉職軟體工程師,請問有建議嗎?

阿川收到網友提問如下: > 阿川你好: > 我的背景是雲科碩畢業,算是混上去的,現在打算轉職軟工,由於有在工作,所以打算先以自學為主3-6個月,看情況後決定是否報名資策會。 > 想請問一下,目前比較希望能夠走後端(網頁開發類),查了一些相關資訊,網頁似乎比較友善,未來有機會再往其他產業前進! > 搜尋了一下職務,網頁類的後端其實也需要html css js 前端三本柱。 > 我想問的是: > 1.是否直接開始學三本柱比較好?(反正前面的作品、入職也會需要)且 有了js基礎還能繼續學習node.js(後端)。 不過又礙於可能比較沒方向,會變成說學一學越來越往前端過去? > 2.先以門檻較低的前端入門、入職以後再好好思考想專精哪一端之類的 or 以c#為主學習,再慢慢學三本柱,資料庫等等 > 3.前端的切版技術等等,是否真的必要? 本人美感很差.. 兩個問題的考量的都是想說是否先以java,c#等後端去建立程式概念或許比較好。 > 文有點長,再麻煩您給我一些建議了,也想順便問一下,有看到您有提供免費html css 以及付費js課程,能在跟您要這方面的資訊嗎? 這些問題很好,我一樣公開回答,給類似狀況的人參考。 --- 簡單回答如下: 1、不論前後端 html 跟 css 都要會,所以這兩個可以先學。js 的話後端不用學精,稍微會寫就好,除非你是寫 node 至於最後會去前端或後端的職缺,都可以,先不用擔心這個,不然你就找全端的職缺也可以 2、後端需要學資料庫、基本伺服器管理,語言的話 C# 或 java 或 php 或 python 或 node 之類的都可以 3、前端做久了,因為常常跟設計師合作,會慢慢具備一點設計素養。如果對「UI 設計」有興趣是最好,沒有的話,倒也沒關係。美感可以慢慢訓練,先不用畫地自限 --- 總結來說,我建議你就先學 html 與 css,之後再看你用 html css 把網頁寫漂亮有沒有興趣,如果喜歡把畫面弄漂亮,就多學一點前端。如果只想做工程,就專心在後端吧。這些問題學了 html css 之後會更清楚,先不用太糾結。不然你就以全端為方向也可以,前後端都寫!你就先挑一個免費 or 便宜的線上課程,先開始寫寫看再說 先開始行動,會更清楚自己在做什麼,之後需要花大錢去報名補習班時,也會比較有把握 就算你一開始只寫前 or 後端,很多人上班之後,因為工作需求,還是慢慢有具備全端的技能 其實不用太排斥全端,都寫的話,一來在公司能做的事情變多、能應徵的機會變多,二來還可以自己用業餘時間寫 side project,因為一個人就能做完全部事情,所以會很好玩,也對職業生涯很有幫助 關於我設計的免費 html css 教材,請參考:https://codelove.tw/courses/frontend-beginner 另外,轉職過程會有諸多問題,可以加我們 LINE 群多跟大家討論:https://line.me/ti/g2/nipkjq2WoZPKX5dTn9tE9266aEOt6EOICFGa1g --- 以上,簡單分享,希望對大家有幫助!

【前端動手玩創意】動態生成的藝術|小心,亂改DOM你可能會被打臉。

## 目錄 ##### [【前端動手玩創意】等待的轉圈圈效果 (1)](https://ithelp.ithome.com.tw/articles/10311621) ##### [【前端動手玩創意】google五星評分的星星(2)](https://ithelp.ithome.com.tw/articles/10311643) ##### [【前端動手玩創意】CSS-3D卡片翻轉效果(3) (今天難度頗高,想挑戰再進來!)](https://ithelp.ithome.com.tw/articles/10311672) ##### [【前端動手玩創意】一句CSS做出好看的hero section!(4)](https://ithelp.ithome.com.tw/articles/10311691) ##### [【前端動手玩創意】創造一個Skill bar(5)](https://ithelp.ithome.com.tw/articles/10311756) ##### [【前端動手玩創意】遮蔽廣告(D卡未登入)腳本、自定義新增名單(6)](https://ithelp.ithome.com.tw/articles/10311999) ##### [【前端動手玩創意】前端canvas截圖的招式!竟然有三招,可存成SVG或PNG (7)](https://ithelp.ithome.com.tw/articles/10312001) ##### [【前端動手玩創意】讓你的PDF檔案更難被抓取(8)](https://ithelp.ithome.com.tw/articles/10312046) ##### [【前端動手玩創意】哇操!你敢信?花式寫todo-list,body裡面一行都沒有也能搞?(9)](https://ithelp.ithome.com.tw/articles/10312056) ##### [【前端動手玩創意】卡片製作,才不是!是卡片製作器!(10)](https://ithelp.ithome.com.tw/articles/10312066) ##### [【前端動手玩創意】太屌了吧!?用Class(類)製作Jquery的效果!(11)](https://ithelp.ithome.com.tw/articles/10312114) ##### [ 【前端動手玩創意】置頂按鈕,老梗經典|帶你的網頁搭電梯(12)](https://ithelp.ithome.com.tw/articles/10312922) ## 前情提要 一陣子沒寫前端動手玩創意了 今天要來點好料的 我們談談關於藝術 對 就算是寫程式我們也是可以有藝術氣息的 別這麼驚訝XD 假設我有一組資料 一般人來說 最直覺的就是把html裡面的元素寫出來寫死 直覺菜鳥就是寫出來啊 ``` <div id="items_list"> <li class="buy_item">1.紅茶 <div class="price">10</div> <div class="del_btn">X</div> </li> <li class="buy_item">2.奶茶 <div class="price">15</div> <div class="del_btn">X </div> </li> <li class="buy_item">3.綠茶 <div class="price">30</div> <div class="del_btn">X</div> </li> </div> ``` 要更新則是就去更改DOM就好了 反正我都學會JS了 有什麼大不了(? 但是現在已經進入大前端時代了就算你寫原生 也會有data model的概念 這部分可以參考站長阿川寫過的好文 裡面的文筆跟邏輯 不誇張 是我見過「華文圈寫得最好的前端教學」 尤其就是這篇 關於data model的介紹 切入點非常的有趣也很有道理 有興趣的自己去花心思讀看看 [認識 data model 與 render function](https://codelove.tw/@howtomakeaturn/post/9xLo5q) 稍微有點料的前端學習者 本身就會寫一寫 想說:既然有一隻API是createElement 那是不是我可以整個html都用js寫出來(? 這是個超級有趣的觀點 ## 關於data render的概念: 「是不是我可以整個html都用js寫出來」 相傳牛頓提出三大定律以後 認為地球和八大行星一開始的慣性力叫「上帝的第一推動力」 實際上這個: 「整個html都用js寫出來」 也是推動前端往框架邁進的思考第一步 可以說是前端慣性的上帝推力了 當然如果你有打籃球 也可以比喻成上籃的第零步XD ## 觀念筆記 ### html程式碼 ``` <div id="buylist"> <h1>myBuylist 購物清單</h1> <div class="buyitem"> <label>產品名</label> <input/> <label>價錢</label> <input/><span class="addbtn">+新增</span> </div> <div id="items_list">這邊準備用JS插入東西所以這段只是說明文字</div> </div> ``` 把整個頁面的元素寫出來 但是資料的區塊保留著 因為等等我們要用JS的API去動態生成 未來直接data render 方便更新與管理 ### JS程式碼 ``` var shoplist = {}; shoplist.name = "購物清單"; shoplist.list = [ { name: "吹風機", price: "300" }, { name: "麥克筆", price: "20" }, { name: "筆記型電腦", price: "29300" }, { name: "Iphone 9", price: "5200" }, { name: "神奇海螺", price: "1000" }, ]; var item_html = "<li id={{id}} class='buy_item'>{{name}}<div class='price'>{{price}}</div><div class='del_btn'>X</div></li>"; var total_html = "<li class='buy_item total'>總價<div class='price'>{{price}}</div><div class='del_btn'>X</div></li>"; var total_price = 0; for (var i=0; i < shoplist.list.length; i++) { var item = shoplist.list[i]; total_price += item.price; var current_item_html = item_html.replace("{{num}}", i + 1) .replace("{{name}}", item.name) .replace("{{id}}", "buyitem_" + i) .replace("{{price}}", item.price); $("#items_list").append(current_item_html); } ``` 這邊值得關注的一點是資料的處理 也就是數據結構上使用物件與陣列去儲存資料 為什麼要學 陣列 為什麼要學物件 這兩個都是抽象的名詞 他們都是為了來處理資料所規劃的兩種不同內容 ## 關於物件與陣列 物件就像是RPG角色 會有很多的屬性 魔法 敏捷 力量 血量 這些屬性都是被附加在person上面 所以person.blood是一個資料 person.power是一個資料 person.magic是一個資料 最後都存在person裡面 這個person就是一個含有很多屬性的物件 感覺就是有血有肉很3D 而陣列就比較平面化 就是很多數字排成一列而已 其實沒什麼特別需要關注的 這兩個也不會不好區分 只要稍微做個比喻 都很好理解 以我們的code來講解 shoplist就是一個物件 含有一些屬性 包含名字與清單 因為清單很多 所以清單用一個陣列儲存 陣列裡面放很多個物件 這些物件就是每一個清單包含的那些購買項目 其實不用太在意誰是誰因為用看的就很清楚 最後我們用迴圈去把shoplist裡面的每一筆資料都丟進去 中途replace是文字處理 把我們設置的{{name}}這種花括號的東西換成真實資料 這部分有點樣板語言的感覺XD 其實非常有趣 很值得玩味 ## 心得 這次比較多實在的JS程式碼 就不只是玩玩切版了 算是有點靠近框架的部分(◉3◉) 動手玩創意這個系列其實靈魂之處就在於「有趣」兩個字 坊間把前端描繪成為了找工作的銅臭味 以及把切版講成無聊的工匠苦力活 我認為都是錯誤的解讀 我認為 只要是有趣的地方就是前端最有價值的地方 而不是誰學了那個框架 誰又認為哪個東西比較厲害 哪個語言比較屌 那都是很無聊的文字遊戲罷了 如果你喜歡這樣子的前端 請跟著這個系列繼續走(→ܫ←) 我們才只是在桃花源外的小溪旁玩水而已呢! 未來會往天空飛翔哦XD

回答網友提問:32歲非本科考慮轉職工程師,壓力很大,怎麼辦?

阿川收到網友提問如下: ``` 我最近有在看前端的一些基礎課程,想問問如果32歲想轉職工程師是不是不吃香😅畢竟我也不是本科的 ``` 看過很多人提出類似問題,寫一篇公開回答跟大家分享,給類似狀況的人參考。 --- 首先我自己親自指導過轉職的,年齡最大的是31歲、非本科、私立科大夜間部,原本在餐飲業 在網路上搜尋「30歲轉職工程師」、「40歲轉職工程師」、「50歲轉職工程師」 會發現30歲相關文章很多,大家議論紛紛 40歲相關文章比較少,持鼓勵、正面意見的佔少數 50歲相關文章,一篇心得分享都沒有 我建議把幾歲轉職當成是一個「漸層問題」,不是非黑即白的「二元問題」 也就是年紀越大越難,但沒有過了幾歲就一定不行這種事 --- 再來我認為要務實一點,不論自學或上課,半路出家至少也需要2個月~6個月的時間 請減少生活開銷,然後原本工作可以的話,先別辭掉,利用晚上&週末的時間進修,壓力也小一點 不然壓力大到睡不著覺的話,精神不佳,學習效果怎麼會好呢? 然後建議多找幾種學習方法試試看,如果一種不行,就換另一種方法試試 別太快覺得「自己不行」,說不定是「老師不行」,或只是方法不適合你 我建議先大量找免費或便宜的教材,先吸收,多試幾份,真的卡關了,再開始挑補習班 先直接找一些作業跟專案寫寫看,從免費 -> 便宜的 -> 稍貴的,這樣一點一點花錢,風險比較小 更認識自身需求之後,再去比較市面上的各種補習班,最後再把這錢花下去,比較保險 --- 最後我必須說,2023 全球軟體業狀況比較嚴峻,目前職缺好像比較緊縮,不知道何時會恢復 這跟 2008 年金融海嘯出社會的新鮮人狀況一樣,就是比較倒霉 反正轉職過程中,記得早點開人力銀行等等網站,看看職缺狀況,心裡有個底,知道一下要面臨多少競爭 順帶一提,我也有設計免費的 html&css 教材,還有優惠的 javascript 教材,內含「大量練習專案」,不論你最後選擇哪種學習方式,我都推薦搭配拿去學習、練習,稍有難度,但不少人全做完之後就順利面試上班了 以上,祝各位轉職順利!

一位資深軟體工程師的 VSCode 設定方式&外掛套件分享

資深開發者 Jatin Sharma 在國外論壇分享了個人使用的 VSCode 設定,內容豐富,跟大家分享! 原文出處:https://dev.to/j471n/my-vs-code-setup-971 ## 🎨主題 我使用 [**Andromeda**](https://marketplace.visualstudio.com/items?itemName=EliverLara.andromeda) 作為我的 VS Code 的主要主題 ![andromeda-截圖](https://res.cloudinary.com/practicaldev/image/fetch/s--bw_aagIQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/EliverLara/Andromeda/raw/master/images/andromeda.png) ## 🪟圖標 對於圖標,我會在 [**材質圖標主題**](https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme) 和 [**材質主題圖標**]( https://marketplace.visualstudio.com/items?itemName=Equinusocio.vsc-material-theme-icons) **找找看。** ### 材質圖標主題 ![材質圖標主題](https://i.imgur.com/xA90m2X.png) ### 材質主題圖標 ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1675233057115/b8d1623c-a092-475e-a66a-91b4a42e5441.png) ## ⚒️外掛 最讚的部分來了,有很多擴展我只提到了我最喜歡的或我每天主要使用的擴展。 ### 自動重命名標籤 自動重命名配對的 HTML/XML 標記,與 Visual Studio IDE 的操作相同。 **下載:** [**自動重命名標籤**](https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag) ![](https://github.com/formulahendry/vscode-auto-rename-tag/raw/HEAD/images/usage.gif) ### 括號對著色切換器 VS Code 擴展,為您提供一個簡單的命令來快速切換全局“括號對著色” **下載:** [**括號對著色切換器**](https://marketplace.visualstudio.com/items?itemName=dzhavat.bracket-pair-toggler) ![](https://github.com/dzhavat/bracket-pair-toggler/raw/HEAD/assets/bracket-pair-toggler-demo.gif) ### C/C++ C/C++ 擴展向 Visual Studio Code 加入了對 C/C++ 的語言支持,包括編輯 (IntelliSense) 和除錯功能。 **下載:** [**C/C++**](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) ![](https://i.imgur.com/0syu1Ym.png) ### 程式碼執行器 執行多種語言的程式碼片段或程式碼文件 **下載:** [**程式碼執行器**](https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner) ![用法](https://github.com/formulahendry/vscode-code-runner/raw/HEAD/images/usage.gif) ### 程式碼拼寫檢查器 一個基本的拼寫檢查器,可以很好地處理程式碼和文件。 該拼寫檢查器的目標是幫助發現常見的拼寫錯誤,同時保持較低的誤報數量。 **下載:** [**程式碼拼寫檢查器**](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) ![示例](https://raw.githubusercontent.com/streetsidesoftware/vscode-spell-checker/main/images/example.gif) ### DotENV VSCode `.env` 語法高亮。 **下載:** [**DotENV**](https://marketplace.visualstudio.com/items?itemName=mikestead.dotenv) ![示例](https://github.com/mikestead/vscode-dotenv/raw/master/images/screenshot.png) ### 錯誤鏡頭 ErrorLens 通過使診斷更加突出來增強語言診斷功能,突出顯示語言生成的診斷的整行,並內聯打印訊息。 **下載:** [**錯誤鏡頭**](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens) ![演示圖片](https://raw.githubusercontent.com/usernamehw/vscode-error-lens/master/img/demo.png) ### ES7+ React/Redux/React-Native 片段 ES7+ 中的 JavaScript 和 React/Redux 片段以及 [VS Code](https://code.visualstudio.com/) 的 Babel 插件功能 **下載:** [**ES7+ React/Redux/React-Native 片段**](https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets) ![](https://i.imgur.com/cYpm6cw.png) ### ESLint 該擴展使用安裝在打開的工作區文件夾中的 ESLint 庫。如果該文件夾未提供,則擴展程序將查找全局安裝版本。如果您尚未在本地或全局安裝 ESLint,請在工作區文件夾中執行“npm install eslint”進行本地安裝,或執行“npm install -g eslint”進行全局安裝。 **下載:** [**ESLint**](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) ![](https://i.imgur.com/R3o4517.png) ### Git 圖 查看存儲庫的 Git 圖表,並從圖表中輕鬆執行 Git 操作。可配置為您想要的外觀! **下載:** [Git Graph](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph) ![Git Graph 記錄](https://github.com/mhutchie/vscode-git-graph/raw/master/resources/demo.gif) ### GitLens GitLens **增強了 VS Code 中的 Git,並解鎖每個存儲庫中**未開發的知識**。它可以幫助您通過 Git Blame 註釋和 CodeLens 一目了然地**可視化程式碼作者**,**無縫導航和探索** Git 存儲庫,**通過豐富的可視化和強大的比較命令**獲得有價值的見解**,等等更多的。 **下載:** [**GitLens**](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1675224552887/688896dd-cfff-41fc-aa2e-53716e5585c6.png) ### HTML 樣板 此擴展提供了所有 Web 應用程式中使用的標準 HTML 樣板程式碼。 **下載:** [**HTML 樣板**](https://marketplace.visualstudio.com/items?itemName=sidthesloth.html5-boilerplate) ![替代文本](https://s19.postimg.cc/3mig98d5v/html_boilerplate_1_0_3.gif) ### Import Cost 此擴展將在編輯器中內聯顯示導入包的大小。該擴展利用 webpack 來檢測導入的大小。 **下載:** [**Import Cost**](https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost) ![示例圖片](https://citw.dev/_next/image?url=%2fposts%2fimport-cost%2f1quov3TFpgG2ur7myCLGtsA.gif&w=1080&q=75) ### Live Server 它將啟用實時更改而不保存文件。 **下載:** [**Live Server**](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) ![實時伺服器演示 VSCode](https://github.com/ritwickdey/vscode-live-server/raw/HEAD/images/Screenshot/vscode-live-server-animated-demo.gif) ### Markdown 多合一 Markdown 所需的一切(鍵盤快捷鍵、目錄、自動預覽等)。 ***注意***:VS Code 具有開箱即用的基本 Markdown 支持(例如,**Markdown 預覽**),請參閱官方文件了解更多訊息。 **下載:** [**Markdown All in One**](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) ![切換粗體gif](https://github.com/yzhang-gh/vscode-markdown/raw/master/images/gifs/toggle-bold.gif) ### Markdown 預覽增強 它顯示了 Markdown 內容的增強預覽。 **下載:** [**Markdown 預覽增強版**](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced) ![簡介](https://user-images.githubusercontent.com/1908863/28495106-30b3b15e-6f09-11e7-8eb6-ca4ca001ab15.png) ### 將 JSON 粘貼為程式碼 複製 JSON,粘貼為 Go、TypeScript、C#、C++ 等。 **下載 -** [**將 JSON 粘貼為程式碼**](https://marketplace.visualstudio.com/items?itemName=quicktype.quicktype) ![圖片描述](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/llqdlpz0amo1vj7m5no5.png) ### 更漂亮 使用 Prettier 的程式碼格式化程序 **下載 -** [**Prettier**](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) ![更漂亮](https://i.imgur.com/wHlMe9e.png) ### Python IntelliSense (Pylance)、Linting、除錯(多線程、遠程)、Jupyter Notebooks、程式碼格式化、重構、單元測試等。 **下載 -** [**Python**](https://marketplace.visualstudio.com/items?itemName=ms-python.python) ![Python](https://i.imgur.com/cQ1ARrG.png) ### 設置同步 使用 GitHub Gist 跨多台計算機同步設置、程式碼片段、主題、文件圖標、啟動、按鍵綁定、工作區和擴展。 **下載 -** [**設置同步**](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) ![設置同步](https://shanalikhan.github.io/img/login-with-github.png) ### Tailwind CSS IntelliSense 適用於 VS Code 的智能 Tailwind CSS 工具 **下載 -** [**Tailwind CSS IntelliSense**](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) ![Tailwind CSS IntelliSense](https://raw.githubusercontent.com/bradlc/vscode-tailwindcss/master/packages/vscode-tailwindcss/.github/banner.png) ### 所有亮點 突出顯示程式碼中的“TODO”、“FIXME”和其他註釋。 有時,在將程式碼發佈到生產環境之前,您會忘記檢查編碼時加入的 TODO。所以我長期以來一直想要一個擴展來突出顯示它們並提醒我還有註釋或尚未完成的事情。 希望這個擴展也能幫助您。 **下載 -** [**TODO 突出顯示**](https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight) ![TODO 突出顯示](https://github.com/wayou/vscode-todo-highlight/raw/master/assets/material-night.png) ### Turbo 控制台日誌 自動編寫有意義的日誌訊息的過程。 **下載 -** [**Turbo 控制台日誌**](https://marketplace.visualstudio.com/items?itemName=ChakrounAnas.turbo-console-log) ![Turbo 控制台日誌](https://image.ibb.co/dysw7p/insert_log_message.gif) ### 塔布寧人工智能 Tabnine 是一款 AI 程式碼助手,可讓您成為更好的開發人員。 Tabnine 將通過所有最流行的編碼語言和 IDE 中的實時程式碼完成來提高您的開發速度。 **下載 -** [**Tabnine AI**](https://marketplace.visualstudio.com/items?itemName=TabNine.tabnine-vscode) ![Tabnine AI](https://raw.githubusercontent.com/codota/tabnine-vscode/master/assets/completions-main.gif) ## ⚙️設置 以下“JSON”程式碼顯示了我的 VS Code 設置: ``` // user/settings.json { "files.autoSave": "afterDelay", "editor.mouseWheelZoom": true, "code-runner.clearPreviousOutput": true, "code-runner.ignoreSelection": true, "code-runner.runInTerminal": true, "code-runner.saveAllFilesBeforeRun": true, "code-runner.saveFileBeforeRun": true, "editor.wordWrap": "on", "C_Cpp.updateChannel": "Insiders", "editor.suggestSelection": "first", "python.jediEnabled": false, "editor.fontSize": 17, "emmet.includeLanguages": { "javascript": "javascriptreact" }, "editor.minimap.size": "fit", "editor.fontFamily": "Consolas, DejaVu Sans Mono, monospace", "editor.fontLigatures": false, "[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "python.formatting.provider": "yapf", "[css]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "git.autofetch": true, "git.enableSmartCommit": true, "html-css-class-completion.enableEmmetSupport": true, "editor.formatOnPaste": true, "liveServer.settings.donotShowInfoMsg": true, "[python]": { "editor.defaultFormatter": "ms-python.python" }, "diffEditor.ignoreTrimWhitespace": false, "[json]": { "editor.defaultFormatter": "vscode.json-language-features" }, "[c]": { "editor.defaultFormatter": "ms-vscode.cpptools" }, "editor.fontWeight": "300", "editor.fastScrollSensitivity": 6, "explorer.confirmDragAndDrop": false, "vsicons.dontShowNewVersionMessage": true, "workbench.iconTheme": "material-icon-theme", "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.renderWhitespace": "none", "workbench.startupEditor": "newUntitledFile", "liveServer.settings.multiRootWorkspaceName": "", "liveServer.settings.port": 5000, "liveServer.settings.donotVerifyTags": true, "editor.formatOnSave": true, "html.format.indentInnerHtml": true, "editor.formatOnType": true, "printcode.tabSize": 4, "terminal.integrated.confirmOnExit": "hasChildProcesses", "terminal.integrated.cursorBlinking": true, "terminal.integrated.rightClickBehavior": "default", "tailwindCSS.emmetCompletions": true, "sync.gist": "527c3e29660c53c3f17c32260188d66d", "gitlens.hovers.currentLine.over": "line", "terminal.integrated.profiles.windows": { "PowerShell": { "source": "PowerShell", "icon": "terminal-powershell" }, "Command Prompt": { "path": [ "${env:windir}\\Sysnative\\cmd.exe", "${env:windir}\\System32\\cmd.exe" ], "args": [], "icon": "terminal-cmd" }, "Git Bash": { "source": "Git Bash" }, "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe (migrated)": { "path": "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "args": [] }, "Windows PowerShell": { "path": "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" }, "Ubuntu (WSL)": { "path": "C:\\WINDOWS\\System32\\wsl.exe", "args": [ "-d", "Ubuntu" ] } }, "javascript.updateImportsOnFileMove.enabled": "always", "[dotenv]": { "editor.defaultFormatter": "foxundermoon.shell-format" }, "editor.tabSize": 2, "cSpell.customDictionaries": { "custom-dictionary-user": { "name": "custom-dictionary-user", "path": "~/.cspell/custom-dictionary-user.txt", "addWords": true, "scope": "user" } }, "window.restoreFullscreen": true, "tabnine.experimentalAutoImports": true, "files.defaultLanguage": "${activeEditorLanguage}", "bracket-pair-colorizer-2.depreciation-notice": false, "workbench.editor.wrapTabs": true, "[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[ignore]": { "editor.defaultFormatter": "foxundermoon.shell-format" }, "terminal.integrated.fontFamily": "courier new", "terminal.integrated.defaultProfile.windows": "pwsh.exe -nologo", "terminal.integrated.shellIntegration.enabled": true, "terminal.integrated.shellIntegration.showWelcome": false, "editor.accessibilitySupport": "off", "editor.bracketPairColorization.enabled": true, "todohighlight.isEnable": true, "terminal.integrated.shellIntegration.history": 1000, "turboConsoleLog.insertEnclosingClass": false, "turboConsoleLog.insertEnclosingFunction": false, "files.autoSaveDelay": 500, "liveServer.settings.CustomBrowser": "chrome", "liveServer.settings.host": "localhost", "liveServer.settings.fullReload": true, "workbench.editor.enablePreview": false, "workbench.colorTheme": "Andromeda Bordered" } ``` ## 總結 以上簡單分享,希望對您有幫助!

後端 JS 訓練二:第6課 ── 回應 http post request

## 課程目標 - 使用 node 與 express 回應 http post request ## 課程內容 前面幾課我們學習了 http get 的寫法,這次來學 http post 的寫法 在「會更新主機資料狀態」的操作時,通常都會用 http post 例如,新增資料、更新資料、刪除資料,等等常見操作! 通常主機資料狀態會放在「資料庫軟體」例如 mysql 裡面,我們簡單起見,放在一個 json 檔案就好! --- 替這課建立 lesson6 資料夾,內容跟 lesson5 一樣即可 新增一個 new.ejs 檔案,放入以下內容 ``` <h1>新同學報到!</h1> <form method="post" action="/create"> name: <input type="text" name="name"> </form> ``` 然後在 index.js 加入這段程式碼 ``` const bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: true })); app.get('/new', function(req, res){ res.render('new'); }); app.post('/create', (req, res) => { const fs = require('fs'); const name = req.body.name; const data = fs.readFileSync('./lesson6/users.json'); const users = JSON.parse(data); users.push({ name: name }); fs.writeFileSync('./lesson6/users.json', JSON.stringify(users)); res.send('<h1>新增成功!</h1>'); }) ``` 然後去終端機輸入 ``` node lesson6/index.js ``` 接著打開瀏覽器,在網址輸入 ``` http://localhost:3000/new ``` 你會看到新增同學的頁面與表單! 輸入姓名之後,送出表單就可以新增同學的資料了! --- 開頭跟 bodyParser 有關的兩行,要引入並設定好,才能使用 req.body 的參數 為什麼要加這兩行?這跟 express 的 middleware 機制設計有關,這邊不深入說明 反正就是在需要使用某些功能的時候,express 不會預設通通提供給你,要請你去設定啟用之後,才會支援 --- 之前處理 http get 的 url 參數時,我們使用 req.query 來取得參數 這次處理 http post 的表單參數時,我們使用 req.body 來取得參數 express 會這樣設計,是因為在 http 協定中,這兩種參數本來就放在不同地方喔! 看不太懂沒關係,先照做就對了! --- 檔案處理、新增資料放進 json 檔案的段落,跟之前的課程一樣,忘記的話就回頭翻閱一下吧! ## 課後作業 這次要開發「新增文章」的功能 並且練習用 node 回應 http post request 請把 hw5 的內容複製到 hw6,然後增加 new.ejs 檔案 ``` /repo /hw6 /index.js /homepage.ejs /view.ejs /new.ejs /posts.json /public /style.css ``` 接著修改主程式 index.js 的內容,讓網站能夠回應 `/new` 這個網址 這網址會把 new.ejs 的內容 render 出來,內容就放一個 form 表單 表單內可輸入 `標題` 以及 `文章內容`,點擊送出按鈕會以 http post 的形式發送到 `/create` 接著修改主程式 index.js 的內容,讓網站能夠回應 `/create` 這個網址 將接收到的資料,存進 `posts.json` 裡面 完成以上任務,你就完成這次的課程目標了! --- 在上傳到 github 時,你會注意到因為 `posts.json` 有改變,所以會帶著新資料一起上傳,好像有點怪? 其實,實務上會把資料存在 mysql 這類專門資料庫軟體,不會這樣存在 json 檔案中 本課程為了簡化,所以直接存在 json 檔案,這不是實務正常做法~ 為了方便起見,每次新增文章 `posts.json` 都會改變,就都一起上傳,沒關係~

後端 JS 訓練二:第5課 ── 處理 url 參數

## 課程目標 - 使用 node 與 express 處理 url 參數 ## 課程內容 在瀏覽網站的時候,點擊不同頁面時,有時需要透過 url(網址)附帶一些參數 這課來學習如何用 node 處理 url 參數 替這課建立 lesson5 資料夾,內容跟 lesson4 一樣即可 在 index.js 加入這段程式碼 ``` app.get('/view', (req, res) => { const data = fs.readFileSync('./lesson5/users.json'); const users = JSON.parse(data); const index = req.query.index; const user = users[index]; res.send('<h1>' + user.name + '同學,你好!</h1>'); }); ``` 然後把 hello.ejs 的內容修改成 ``` <div> <% for(var i = 0; i < users.length; i++) { %> <p> <%= users[i].name %>同學,你好! <a href="/view?index=<%= i %>">單獨打招呼頁面</a> </p> <% } %> </div> ``` 然後去終端機輸入 ``` node lesson5/index.js ``` 接著打開瀏覽器,在網址輸入 ``` http://localhost:3000/ ``` 你會看到每段訊息旁邊,多了一個單獨連結,點下去,就會到單獨打招呼頁面! 操作看看吧!試試看「透過網址傳參數」的感覺! --- 在 http 協定中,網址中出現問號 `?` 代表後面的部份是參數,參數的值應該可以單獨被抓出來 前面說過 `(req, res)` ,很多人會寫 `(request, response)`,兩者意思一樣,就是在 express 中代表請求&回應的物件 這邊是我們第一次使用「請求」物件!我們在請求物件中,使用 `req.query.index` 找出名為 `index` 的參數 然後在首頁,透過迴圈,加上每個單獨頁面的連結,通通使用 `index` 作為參數傳遞 --- 實務上,開發後端應用時,只要是 http get request,有時會透過網址本身代表參數,例如 ``` /view/1 /view/2 /view/3 ``` 有時會透過 url parameter 傳遞參數,例如 ``` /view?id=1 /view?id=2 /view?id=3 ``` 這是一個主觀偏好問題,其實都可以!效果也差不多 這兩種寫法,在各種程式語言中,處理起來有點不一樣 本課就以 url parameter 作為示範,先照做即可,別擔心! ## 課後作業 這次要開發「閱讀單篇文章」的功能 並且練習 url 參數的傳遞&取得 請把 hw4 的內容複製到 hw5,然後增加 view.ejs 檔案 ``` /repo /hw5 /index.js /homepage.ejs /view.ejs /posts.json /public /style.css ``` 修改部落格首頁,替每篇文章加上 <a> 超連結,點擊之後會前往單篇文章的網址 舉例來說,第一篇文章的網址會是 ``` <a href="/view?index=0"> ``` 第二篇的網址會是 ``` <a href="/view?index=1"> ``` 第三篇的網址會是 ``` <a href="/view?index=2"> ``` 接著修改主程式 index.js 的內容,讓網站能夠回應 `/view` 這種網址 然後根據從網址取得的索引參數,找出 posts.json 中對應的文章資料 接著把資料放進 view.ejs 模板中,回應顯示為網頁 請自行設計 view.ejs 的內容,簡單顯示一篇文章內容即可 請稍微加上一點樣式,弄得漂亮一點! 完成以上任務,你就完成這次的課程目標了!

後端 JS 訓練二:第4課 ── 提供靜態檔案

## 課程目標 - 使用 node 與 express 提供靜態檔案 ## 課程內容 目前為止的網頁,都是純 html,太陽春了! 這一課來學習,如何用 node 來提供 css 或圖片之類的「靜態檔案」! 替這課建立 lesson4 資料夾,內容跟 lesson3 同樣之外,再建立一個 public 資料夾,裡面新增 style.css 檔案 ``` /repo /lesson4 /index.js /hello.ejs /users.json /public /style.css ``` 在 index.js 裡面多加一行程式碼 ``` app.use(express.static('./lesson4/public')); ``` 在 style.css 裡面加入一些樣式 ``` p { color: green; } ``` 接著在 hello.ejs 加入樣式連結 ``` <link rel="stylesheet" href="/style.css"> ``` 然後去終端機輸入 ``` node lesson4/index.js ``` 接著打開瀏覽器,在網址輸入 ``` http://localhost:3000/ ``` 你會看到原本的打招呼訊息,文字變成了綠色! --- 後端程式設計,不論何種程式語言,在提供圖片、css 這種靜態檔案的時候,通常會開一個獨立的 public 資料夾來放檔案 所以本課使用的 `app.use(express.static('./lesson4/public'));` 程式碼 就只是設定一下,請 express 從某個資料夾提供靜態檔案,就這樣而已! ## 課後作業 這次要練習用 node 回應靜態檔案 請把 hw3 的內容複製到 hw4,然後增加 public 資料夾與 style.css 檔案 ``` /repo /hw4 /index.js /homepage.ejs /posts.json /public /style.css ``` 請在 style.css 中,稍微替你的日記首頁加一些樣式,弄得漂亮一點! 完成以上任務,你就完成這次的課程目標了!

用Github Page整理作品集

因為一直找不到工作(...汗)所以來整理作品 [成果展示](https://superyngo.github.io/to_do_list/) 基本上是參考[Let's Write](https://www.letswrite.tw/)做的[Demo](https://letswritetw.github.io/letswrite-food-check/) 在頁面下方有作品導覽以及Github連結 使用工具: 1.Github Page 2.[Google Tag Manager](https://tagmanager.google.com/#/home) 步驟: 1.申請GTM並取得GTM代碼 2.將GTM代碼插入所有專案的index.html中,並將所有專案上傳github,開啟page頁面 3.另外做一個myNavbat的github page,將所有專案連結放進去,可參考[我做的](https://github.com/superyngo/myNavbar) 4.用GTM的「自訂HTML」功能將myNavbar和github連結塞進所有專案中,參考代碼如下: ``` <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> <div class="myNav"></div> <div class="github"> <a class="githubHerf"> <i class="fa fa-github" aria-hidden="true"></i> </a> </div> <script> var githubHerf=document.querySelector(".githubHerf") githubHerf.setAttribute("href","https://github.com/superyngo"+{{Page Path}}) var myNav2 = document.querySelector(".myNav"); var iframe2 = document.createElement("iframe"); iframe2.setAttribute("src", "https://superyngo.github.io/myNavbar/"); iframe2.setAttribute("width", "100%"); iframe2.setAttribute("frameborder", "0"); myNav2.appendChild(iframe2) </script> <style> body{ background-color: #fff0df; } .github { position: fixed; left: 0; bottom: 0; display: flex; width: 100px; height: 100px; cursor: pointer; z-index: 2; :hover { position: absolute; left: 10px; bottom: 5px; font-size: 3rem; color: #fff; scale: 0.9; } } .github::before { content: ""; width: 0; height: 0; border-style: solid; border-width: 100px 0 0 100px; border-color: transparent transparent transparent #6e5494; } .github .fa { position: absolute; left: 10px; bottom: 5px; font-size: 3rem; color: #fff; } @media screen and (max-width: 600px) { :root { font-size: 12px; } .github { width: 70px; height: 70px; } .github::before { border-width: 70px 0 0 70px; } .github .fa { left: 8px; bottom: 4px; font-size: 2rem; } } </style> ``` 注意事項; 1.不知為何我GTM塞iframe一直不給過,所以用append的。 2.iframe內的超連結預設會在iframe內開啟,要避免只要在myNavbar的head裡加上<base target="_parent" />就可以了。 3當初做這些作業時完全沒考慮theme和RWD,花了一些時間但又不想花太多時間結果就勉勉強強用手機也都能開。 閒聊: 前陣子都在codeSignal上刷題,看別人解法真的很神,學很多... 有沒有北部公司缺人啊...投履歷都沒人回..中年轉行真的不行嗎...

用 JavaScript 輕鬆做出深色模式 vs 淺色模式的方法

我曾經不同意淺色和深色模式切換。 “切換開關是用戶系統偏好設置!”我會天真地感嘆,選擇讓 [prefers-color-scheme CSS 媒體查詢](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme) 控制我個人網站上的主題。沒有切換。沒有選擇。 🫠 自從黑暗模式出現以來,我一直是它的用戶。但最近,我更喜歡在輕型模式下使用_**一些**_網站和工具 - 包括我的個人網站 - 同時將我的系統設置牢牢地保留在黑暗中。我需要一個開關。我需要一個選擇!其他人也是如此。 在這篇文章中,我將向您展示如何使用 JavaScript 為我的網站建置終極主題 Toggle™️: 1. 在本地瀏覽器存儲中存儲和檢索主題首選項, 1. 退回到用戶系統首選項, 1. 如果未檢測到上述情況,則回退到默認主題。 TL;DR:[這是 CodePen 上的程式碼](https://codepen.io/whitep4nth3r/pen/VwEqrQL)。 原文出處:https://dev.to/whitep4nth3r/the-best-lightdark-mode-theme-toggle-in-javascript-368f ## 將資料屬性加入到 HTML 標記中 在 HTML 標記上,加入一個資料屬性,例如“data-theme”,並為其指定默認值“淺色”或“深色”。過去我使用自定義屬性“color-mode”而不是資料屬性(例如“color-mode=”light“”)。雖然這可行,但它沒有被歸類為有效的 HTML,而且我找不到任何相關文件!對此的任何見解都非常感激。 😅 ``` <html lang="en" data-theme="light"> <!-- all other HTML --> </html> ``` ## 通過 CSS 自定義屬性配置主題 在 CSS 中,通過“data-theme”每個值下的 [CSS 自定義屬性](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)(或變數)配置主題顏色` 屬性。請注意,您不一定需要將 `:root` 與 `data-theme` 結合使用,但它對於不隨主題變化的全局屬性很有用(如下例所示)。 [在 MDN 上了解有關 :root CSS 偽類的更多訊息。](https://developer.mozilla.org/en-US/docs/Web/CSS/:root) ``` :root { --grid-unit: 1rem; --border-radius-base: 0.5rem; } [data-theme="light"] { --color-bg: #ffffff; --color-fg: #000000; } [data-theme="dark"] { --color-bg: #000000; --color-fg: #ffffff; } /* example use of CSS custom properties */ body { background-color: var(--color-bg); color: var(--color-fg); } ``` 在 HTML 標籤上手動切換“data-theme”屬性,您就會看到主題已經發生變化(只要您使用這些 CSS 屬性來設置元素的樣式)! ## 在 HTML 中建置一個切換按鈕 將 HTML 按鈕加入到您的網站標題或任何需要主題切換的位置。加入一個 `data-theme-toggle` 屬性(稍後我們將使用它來定位 JavaScript 中的按鈕)和一個 [aria-label](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label)如果您計劃在按鈕上使用圖標(例如太陽和月亮分別代表淺色和深色模式),以便螢幕閱讀器和輔助技術可以理解按鈕的用途互動按鈕。 ``` <button type="button" data-theme-toggle aria-label="Change to light theme" >Change to light theme (or icon here)</button> ``` ## 計算頁面加載時的主題設置 在這裡,我們將根據我所說的“_**偏好級聯**_”來計算主題設置。 ### 從本地存儲獲取主題首選項 我們可以使用 [JavaScript 中的 localStorage 屬性](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) 將用戶首選項保存在瀏覽器中,該首選項在會話之間持續存在(或直到它手動清除)。在 The Ultimate Theme Toggle™️ 中,存儲的用戶首選項是最重要的設置,因此我們將首先查找它。 頁面加載時,使用 localStorage.getItem("theme") 檢查之前存儲的首選項。在本文後面,我們將在每次按下切換按鈕時更新主題值。如果沒有本地存儲值,則該值為“null”。 ``` // get theme on page load localStorage.getItem("theme"); // set theme on button press localStorage.setItem("theme", newTheme); ``` ### 在 JavaScript 中檢測用戶系統設置 如果“localStorage”中沒有存儲的主題首選項,我們將使用 [window.matchMedia() 方法](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia)通過傳入媒體查詢字串。您只需計算一項設置即可實現首選項級聯,但下面的程式碼顯示瞭如何檢測淺色或深色系統設置。 ``` const systemSettingDark = window.matchMedia("(prefers-color-scheme: dark)"); // or const systemSettingLight = window.matchMedia("(prefers-color-scheme: light)"); ``` `window.matchMedia()` 返回一個 `MediaQueryList`,其中包含您請求的媒體查詢字串,以及它是否與用戶系統設置“匹配”(true/false)。 ``` { matches: true, media: "(prefers-color-scheme: dark)", onchange: null } ``` ### 回退到默認主題 現在您可以通過“window.matchMedia()”存取“localStorage”值和系統設置,您可以使用首選項級聯(本地存儲,然後系統設置)計算首選主題設置,並回退到默認主題您的選擇(這應該是您之前在 HTML 標記上指定的默認主題)。 我們將在頁面加載時執行此程式碼來計算當前的主題設置。 ``` function calculateSettingAsThemeString({ localStorageTheme, systemSettingDark }) { if (localStorageTheme !== null) { return localStorageTheme; } if (systemSettingDark.matches) { return "dark"; } return "light"; } const localStorageTheme = localStorage.getItem("theme"); const systemSettingDark = window.matchMedia("(prefers-color-scheme: dark)"); let currentThemeSetting = calculateSettingAsThemeString({ localStorageTheme, systemSettingDark }); ``` ## 加入事件監聽器到切換按鈕 接下來,我們將設置一個事件監聽器,以便在按下按鈕時切換主題。使用我們之前加入的資料屬性(`data-theme-toggle`)定位 DOM 中的按鈕,並加入一個[事件監聽器](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) 加入到單擊按鈕。 - 將新主題計算為字串 - 計算並更新按鈕文本(如果您在按鈕上使用圖標,則可以在此處進行切換) - 更新按鈕上的aria標籤 - 切換HTML標籤上的data-theme屬性 - 將新的主題首選項保存在本地存儲中 - 更新內存中的currentThemeSetting ``` // target the button using the data attribute we added earlier const button = document.querySelector("[data-theme-toggle]"); button.addEventListener("click", () => { const newTheme = currentThemeSetting === "dark" ? "light" : "dark"; // update the button text const newCta = newTheme === "dark" ? "Change to light theme" : "Change to dark theme"; button.innerText = newCta; // use an aria-label if you are omitting text on the button // and using sun/moon icons, for example button.setAttribute("aria-label", newCta); // update theme attribute on HTML to switch theme in CSS document.querySelector("html").setAttribute("data-theme", newTheme); // update in local storage localStorage.setItem("theme", newTheme); // update the currentThemeSetting in memory currentThemeSetting = newTheme; }); ``` 要確認“localStorage”正在更新,請打開開發工具,導航到“Application”選項卡,展開“Local Storage”並選擇您的站點。你會看到一個鍵:值列表;查找“主題”並單擊按鈕即可觀看其實時更新。重新加載您的頁面,您將看到保留的主題首選項! ![帶有開發工具的瀏覽器窗口在應用程式選項卡上打開。選擇whitepanther dot com上的本地存儲,顯示主題light瀏覽器中存儲的鍵值對。](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zosfts8gbby76vo1h40o.png) ## 把它們放在一起! 您現在可以通過以下方式建置您自己的終極主題切換™️: - 使用CSS自定義屬性來指定不同的主題顏色,通過HTML標籤上的資料屬性進行切換 - 使用 HTML 按鈕來啟動切換 - 使用首選項級聯計算頁面加載時的首選主題(本地存儲 > 系統設置 > 後備默認主題) - 單擊切換按鈕即可切換主題,並將用戶首選項存儲在瀏覽器中以供將來存取 這是完整的 CodePen,您可以在我的個人網站上查看工作版本。快樂切換! https://codepen.io/whitep4nth3r/pen/VwEqrQL

如何在微前端 Micro Frontends 架構中處理 CSS

如何在微前端中處理 CSS?畢竟,樣式始終是*任何* UI 片段所需要的東西,但是,它也是全局共享的東西,因此是潛在的衝突來源。 在這篇文章中,我想回顧一下現有的不同策略來馴服 CSS 並使其擴展以開發微前端。如果這裡的任何內容對您來說聽起來很合理,那麼也可以考慮研究一下[“微前端的藝術”](https://microfrontends.art/)。 **本文的程式碼可以在[github.com/piral-samples/css-in-mf](https://github.com/piral-samples/css-in-mf)找到。請務必查看示例實現。** CSS 的處理是否會影響每個微前端解決方案?讓我們檢查可用的類型來驗證這一點。 原文出處:https://dev.to/florianrappl/css-in-micro-frontends-4jai ## 微前端的類型 過去我寫了很多關於存在哪些類型的微前端、為什麼存在以及何時應該使用什麼類型的微前端架構的文章。採用 Web 方法意味著使用 iframe 來使用來自不同微前端的 UI 片段。在這種情況下,沒有任何限制,因為無論如何每個片段都是完全隔離的。 在任何其他情況下,無論您的解決方案使用客戶端還是伺服器端組合(或介於兩者之間的東西),您最終都會得到在瀏覽器中評估的樣式。因此,在所有其他情況下,您都會關心 CSS。讓我們看看這裡有哪些選項。 ## 無特殊處理 好吧,第一個 - 也許是最(或根據觀點,最不)明顯的解決方案是不進行任何特殊處理。相反,每個微前端都可以附帶額外的樣式表,然後在渲染微前端的元件時附加這些樣式表。 理想情況下,每個元件僅在首次渲染時加載所需的樣式,但是,由於這些樣式中的任何一個都可能與現有樣式衝突,我們也可以假裝在微前端的任何元件渲染時加載所有“有問題的”樣式。 ![衝突](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fewl99l6y04edyjnni2j.png) 這種方法的問題在於,當給出諸如“div”或“div a”之類的通用選擇器時,我們還將重新設置其他元素的樣式,而不僅僅是原始微前端的片段。更糟糕的是,類和屬性也不是故障保護措施。像“.foobar”這樣的類也可以在另一個微前端中使用。 **您將在引用的演示存儲庫中找到兩個衝突的微前端的示例,網址為 [solutions/default](https://github.com/piral-samples/css-in-mf/tree/main/solutions)。** 擺脫這種痛苦的一個好方法是進一步隔離元件 - 就像 Web 元件一樣。 ## 影子 DOM 在自定義元素中,我們可以打開一個影子根來將元素附加到專用的迷你文件,該迷你文件實際上與其父文件屏蔽。總的來說,這聽起來是一個好主意,但與這裡介紹的所有其他解決方案一樣,沒有硬性要求。 ![Shadow DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xp18uw9sxffq1l7oj6mc.png) 理想情況下,微前端可以自由決定“如何”實現元件。因此,實際的 Shadow DOM 集成必須由微前端完成。 使用 Shadow DOM 有一些缺點。最重要的是,雖然 Shadow DOM 內部的樣式保留在內部,但全局樣式也不會影響 Shadow DOM。乍一看,這似乎是一個優勢,但是,由於整篇文章的主要目標只是隔離微前端的樣式,因此您可能會錯過諸如應用某些全局設計系統(例如 Bootstrap)之類的要求。 要使用 Shadow DOM 進行樣式設置,我們可以通過“link”引用或“style”標籤將樣式放入 Shadow DOM 中。由於 Shadow DOM 是無樣式的,並且外部的樣式不會傳播到其中,因此我們實際上需要它。除了編寫一些內聯樣式之外,我們還可以使用捆綁器將“.css”(或者類似“.shadow.css”的內容)視為原始文本。這樣,我們只會得到一些文本。 對於 esbuild,我們可以配置 `piral-cli-esbuild` 的預製配置,如下所示: ``` module.exports = function(options) { options.loader['.css'] = 'text'; options.plugins.splice(0, 1); return options; }; ``` 這會刪除初始 CSS 處理器 (SASS) 並為“.css”文件配置標準加載器。現在,shadow DOM 中的某些樣式的工作方式如下: ``` import css from "./style.css"; customElements.define(name, class extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); } connectedCallback() { this.style.display = "contents"; const style = this.shadowRoot.appendChild(document.createElement('style')); style.textContent = css; } }); ``` 上面的程式碼是一個有效的自定義元素,從樣式角度來看它是透明的(“display:contents”),即只有其內容會反映在渲染樹中。它託管一個包含單個“style”元素的影子 DOM。 `style` 的內容設置為 `style.css` 文件的文本。 **您將在 [`solutions/shadow-dom`](https://github.com/piral-samples/css-in-mf/tree/main) 引用的演示存儲庫中找到兩個衝突的微前端的示例/解決方案/shadow-dom)。** 域元件避免使用影子 DOM 的另一個原因是,並非每個 UI 框架都能夠處理影子 DOM 中的元素。因此,無論如何都必須尋找替代解決方案。一種方法是轉而使用一些 CSS 約定。 ## 使用命名約定 如果每個微前端都遵循全局 CSS 約定,那麼就可以在元級別上避免衝突。最簡單的約定是在每個類前面加上微前端的名稱。因此,舉例來說,如果一個微前端稱為“shopping”,另一個微前端稱為“checkout”,那麼兩者都會將其“active”類分別重命名為“shopping-active”/“checkout-active”。 ![約定](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6l8r1s59v1dcu3yp022u.png) 這同樣適用於其他可能存在衝突的名稱。舉個例子,在微前端稱為“shopping”的情況下,我們將其稱為“shopping-primary-button”,而不是像“primary-button”這樣的ID。如果由於某種原因,我們需要設置元素的樣式,我們應該使用後代選擇器(例如“.shopping img”)來設置“img”標籤的樣式。現在,這適用於具有“shopping”類的 *some* 元素中的“img”元素。這種方法的問題是購物微前端也可能使用其他微前端的元素。如果我們看到“div.shopping > div.checkout img”怎麼辦?儘管“img”現在由通過“checkout”微前端帶來的元件託管/集成,但它的樣式將由“shopping”微前端 CSS 設計。這並不理想。 儘管命名約定在一定程度上解決了問題,但它們仍然容易出錯並且使用起來很麻煩。如果我們重命名微前端會怎樣?如果微前端在不同的應用程式中獲得不同的名稱怎麼辦?如果我們在某些時候忘記應用命名約定怎麼辦?這就是工具幫助我們的地方。 ## CSS 模塊 自動引入一些前綴並避免命名衝突的最簡單方法之一是使用 CSS 模塊。根據您選擇的捆綁器,這可以是開箱即用的,也可以通過一些配置更改來實現。 ![CSS 模塊](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o49rdmokn5kvn8ncjjrt.png) ``` // Import "default export" from CSS import styles from './style.modules.css'; // Apply <div className={styles.active}>Active</div> ``` 導入的模塊是一個生成的模塊,保存將其原始類名(例如“active”)映射到生成的類名的值。生成的類名通常是 CSS 規則內容與原始類名混合的哈希值。這樣,名稱應該盡可能唯一。 作為示例,讓我們考慮使用“esbuild”建置的微前端。對於“esbuild”,您需要一個插件(“esbuild-css-modules-plugin”)和相應的配置更改以包含 CSS 模塊。 使用 Piral 我們只需要調整 `piral-cli-esbuild` 已經帶來的配置。我們刪除標準 CSS 處理(使用 SASS)並用插件替換: ``` const cssModulesPlugin = require('esbuild-css-modules-plugin'); module.exports = function(options) { options.plugins.splice(0, 1, cssModulesPlugin()); return options; }; ``` 現在我們可以在程式碼中使用 CSS 模塊,如上所示。 CSS 模塊有一些缺點。首先,它附帶了一些標準 CSS 的語法擴展。這對於區分我們想要導入的樣式(因此要進行預處理/哈希)和應保持原樣的樣式(即稍後在不導入的情況下使用)是必要的。另一種方法是將CSS直接帶入JS文件中。 ## CSS-in-JS CSS-in-JS 最近的名聲很差,但是,我認為這是一個誤解。我也更喜歡將其稱為“CSS-in-Components”,因為它為元件本身帶來了樣式。一些框架(Astro、Svelte 等)甚至允許通過其他方式直接執行此操作。經常被提及的缺點是性能 - 這通常是由於在瀏覽器中編寫 CSS 造成的。然而,這並不總是必要的,在最好的情況下,CSS-in-JS 庫實際上是建置時間驅動的,即沒有任何性能缺陷。 ![CSS-in-JS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/36w7yuksmdzgstastjxv.png) 然而,當我們談論 CSS-in-JS(或 CSS-in-Components)時,我們需要考慮現有的各種選項。為簡單起見,我只包含三個:情感、樣式元件和香草提取物。讓我們看看它們如何幫助我們在將微前端整合到一個應用程式中時避免衝突。 ### Emotion Emotion 是一個非常酷的庫,它附帶了 React 等框架的幫助程序,但沒有將這些框架設置為先決條件。情感可以很好地優化和預先計算,並允許我們使用可用的 CSS 技術的完整庫。 使用“純粹”情感相當容易;首先安裝包: ``` npm i @emotion/css ``` 現在您可以在程式碼中使用它,如下所示: ``` import { css } from '@emotion/css'; const tile = css` background: blue; color: yellow; flex: 1; display: flex; justify-content: center; align-items: center; `; // later <div className={tile}>Hello from Blue!</div> ``` `css` 幫助器允許我們編寫被解析並放置在樣式表中的 CSS。返回值是生成的類的名稱。 如果我們特別想使用 React,我們還可以使用 Emotion 中的 jsx 工廠(引入了一個名為 css 的新標準 prop)或 styled 幫助器: ``` npm i @emotion/react @emotion/styled ``` 現在感覺很像樣式是 React 本身的一部分。例如,“styled”幫助器允許我們定義新元件: ``` const Output = styled.output` border: 1px dashed red; padding: 1rem; font-weight: bold; `; // later <Output>I am groot (from red)</Output> ``` 相比之下,“css”輔助屬性使我們能夠稍微縮短符號: ``` <div css={` background: red; color: white; flex: 1; display: flex; justify-content: center; align-items: center; `}> Hello from Red! </div> ``` 總而言之,這會生成不會衝突的類名,並提供避免樣式混合的穩健性。 “styled”助手尤其受到流行的“styled-components”庫的啟發。 ### 樣式元件 “styled-components”庫可以說是最流行的 CSS-in-JS 解決方案,並且常常是此類解決方案聲譽不佳的原因。從歷史上看,這實際上是在瀏覽器中編寫 CSS 的全部內容,但在過去幾年中,他們確實極大地推進了這一點。今天,您也可以對所使用的樣式進行一些非常好的伺服器端組合。 與“emotion”相比,安裝(針對 React)需要更少的軟體包。唯一的缺點是打字是事後才想到的 - 所以你需要安裝兩個包才能完全喜歡 TypeScript: ``` npm i styled-components --save npm i @types/styled-components --save-dev ``` 安裝後,該庫就已經完全可用: ``` import styled from 'styled-components'; const Tile = styled.div` background: blue; color: yellow; flex: 1; display: flex; justify-content: center; align-items: center; `; // later <Tile>Hello from Blue!</Tile> ``` 其原理與“情感”相同。因此,讓我們探索另一種選擇,嘗試從一開始就實現零成本,而不是事後的想法。 ### Vanilla Extract 我之前寫的關於利用類型更接近元件(並避免不必要的執行時成本)的內容正是最新一代 CSS-in-JS 庫所涵蓋的內容。最有前途的庫之一是“@vanilla-extract/css”。 使用該庫有兩種主要方式: - 與您的捆綁器/框架集成 - 直接使用 CLI 在此示例中,我們選擇前者 - 並將其集成到“esbuild”。為了使集成正常工作,我們需要使用“@vanilla-extract/esbuild-plugin”包。 現在我們將其集成到建置過程中。使用 `piral-cli-esbuild` 配置,我們只需將其加入到配置的插件中: ``` const { vanillaExtractPlugin } = require("@vanilla-extract/esbuild-plugin"); module.exports = function (options) { options.plugins.push(vanillaExtractPlugin()); return options; }; ``` 為了使 Vanilla Extract 正常工作,我們需要編寫 `.css.ts` 文件,而不是普通的 `.css` 或 `.sass` 文件。這樣的文件可能如下所示: ``` import { style } from "@vanilla-extract/css"; export const heading = style({ color: "blue", }); ``` 這都是有效的 TypeScript。我們最終會得到一個類名的導出 - 就像我們從 CSS 模塊、Emotion 中得到的一樣 - 你明白了。 所以最後,上面的樣式將像這樣應用: ``` import { heading } from "./Page.css.ts"; // later <h2 className={heading}>Blue Title (should be blue)</h2> ``` 這將在建置時完全處理——而不是執行時成本。 您可能會感興趣的另一種方法是使用 CSS 實用程序庫,例如 Tailwind。 ## CSS 實用程序,例如 Tailwind 這是一個獨立的類別,但我認為既然 Tailwind 是這個類別中的主要工具,我將只介紹 Tailwind。 Tailwind 的主導地位甚至達到了甚至有人問“你寫 CSS 還是 Tailwind?”之類的問題。這與 jQuery 在 DOM 操作領域的統治地位非常相似。 2010 年,人們問“這是 JavaScript 還是 jQuery?”。 無論如何,使用 CSS 實用程序庫的優點是根據使用情況生成樣式。這些樣式不會衝突,因為實用程序庫始終以相同的方式定義它們。因此,每個微前端將僅附帶實用程序庫中根據需要顯示微前端所需的部分。 ![Tailwind](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8waj7k3823oq77qhkzmb.png) 如果使用 Tailwind 和 esbuild,我們還需要安裝以下軟體包: ``` npm i autoprefixer tailwindcss esbuild-style-plugin ``` esbuild的配置比之前複雜一點。 `esbuild-style-plugin` 本質上是 esbuild 的 PostCSS 插件;所以必須正確配置: ``` const postCssPlugin = require("esbuild-style-plugin"); module.exports = function (options) { const postCss = postCssPlugin({ postcss: { plugins: [require("tailwindcss"), require("autoprefixer")], }, }); options.plugins.splice(0, 1, postCss); return options; }; ``` 在這裡,我們刪除了默認的 CSS 處理插件 (SASS),並將其替換為 PostCSS 插件 - 使用 PostCSS 的“autoprefixer”和“tailwindcss”擴展。 現在我們需要加入一個有效的 *tailwind.config.js* 文件: ``` module.exports = { content: ["./src/**/*.tsx"], theme: { extend: {}, }, plugins: [], }; ``` 這本質上是配置 Tailwind 的最低要求。它只是提到應該掃描 `tsx` 文件以了解 Tailwind 實用程序類的使用情況。然後找到的類將被放入 CSS 文件中。 因此,CSS 文件還需要知道生成/使用的聲明應包含在哪裡。至少我們只有以下 CSS: ``` @tailwind utilities; ``` 還有其他“@tailwind”指令。例如,Tailwind 帶有重置和基礎層。然而,在微前端中,我們通常不關心這些層。這屬於應用程式 shell 或編排應用程式的關注範圍 - 而不是域應用程式。 然後,CSS 將被替換為 Tailwind 中已指定的類: ``` <div className="bg-red-600 text-white flex flex-1 justify-center items-center">Hello from Red!</div> ``` ## 比較 迄今為止提出的幾乎每種方法都是微前端的可行競爭者。一般來說,這些溶液也可以混合。一個微前端可以採用影子 DOM 方法,而另一個微前端則對 Emotion 感到滿意。第三個圖書館可能會選擇使用香草精。 最後,唯一重要的是所選擇的解決方案是無碰撞的,並且不會帶來(巨大的)執行時成本。雖然某些方法比其他方法更有效,但它們都提供了所需的樣式隔離。 |方法|遷移工作|可讀性|穩健性|性能影響| | ----------- | -------------- | -------------- | ---------- | ------------------ | |大會 |中等|高|低|無 | | CSS 模塊 |低|高|中等|從無到低| |影子 DOM |低到中|高|高|低| | JS 中的 CSS |高|中到高|高|從無到高| |順風|高|中等|高|無 | 性能影響很大程度上取決於實施。例如,對於 CSS-in-JS,如果解析和組合在執行時完全完成,您可能會產生很大的影響。如果樣式已經預先解析但僅在執行時組合,則影響可能很小。如果使用像香草精這樣的解決方案,您基本上不會產生任何影響。 對於 Shadow DOM,主要的性能影響可能是 Shadow DOM 內部元素的投影或移動(本質上為零)以及“style”標籤的重新評估。然而,這是相當低的,甚至可能會產生一些性能優勢,給定的樣式總是切中要害,並且僅專用於要在影子 DOM 中顯示的某個元件。 在示例中,我們有以下捆綁包大小: |方法|索引 [kB] |頁碼 [kB] |表 [kB] |總體 [kB] |尺寸 [%] | | ----------------- | ---------- | --------- | ----------- | ------------ | ------ | |默認| 1.719 | 1.719 1.203 | 1.203 0.245 | 0.245 3.167 | 3.167 100% | |大會 | 1.761 | 1.761 1.241 | 1.241 0.269 | 0.269 3.271 | 3.271 103% | | CSS 模塊 | 2.149 | 2.149 2.394 | 2.394 0 | 4.543 | 4.543 143% | |影子 DOM | 10.044 | 10.044 1.264 | 1.264 0 | 11.308 | 11.308 357% | |情感| 1.670 | 1.670 1.632 | 1.632 25.785 | 25.785 29.087 | 29.087 918% | |樣式元件 | 1.618 | 1.618 1.612 | 1.612 63.073 | 63.073 66.303 | 66.303 2093% | |香草精 | 1.800 | 1.800 1.257 | 1.257 0.314 | 0.314 3.371 | 3.371 106% | |順風| 1.853 | 1.853 1.247 | 1.247 0.714 | 0.714 3.814 | 3.814 120% | 對這些數字持保留態度,因為在情感和样式元件的情況下,執行時可以(並且可能甚至應該)共享。另外,給定的示例微前端確實很小(所有 UI 片段的總體大小為 3kB)。對於更大的微前端,增長肯定不會像這裡描述的那麼問題。 Shadow DOM 解決方案的大小增加可以通過我們提供的簡單實用腳本來解釋,該腳本可以輕鬆地將現有的 React 渲染包裝到 Shadow DOM 中(無需生成新樹)。如果這樣的實用程序是集中共享的,那麼其大小將更接近其他更輕量級的解決方案。 ## 結論 在微前端解決方案中處理 CSS 並不困難 - 只需從一開始就以結構化和有序的方式完成,否則就會出現衝突和問題。一般來說,建議選擇 CSS 模塊、Tailwind 或可擴展的 CSS-in-JS 實現等解決方案。

回答網友提問:26歲無經驗、高職畢,先去讀個二技 vs 直接補習轉職?

阿川收到網友提問如下: ``` 哈囉站長你好 我目前有在看蓬蓬的自學影片跟寫你分享的練習題 有件事想詢問一下我目前快26之前的工作經歷跟軟體一點關係都沒有 高職畢業 目前在自學一些程式語言的技能 如果未來要朝這個方向走建議我先去讀個二技相關科系補學歷嗎? 還是直接找線上課程或補習班轉職謝謝 原本的打算是想說上二技假日進修補個學歷順便幫自己打底 因為網路上看到蠻多分享是上完課後基礎理論不好 想順便詢問一下沒有學歷的話對未來的工作發展影響大嗎? 還是學歷只是初期比較看待後面看能力這樣子 ``` 寫一篇完整、公開回答跟大家分享,給類似狀況的人參考: # 不建議回學校補學歷 回學校補學歷真的太花時間了,動輒數年以上 何況入學之後還未必喜歡學校、未必喜歡寫程式 業界很多人也是「學歷普普且無經驗」自學4-9個月後,半路出家轉職成功 不論是金錢 or 時間成本來說,都應該先這樣試試看比較保險吧 # 很多人半路出家之後覺得自己底子不好 本科&非本科,基礎一定有差 但是現在網路資源、書本資源很多 寫網站不是什麼需要博士學位的「太空火箭科學」 工作上缺哪方面,就往哪方面慢慢自己補充,且戰且走也還夠用的 這行業根據職位狀況,難度可深可淺,一開始先負責較簡單的網頁工作也行 發現自己底子不好,趕快花業餘時間,大力自修一下呀 甚至先入行之後,週末再去學校進修,都比較保險吧 # 學歷對未來工作影響大嗎 學歷好看的話,當然在職場上有優勢 但如果態度不專業、工作多年還是沒什麼作品集,那也很難當工程師吧? 反過來說,學經歷不強的話 如果態度積極,作品集擺開在那邊,就算不是「超猛」的作品,也讓人知道這工程師有基本的「戰鬥力」呀 更不用說,如果積極貢獻社群、Github 專案有一堆星星,這種時候誰會管這工程師的學歷? 所以這題的答案是:學歷出色還是很吃香,但也還好啦!畢竟軟體工程這行,偏向「實力主義」,很難靠「關係」或者當「花瓶」或者「辦公室政治」就能混得出色 # 不建議直接跳進去補習班 另外我也不建議直接跑去需「全職上課」半年左右,學費十萬以上那種實體補習班 首先,班上同學程度不一,如果你稍微沒跟上進度,後面老師在講什麼就聽不懂,這樣花了大錢、時間,學習效果也不怎麼樣呀 我建議先大量找免費或便宜的教材,先吸收,多試幾份,真的卡關了,再開始挑補習班 先直接找一些作業跟專案寫寫看,從免費 -> 便宜的 -> 稍貴的,這樣一點一點花錢,風險比較小 更認識自身需求之後,再去比較市面上的各種補習班,最後再把這錢花下去,比較保險 事實上,也有很多人,最後根本沒去補習班,只靠著免費&便宜的一些資源,就直接順利轉職的呢! # 結論 這行學無止盡,就算台大畢業,工作十年經驗,還是一直在不斷自學寫程式的奇妙&精益求精 另外,我也有設計免費的 html&css 教材,還有便宜的 javascript 教材,內含「大量練習專案」,不論你最後選擇哪種學習方式,我都推薦搭配拿去學習、練習,稍有難度,但不少人全做完之後就順利面試上班了 以上,簡單分享個人看法