🔍 搜尋結果:vs

🔍 搜尋結果:vs

使用 Tailwind 開發時,適合搭配的 4 款 VSCode 外掛

這些外掛都在這個 VSCode 外掛包裡面 [TailwindCSS Kit](https://marketplace.visualstudio.com/items?itemName=KalimahApps.tailwindcss-kit) 原文出處:https://dev.to/kalimahapps/4-vscode-extensions-i-use-for-tailwind-2him ## 1. [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) ![tailwind css 智能圖像](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4w36g7owmtrmljbesu24.png) Tailwind CSS IntelliSense 是一個強大的工具,可以幫助開發人員更快、更高效地編寫程式碼。它為 Tailwind CSS 類別提供即時建議,減少錯誤並提高程式碼品質。使用 IntelliSense,開發人員可以提高工作效率、縮短學習曲線並改進應用程式的可存取性。如果您是使用 Tailwind CSS 的開發人員,一定要試試這個強大的外掛。 ## 2. [Tailwind Fold](https://marketplace.visualstudio.com/items?itemName=stivo.tailwind-fold) ![tailwind 折疊擴展圖像](https://github.com/stivoat/tailwind-fold/raw/HEAD/images/docs/demo.gif) 在使用 Tailwind 時,此外掛非常有用。長長的類列表會使 html 有點混亂,此外掛提供了一種隱藏它們並僅在需要時顯示的好方法。除了預設功能外,這些選項經過細心設計,幾乎可以滿足任何偏好。例如,我喜歡在點擊線條而不是類別本身時展開類別。 ## 3. [Tailwind Documentation](https://marketplace.visualstudio.com/items?itemName=alfredbirk.tailwind-documentation) ![Tailwind 文件圖片](https://user-images.githubusercontent.com/11172530/163716626-8d74a1bb-f05b-4b45-aa12-70f66e0efad8.gif) Tailwind Documentation 提供對官方 Tailwind CSS 文件的快速存取。此外掛使開發人員能夠直接從 VSCode 編輯器中存取 Tailwind CSS 文件,而無需打開瀏覽器或離開編輯器。 ## 4. [Tailwind Config Viewer](https://marketplace.visualstudio.com/items?itemName=KalimahApps.tailwind-config-viewer) ![Tailwind 配置查看器圖像](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxwuaxi8v4o9olb4g06d.png) Tailwind 配置可能會令人困惑。它們可能呈指數級增長,並使用戶更難了解已解析的設定。這外掛使用戶能夠查看 **resolved** Tailwind 配置,它還會顯示任何與顏色相關的類別(text-\*、bg-\*、accent-\* ... 等)的顏色 --- 以上,簡單分享,希望對您有幫助!

[資源分享] 裝爆的VScode擴充套件,人生沒有擴充套件就是黑白的!

## code spell checker ![](https://i.imgur.com/dEaysXp.png) 不管是自己的英文程度太差,還是粗心大意,把英文字拼錯是家常便飯, 這款擴充套件就是來幫助你的救星! 使用code spell checker馬上會幫你標出奇奇怪怪的單字, 讓你確定沒有不小心把1跟l搞錯,就debug一整天的那種尷尬事件! ## live server ![](https://i.imgur.com/BdyRNga.png) 寫前端最需要的就是看到畫面٩(。・ω・。),و 每次如果都要自己在網址列找到檔案的位置才打開html, 那實在是太沒有工程師的效率了,簡直荒唐!! 當然要使用這款live server來架,馬上就可以看到自己的前端畫面, 而且儲存之後自動更新,根本神器。 ## material icon theme ![](https://i.imgur.com/cLgrQLt.png) 沒有什麼其他的,純粹就是好看! 裝了這款之後可以讓icon變得比較不一樣,整天都跟程式為伍, 當然就是要追求好看的圖圖。 ## prettier - code formatter ![](https://i.imgur.com/DDkFzb4.png) 超級讚的排版好物,懶得自己縮排了啦!就靠這款prettier, 讓你的程式從原本醜醜的排版, 最後,變成人類也能看懂的正常程式,必裝神器之一! ## 補充有人整理的 ### github ![](https://i.imgur.com/7X9O5Dz.png) [專案點這邊](https://github.com/Lin-jun-xiang/vscode-extensions-best/blob/main/README_%E4%B8%AD%E6%96%87.md) ### 影片分享 https://www.youtube.com/watch?v=xGE_M3R69YA [ Alex 宅抬槓 ] Visual Studio Code 外掛生存戰|從 2019 到 2020 前端開發必備安裝推薦 ## 心得 以上都是寫程式過程中會發現的需求,自然會想要找擴充來安裝,提升效率、美觀, 利用這些擴充功能,寫程式的體驗真的變得很舒服呢(๑•́ ₃ •̀๑)。 未來如果有什麼新的,也會持續補充,也歡迎大家分享討論唷~~

自學網頁の嬰兒教材:JavaScript(九)作業分享

[第1課 ── 學習 Vue 元件基本觀念](https://play.vuejs.org/#eNp1kMsKAjEMRX8ldqOCWNxKEdyILvyD2RQngwP2Qc2IIPPvNm1nfKBQSm56btLkIbbeL28dirVQ11NoPW0q2xrvAsEedY0BmuAMTJcyS4anI3LUrR0BFp/PO+forUKWBQGoLN4TVmOjuwvBg7MnF70WLV3XOQHlI4ssuEsJcz2O+5SpNenZfHAFpC7YQXE7vvuEVzYeJceJoyA0/qIJowJQZXaZVRqzxGUmVkqOJrEQr/3wMj/LnVebA2gD58RMlIyJb/+wvv9uE4nf3tdm/7ubxPzy90/ta6nn) [第2課 ── 學習 Vue 的 props 觀念](https://play.vuejs.org/#eNqNkcGO0zAQhl9l5D0URNOWBVbUhJVYEDdOXHNx60mISGzLcVBLlHdnMolDutWuNoqizD+emW9+d+KLc5s/LQop0uboSxfuM1PWzvoAP84PShcIubc1rDbbKR6OrzIDkBk88UGNuWqrAN2gHi1VGzShkaMAsdF6iHr+ahXUq9cx7zG03sSI+g7fnk9nht50O6NRELB2lQpIEUBan5MDU1bqgNXnTNy8/7a/+36bCSKprF8q9+k2Hn+ieFlmvTIFkhDwFL7GXrvd7iWN9vv9m0Uvj5oib1ujUV9Wp9t5IbEWC48vriQjiGuvAZy37r/Rg/s0UMLP4EtTsNXDM29wlWHeK3UClfBgbYWKXF/eyHPX0ThlQB4r1TS0djc3mn56ckE24VzhkIXVQR1/F5xLmHwlxw3WcZGZnAYLHgHQdUzdMw/B0MhLH5mLp3AFM0W/lNa0qYRbd4I7d/o0yrXyRWkSXxa/goS3uzlxsF6jT7zSZUs+v5sTuTUhacq/KOHjLE7QN3mes8KEm2n3iPCo5Yc4bHR2pA6i/wcEYzAB) [第3課 ── 學習 Vue 的 events 觀念](https://play.vuejs.org/#eNqVVM1u00AQfpWVAblV4yRQUVETqlKuLZdcItU9OPE6sWrvmvW6TYkiIXEAVUgcQEUViB+BxAnEEQSvk6g98QrM7tpru04RRHE2++3MtzPfzHhi3I3j5kGKDdvoJAMWxHzDIUEUU8bRztFWyjklyGc0QmazlQPCwXQIQg7BY2nqYd9NQ44mAh1Q8CeY8MRWANJUDbGdyl/P5e7Scm7AME8ZyXcIJcFDDO67Zq9rNkzx7MCzDU9v29yTBOJDbHR9LdtNJbdD4Ntp6Vxgw3EUhy7HsEOoEx1ZfZVW6PZxeMcxfHeA+5TuOwaEHlIG0JXV9VuutwYIx2N+L0d933eMjU5LcyjKPruMOnmQugyXiClzyVAAFd52uw2QMv4X+gPLl45CJUR9pRYw2PpeAMRerHpbZx5dGvhKWQwVXl0JxGhKPLTpet59AMkKeNUvqZNb/0MeBSRNJL0FfnX6GLLkR6FIc+JTwruQq40IWkFmPDan4KLa4/zn2/mL49nx+7PTd/OnJ/Pvr+HP71/Pzh+dnn38MD95Mvvyav7m8fzlj7Ovx7NPn2ffnkv+VgwEnZZuIqNhlOegMjgOpFGfB4RiRuNiGBwuhbBRl7OADHUzS0lqqFamdqL6xUZblIbYVbOVz07NWKp50VZNIkIR5iPqFRFCLGEw2C/GUwYyCpLmVRwFfMkUFTeXNXn1UFXMXM5P5WAW8/m34cwapaio2XcH+0MZvCX1MW2lUyOXS+sDpS7iQcgehG6SAMfuJBdKrY1cC7lMG0KuvarvpkwffOWqW2gyUS2MplN49Yne0I1YahCZlkxAumUpZUL2KfMwRE3gBXk7aw4QEyoFb7J2PM6wQcoSkVxMA8Ixy1DlbDHXC1Io1k1tHrlsGBCrT+GqCIhqJywYjnjhIUvRVHJUI9Pk7ZKhmkRl5/DDwOMjG60W0Y6woi9BYUCwleOKCyExntZhBq63c/hiWu1rpbt73TxA6a16WyulbBaaVHPdWWByo8qyvcikytJbZKOzVr0tC29M/wBn121P) [第4課 ── 學習 Vue 的 v-model 觀念](https://play.vuejs.org/#eNqNVF1v0zAU/StX2VA3qWm7jSIIYQLeeOAJiRfCg5s4m4VjG8cJ66ry27n+ysc6TSxra1/fc33OuY4PySelVn1HkyzJ21IzZW4LwRoltYGv+y9CdQZqLRtYrNZhbtMXhQAoBH1wiRWtSccNHGy0lIgWVJg28wGIhZZ2dnTfFTHk4jKua2o6LeIMwNAHk4HoOHfJCHLIQuB/vh5o4sTQRnFiKM4A8mafMse4TxtZUf6hSGypIgFOdm5aM85phQE/AFZh0GHSqyK5zdexxP8WlJ3hTLiScTgtev20aL4eKCfLZOLorAEF7nLqLIDSUo22AjhS3wnvaAbfjGbiLhgGnuBJ1MvO4LOUnBIxxCP30xWGsVkR30Bk2DDb4h+LTmE3aTZyWfwM7XqpVxXr3QCH3uLM22adNHtFR6s1/d0xjRYHRviXlZy0LaYcoiD/u5wIiaNjkUyRvWWIyJEubjFJ+OjYYMK5FXjxjLolnNMez/fKEH1HsXk2eomN9r7kznnIaqmDnls4HHw/4HjM127kTVh7FyaHwjnVmj33NuH60HvZMsOkyNAQTGU9fe8XGqTBMLzdqAfYuKB7X7ytAf2HVebe5rwKKEWqCpuawbWFXeFXWKilMGnLHvFIXb0J0bEeyiq7Fv56PcsQRAtYFYNhRyNVBunr7bSE/XgjTkSRXSt5Z6Ioh/ZiEEJrvA8mHEfy14NmxGgiYjnEw2Z104alstOt1BjGIxWzcZg6CHaqyaAkihnU8egpOL6rcE0EtjtS/rrTshNVWkpu651RGhnvpK4ohgRefrNQupPGSNzhBrmiSHTKbauIxlMUUsNpncGnep5ujeK2XtyUaHYve6pfoFu9tc8pznc14ua0rcWe9tlms63LcgIf7rwZFHs1YsrKPs9JcrlPhQwv8FzKad13G/tEJF417qVJjv8AFoE/Hg==) [第5課 ── 學習 Vue 的 slots 觀念](https://play.vuejs.org/#eNrNlE1vnDAQhv/KiBySSAHStLlQulJzb3uJVFXiYmBg3YJt2cM229X+9w7GsB/aNtdIKxaP3xnPeJ5hF302JtkMGGVR7iorDa0KVZDsjbYEX7ZPQim00Fjdw3WSzobR5bpQAIXCFy+tsRFDR7AbrZVmf4WKXDYZYAl1Ny73/lkLEje3s8AiDVb51WTYe2Wh+Jenh9xUTtibThDyCiDvt3E5JVl1wrlPRRSWZRu3VmyLyOsAfugB1mKD0GlHnCKLKpJaAWmgNYJUhFYhJfC8lg6EMcB/umk6qTCZYixnw5XwziE2wPOY/Lev8F02MmjT00TTJVO/fjV5i3URgdWDqrF+izWcbPLS0babdEmoIrTWiLqWqs3g4d68fJxsvbCtVHGpiXSfwbvDTi0dB91m0HQ4234OjmSzjbliYqwycEZUGJdIvxFVEIlOtiqWnBRjV7EMbdipdKdtBldN03iLRysJgMxZlqL61frr5mO8ftw91XNP/i3nzVnNwPrLiO6i45E5m7JLo8O3ZbU5zA0PxkRABk9adyiUn515hl4ZjlpuIJvR2i2Rwst+mY3crHLXaUpXeWpmWzlwb2Y6CvICUKJHjjWRw/58OptXE88jIUdeecrn/xcUM5c54ZDBfehYw42OnfyDjMaHgIbvwhR+dqsG68arN9qTH5wX3o6oKrWtkZWKv0snptiKWg584Y+L9hyXS80mKxRDaBmzoOF2UuzNjbaM9GAM2kq4+bhLJbHX6CDHy8wY4A7uk/fuvNpsrTeHaboAXluKm4fHxzs4PDjO7RynoCR0fIlxufRjcvd/AZMZBoM=) [第6課 ── 學習用外部狀態管理 vue 元件](https://play.vuejs.org/#eNrtVUtvGzcQ/isDpYAdQCs7dYMCW0VogB56aC499BL1QO3OSqz5KjkrSwn83zPkch+SpSQ/IIKw4Azn/fj4efbeucW+xVk5W4bKS0ertZHaWU/w4fiHFMpuofFWw83irmdEhZu1AVgbPCTRGhvRKoLPkVtZ1jdoKJQdAwZT80g+p28tSNy+7gU8UutNTwGEnX16r9DTB1sLVUIjVMCk19/+iUrZC7fPycXa8H95N6TEBKF2ShAyBbDctETWwO+VktXju/Xs1CG8A/ItrmerxFvedeLXVcdoRtXEO1FN6vpY1F1d94W2NaoX3lk3SdMQM7wiSQr7aE5SYZOjWGUNceVXf1mPGqQLrYbaKushSAKhkbg9JmBFseAgaulkkJU0W0AlaQF/o2cVj46DR1O3ISnurWodRQ/5FAD3aCSb4/572+ttlDC1JCkDOPQNejbBZ7Ik9BxQgCCw2jBrjwpMq/9vhQY8oK8km5c8NhpES3Mwgti3ljyMYt45ASU2nNbia/l3xS4ID7Syj2eSy7uh9t9ux9jR6+3IHf7Rju9pR6VswK925OSSyUBHLnKUyyuX4cGJuuYSlfDWHeDNvTv81vGr1gfrSw5Pctl95mrht9IUXm53VI7iHT4kD7P5bAptJ1i45thfQhzH4K1jfPt4k2bmH6EYEv9NEMQaWkbs+3jTOkY5LC+IRIxsCesBIde0jwIDHX9bpBEhu1/GSdrJsBjNjhIdtmaUZPVk9MxGUv4pBnl7IcI5dDoTm/0xHdbU++Dp3dl6BHluQGzxacjfcpage3CWXfUYfh3AeRlruWeHIgReWDYZ95RXOK5ux+hr020vz9pUoRK+Hm74bvcwnJkKyhKPvEaWTJvOohwLc0eNu4nK0l3TzgBwSd+tEgAl4vxJSYWcxMfpTq1O1uqS5cmLE0nOOy9bd7q+ZnGk+AXL7duI6nHrbWvqooqYVYLfbsTt/Rzyf/Hr67xjzjIsMVzwUywPWGcuWVfCfSby/vWkwmZCbSxHrEeaUYoDPLI5hf12/9cGks2RY0klLaHi77DlQsmtKSRnxgM5uUmjtIjtvp7Wq6ZpBrA4FE+yph2Dy/2ILDvM6PF25A0o9PPI+664gxMVFhukJ0SThaI8A6HnlyCVkSNrdX/JMFujLzw/Dy1n9zAiWJ/a7mGeT65P80IWHRKOVR4y6BgTe4MVJQ0WffaTRBtOpgjyEwPWm19exnOK111vAqqmK0zBz9B5CGdQfhrqFKufvwCVGY00) [第7課 ── 學習開發狀態複雜的 vue 元](https://play.vuejs.org/#eNrVWHtv2zYQ/yqEE9T26ncad1DtoMswZAXW/ZECw4AoQGmJtrVIlEBRTrLA333HpyhZtuNuAzYkkMU73uN3d3ycXlo/ZNlgU5CW15rlAYsyfuXTKMlSxtHn5x/TOGVoydIEtQdDPRbT2z5FyKfkSU4MyRIXMUcvghqkIE0J5bmnCMgo6onRVj5DzHGna/iM8IJRM0JoTZ5+w7GH2mfLJR6PRtIaiJbyj5gHa6tf0n0K/7OhBQEDTpIsxpzACKFZ8twPJJ44Wq052vSTNCTx3G8pc37rajY0c2oSIWYPRwVmQ2sPPIJxzp9jZfs74+kifern0Z8RXXnwzkLC+kD6oJgJZquIemikxxkOQzlTERQ8qbPVaznJqORuX1oylmZlRiQSwFAQD33hDKzIsCIVGw9dp2lMMNVEAb9KU1kgSSSyfNcuMkgo8Uqt7fujafY5I6FM8+TyUhtCaMUIoZI6no4tdQEqJXFkSSoHtyQHhE6lWH6ON+S2wYCg3zQaEZzrXUNBwRhU8+3NNZhhq0VHaBNyo66x5hRmQvg6DctABxAy9olmBS/jgBBfR/ngXISv0xC7HsBpd7VqbSJYk+Dhs53zC6ErvjYqfe7zaIk6Um2paBDLWWiG3lvbPj9mW/Ld6EpPhAmAqX+al6HKZ0dE1sEqHBMkdDVHI/TmDZKD2VxkRU4TOsXfjmE0F4F4+2uRLAhTagc8VeXaGU+7A1ggXzhmvDPptUftrpkpFZlCOkFEV9lhCQPreBKbA+nIliUKSCVFRdBM2yIS56SMpBZTk4xIqcSKVSvHBOLfyovj0+ti/T/IitkgTJBNDI9kxkxzc2NU7cmORvefSc43rJ3jM//h7OhN2kRZh/BIbvQsNzVaz57MlH7tS47ZX+dzZ4PdXaYZZjn5RLmUuRvfo7cym3eTezhGLD6dSqeEqnIXVu5dk1wJryp2acWmTWLl4QaSX8Xpdv7ieL/t6aFxyxK0vW33az18+qoi7iFHLmRhtIHzEec5XKnkJaofYBb6LeQZ6ou+jsifnr6HiOcWLl/KXlWLgqOuZEKRvC4JRe0FDh5WLC1oqLhtzznZHXVD0NekOsOUiCufgVthQsU6LGDGeEHiq59/+n02VK8OLxK3AVe0LynC3Y0oNyCWtee3lORHOQdYBxbPOdkAnAEsvBXhA6mrC1oT/KQKFaTfw/hjEEfBg4iWvZsIKmSUCWLTRcPF7QSoFgUon4YooGUq9EI6rm73RoM/ZwI3w3QFkFEUKolStWYkEYXRSKGCN9gO4b28mesDtOJFNd7gZB9Cs19K7KouSBi9GuQKWDcngQSJk0Ha0+hEmDW5vwNUsK5PAgoSJwM1O/uJOKtidZjlu3k70LgpY7Z5Ew2bhyi0t/UW7SIzXVxa8Dii0FfZaXI3HJQ7nNH3GIUcbs+Ty5EVtvomJc20hQ5Jt44Mh1EBvcalw4D+co3D9BFaGPgDDjqbTqeOH6r7NZDsruihM0Jcf9W8hgBYswazmi975Ca1FxcXH2SLLr4NQAyAtFwu65JVQ7XNGkQMiF0lR/yqnAnGwJqogwVaxlqcoR/nPE0q4Q6jHMrj2UPLmBjaH0UOPZfo/ikH9XCawJMwzcUQPdqPoK7AnwrnoK9wGNgOverN+LA3++yVasVDHTTGghAHxVX0MVkClu+tMU6eeJ/Dgs1h4YMfRZYRFuDcrRRYg9/m9U4M8wwHpL8g/BF2qldBA9sebAWQ3nUU25VVc8N+P9HOiofYNWoL8V3prYQtLdfSVwmTheeqFntbc4h3v+doIbWzVp0ZT+qFyUzJlkbt96DtX340SC4=) 作業心得: 製作元件就像在組LEGO一樣,基礎和常用的就那幾個,把他們組一起成為一個新的作品,一開始製作觀念還很模糊,之後就慢慢熟悉,也了解能製作出可以重複使用元件多麼重要

我推薦 Svelte 給所有工程師的 10 個理由

原文出處:https://dev.to/mhatvan/10-reasons-why-i-recommend-svelte-to-every-new-web-developer-nh3 儘管 [Svelte](https://svelte.dev/) 的初始版本早在 2016 年 11 月就發布了,但它在 JavaScript 前端框架中仍然處於劣勢,並且最近才開始受到社區應有的關注。 在使用了多年的各種 JavaScript 框架(包括 Angular、React 和 Vue.js)之後,我認為我對編寫程式碼如何愉快以及如何令人沮喪有了良好的總體印象。 幾年前,使用 [jQuery](https://jquery.com/) 編寫程式碼感覺就像來自純 JavaScript 的啟示。然後在我的第一份工作中,我開始使用 Angular 2,突然間 jQuery 感覺像是一個拖累。現在,React 是最酷的孩子,相比之下,Angular 感覺太複雜了。您可能會看到這是怎麼回事! 對我來說,Svelte 是快速變化的 JavaScript 框架生態系統中的下一個進化步驟。用 Svelte 的方式編寫感覺很容易,你可以看出它的建立者 [Rich Harris](https://twitter.com/Rich_Harris)厭倦了現有框架要求您學習的所有煩人的抽象和必要的樣板程式碼。 現在你可能會問自己這個問題: ## 是什麼讓 Svelte 與眾不同? 您可能聽說過 Svelte 出現在諸如 [前端框架的真實世界比較](https://medium.com/dailyjs/a-realworld-comparison-of-front-end-frameworks-2020-4e50655fe4c1) 和 [State of JS Survey](https://2019.stateofjs.com/front-end-frameworks/) 等開發人員調查將其列為在捆綁包大小、性能、程式碼行數方面排名最好的框架之一以及最重要的開發者滿意度。 與流行的 [React](https://reactjs.org/) 和 [Vue.js](https://vuejs.org/) 庫相比,它們在執行時執行大量工作並使用一種稱為“虛擬”的技術DOM diffing”用於檢測變化,Svelte 作為建置步驟被編譯成無框架的 vanilla JavaScript,因此可以從大量程式碼優化中受益。 出於本能的猶豫,我起初將 Svelte 視為“只是另一個 JavaScript 框架”而不予考慮,也沒有費心去研究它。第二次聽說後,我想知道:Svelte 是炒作還是真的那麼好?我決定對它進行實戰測試並將其用於我的個人專案。 現在幾個月後,我可以給你一個明確的答案: ## Svelte 簡單、強大且優雅,您會愛上它! 事不宜遲,以下是我向每位開始學習編程的新 Web 開發人員推薦 Svelte 的十大理由: ## 1. Svelte 元件易於理解 如果您以前從未見過 Svelte 語法,這就是一個簡單示例的樣子: https://gist.github.com/mhatvan/3630989d364e4020f26ebb96d2d7c332 與其他引入大量抽象概念、需要花時間學習和理解的前端框架相比,看到 Svelte 只是並排使用普通的舊 HTML、CSS 和 JavaScript,真是令人耳目一新。您可以通過其對初學者友好的語法查看並輕鬆辨識此處發生的情況。 ## 2.簡單寫簡潔的程式碼 正如您在上面的程式碼示例中看到的,您編寫的業務邏輯既簡單又易於閱讀。畢竟,您編寫的程式碼越少,錯誤就越少,對吧? Svelte 的天才創造者 Rich Harris 在他的文章 [少寫程式碼](https://svelte.dev/blog/write-less-code) 中對 React 和 Vue.js 進行了一些很好的比較。根據他對編寫簡單的兩個數字相加邏輯所需的字符的檢查,React 元件通常比其 Svelte 元件大 40% 左右! ## 3. 與標記語句的反應性 每當您希望根據其他變數更新和重新計算變數值時,您可以使用反應式聲明。只需在您想要響應的變數前面放一個美元符號,您就可以開始了! https://gist.github.com/mhatvan/7e2f0fea362c79d64a34cb7e0c088453 每次單擊按鈕時,`count` 將增加 1,而 `doubled` 將知道 `count` 的值發生變化並相應地更新。從反應性的角度思考真的很有趣,而且寫起來感覺很好。 ## 4.開箱即用的簡單全局狀態管理 無需任何復雜的第三方狀態管理工具,如 [Redux](https://redux.js.org/) 或 [Vuex](https://vuex.vuejs.org/)。 您只需將一個變數定義為可寫/可讀存儲,並在任何以 `$` 符號為前綴的 `.svelte` 文件中使用它。 https://gist.github.com/mhatvan/710b6bb6df4ece7e9a5f53886eb2dd0d 在此示例中,我們檢查當前環境,它作為值存在於我們的商店中,並使用它來決定是否應顯示 cookie 通知。很簡單,不是嗎? 使用 Svelte 存儲,您也永遠不必擔心內存洩漏,因為以 `$` 符號為前綴的存儲變數充當自動訂閱和自動取消訂閱。 ## 5. 內置可存取性和未使用的 CSS 檢查 Svelte 希望讓網路變得更美好,並通過程式碼中的有用提示幫助您。 每當您忘記將 alt 屬性放在 `<img>` 標籤上時,Svelte 都會為您顯示 `A11y: <img> 元素應該有一個 alt 屬性` 提醒。在 Svelte 中實現了一長串可存取性檢查,它們會提示您而不會成為麻煩。 為了使程式碼盡可能簡潔並避免遺留程式碼片段,只要在元件中找不到相應的標記,Svelte 還會為您標記未使用的 CSS 選擇器。 ## 6.元件自動導出 每當你想在元件 B 中使用元件 A 時,你通常需要先編寫程式碼導出元件 A,這樣它才能被元件 B 導入。使用 Svelte,你永遠不必擔心忘記導出, `.svelte` 元件始終默認自動為您導出,並準備好由任何其他元件導入。 ## 7. 默認情況下樣式是有範圍的 類似於 [CSS-in-JS](https://webdesign.tutsplus.com/articles/an-introduction-to-css-in-js-examples-pros-and-cons--cms-33574) 庫,Svelte默認情況下,樣式是有範圍的,這意味著 `svelte-<unique-hash>` 類名將附加到您的樣式,因此它們不會洩漏和影響任何其他元件樣式。當然,您可以選擇全局應用樣式,只需在它們前面加上 `:global()` 修飾符,或者如果您願意,也可以只使用 `.css` 文件。 ## 8. #await 塊 對於大多數 Web 應用程式,您將需要處理異步資料以向用戶顯示有用的統計訊息。 https://gist.github.com/mhatvan/2e44dc1ec402f477830f90bd77614f34 `{#await}` 塊的優點是您不必為已解決/拒絕的承諾定義額外的狀態,您只需在模板中定義內聯變數即可。 ## 9.傳遞道具的速記屬性 如果存在與變數名稱相同的 prop 名稱,我們可以將其作為簡寫屬性傳遞給元件,如下面的“{message}”。與使用 `message="{message}"` 相比沒有任何優勢,但更簡潔。 https://gist.github.com/mhatvan/9085f5330eeccdc2238e4f4e609b4f88 在上方,您可以看到根據 round 是真還是假將 class:round 屬性應用於按鈕。這很容易成為一個可重用的元件,您可以從外部傳遞 `round` 的值來有條件地決定元件的樣式。 ## 10.內置效果和動畫 Svelte 預裝了強大的效果模塊: - `svelte/motion` 效果,如補間和彈簧 - `svelte/transition` 效果,如淡入淡出、模糊、飛行、滑動、縮放、繪製 - `svelte/animate` 效果如翻轉 - `svelte/easing` 效果,如彈跳、立方體、彈性等等 Svelte 官方教程中有幾個示例,但我最喜歡[這個進度條示例](https://svelte.dev/tutorial/tweened),因為它很簡單。 動畫是 web 開發的一個領域,您通常會在其中尋找外部依賴項來為您處理它,因此您可以開箱即用地使用它們真是太好了。 ## 不採用 Svelte 的合理理由 為了避免讓這篇文章聽起來像一篇冗長的狂熱帖子,以下是我迄今為止使用 Svelte 時遇到的缺點: ### `.svelte` 文件不能導出多個元件 一方面,我們受益於默認自動導出的 .svelte 文件,但這也意味著我們無法從單個文件導出多個元件。我不認為這有什麼大不了的,因為它會迫使您遵循最佳實踐來使用許多小的獨立元件編寫您的應用程式,這使它們易於理解和單元測試。 ### 一般模板語法 為了顯示條件邏輯,Svelte 使用類似於眾所周知的 [Handlebars](https://handlebarsjs.com/guide/builtin-helpers.html#if) 模板語法的語法。 https://gist.github.com/mhatvan/95cc1837441a272cb8422fcae24d91e0 這種編寫邏輯的方式我沒有遇到任何問題,但我更喜歡更簡潔的語法。 ### 使用 export let 在子元件中接收 props 當您想要將值從父元件傳遞到子元件時,您需要將一個值作為屬性傳遞,並使用帶有匹配變數名稱的 export let 來接收它。 https://gist.github.com/mhatvan/b67ceafb05d21c15b5782c068690d632 在現代 JavaScript 中,`export` 通常用作導出模塊的關鍵字和 `let` 聲明塊範圍變數,所以我覺得語法濫用現有關鍵字,但我習慣了它並且效果很好. ###開發速度 這與 Svelte 的開發體驗沒有直接關係,但您絕對應該知道,在財務支持方面,Svelte 無法(目前)與更大的和讚助的開源專案競爭,如 React、Angular、Vue.js 和其他專案,截至目前的貢獻者數量和受歡迎程度。 儘管如此,社區正在迅速發展,社區為 Svelte 建置的第三方專案列表也在不斷增加,這些專案可在 [Made with Svelte](https://madewithsvelte.com/) 上找到。開發 Svelte 相關工具的開發人員都是天才,您可以隨時在 [Discord](https://discord.com/invite/qa4pnmw) 頻道、[Twitter](https://twitter.com/sveltejs) 上尋求幫助) 或 [Reddit](https://reddit.com/r/sveltejs)。 Svelte 最近還加入了 TypeScript 支持,而且效果很好! 我喜歡 Svelte 的易用性、較小的包大小和開發人員體驗等因素,因此我可以接受較慢的開發速度作為權衡。如果您總是需要盡可能快地合併最新功能,那麼您可能需要查看其他可用的 JavaScript 框架。 ### 缺少可用的工作 大多數公司仍在尋找對三大前端框架有經驗的開發人員,但也有各種知名的 Svelte 早期採用者,如 IBM、Apple、Philips、GoDaddy、1Password 或紐約時報,僅舉幾例.您可以在 [Svelte 網站](https://svelte.dev/) 底部找到大量使用 Svelte 的公司。通常,採用新框架需要一段時間才能出現在公司的工作機會中。儘管如此,Svelte 學習起來很有趣,許多開發人員喜歡使用 Svelte,尤其是在他們自己的個人專案或小規模應用程式中。 ## 結論 如果對初學者友好的語法、較小的包大小輸出和 Svelte 的瘋狂性能對您來說是一個不錯的選擇,我建議您開始使用 [Svelte 教程](https://svelte.dev/tutorial/basics)。該教程非常詳細,您可以快速了解該框架的強大功能。 在 JavaScript 框架的世界裡,事情肯定會快速變化,我希望你和我一樣相信 Svelte 擁有所有的優勢和潛力,可以讓它成為新的 #1 JavaScript 前端框架! 您之前使用過 Svelte 嗎?你的經驗是什麼? 在評論中告訴我,我很想知道。 感謝閱讀,希望您喜歡! ## 有用的資源 - [Svelte 教程](https://svelte.dev/tutorial/basics) - [Svelte REPL](https://svelte.dev/repl) - [Rich Harris - 重新思考反應性](https://www.youtube.com/watch?v=AdNJ3fydeao) - [為什麼要苗條](https://github.com/feltcoop/why-svelte) - [為什麼 SvelteJS 可能是新 Web 開發人員的最佳框架](https://dev.to/bholmesdev/why-sveltejs-may-be-the-best-framework-for-new-web-devs-205i) - [為什麼我們從 React 轉向 Svelte](https://medium.com/better-programming/why-we-moved-from-react-to-svelte-f20afb1dc5d5) - [我喜歡 Svelte 的寫作風格](https://css-tricks.com/what-i-like-about-writing-styles-with-svelte/) - [我在 React 和 Svelte 中建立了完全相同的應用程式。這是差異。](https://medium.com/javascript-in-plain-english/i-created-the-exact-same-app-in-react-and-svelte-here-are-the-differences-c0bd2cc9b3f8) ## 正在尋找 Svelte 支持的伺服器端渲染解決方案? 在使用 [Sapper](https://sapper.svelte.dev/) 接觸框架後,我是一個忠實的粉絲,一有機會就嘗試推廣 Svelte 之道。 如果您要建立一個網站並正在尋找合適的工具,我發表了一篇關於我迄今為止使用 Sapper 的經驗的文章,供您在此處閱讀:[“為什麼我為我的網站選擇 SapperJS,以及我做了什麼”到目前為止,我已經了解了該框架”](https://markushatvan.com/blog/why-i-chose-sapperjs-for-my-website-and-what-ive-learned-about-the-framework-so-遠的)。

Svelte 程式範例:動手寫一個「蕃茄鐘工作法」小專案

原文出處:https://dev.to/vintharas/discovering-svelte-getting-started-with-svelte-writing-a-pomodoro-technique-app-2lph ## 開始使用 Svelte [開始使用 Svelte 的最簡單方法](https://svelte.dev/blog/the-easiest-way-to-get-started) 是: 1. 瀏覽 [svelte.dev 中的 Svelte 教程](https://svelte.dev/tutorial) 2. 在 [svelte.dev 中的 Svelte REPL](https://svelte.dev/repl) 中進行試玩 3. 使用 svelte 模板從頭開始建立應用程式 儘管我認為通讀教程對於學習 Svelte 的語法和可用的東西確實很有幫助,但我認為**學習某些東西的最佳方法是在盡可能接近它的環境中實際操作**會在現實世界中開發一個 Svelte 應用程式。 **[你需要自己努力解決問題才能真正學到東西](https://amzn.to/2soWN5m)**。 ## 建立一個新專案 我們使用 [degit](https://github.com/Rich-Harris/degit)(也是由 Svelte 的建立者 Rich Harris 編寫的專案腳手架工具)生成一個新專案。類型: ``` $ npx degit sveltejs/template il-pomodoro ``` 這將在 `il-pomodoro` 目錄中建立一個全新的 Svelte 專案。我們跳進去,安裝依賴項並執行開發伺服器: ``` # Jump in $ cd il-pomodoro # Install the dependencies $ npm install # Run the development server $ npm run dev ``` 現在我們在 localhost:5000 上打開瀏覽器,讓我們看看我們得到了什麼…… **塔達!測試成功!** ![](https://thepracticaldev.s3.amazonaws.com/i/zyr2vgqeub11k253xsdx.png) ## 設置你的編輯器 Svelte 是一個編譯器優先的框架,它編譯代表 Svelte 元件的 .svelte 文件來建置 Web 應用程式。我在教程中看到的那個特殊的 .svelte 擴展和非 Web 標準語法告訴我,我需要在我的編輯器中提供一些額外的支持來處理 Svelte。 Svelte 博客有一篇關於[如何設置編輯器以使用 Svelte](https://svelte.dev/blog/setting-up-your-editor) 的好文章。我通常使用 Vim 或 VSCode,所以讓我們設置這兩個編輯器以使用 Svelte。 ### 設置 VSCode 以使用 Svelte 對於 VSCode,有 [svelte-code](https://marketplace.visualstudio.com/items?itemName=JamesBirtles.svelte-vscode) 插件,它支持 `.svelte` 語法突出顯示、診斷、自動完成和 [更多](https://marketplace.visualstudio.com/items?itemName=JamesBirtles.svelte-vscode)。 ### 設置 Vim 以使用 Svelte 對於 Vim,[設置你的編輯器文章](https://svelte.dev/blog/setting-up-your-editor) 沒有提供很多支持。它基本上告訴您將 .svelte 文件的文件類型更改為 HTML。經過一番挖掘,我發現了一些插件,它們可以讓你在 Vim 中獲得更好的 Svelte 體驗,並達到 VSCode 的標準: * [vim-svelte](https://github.com/evanleck/vim-svelte) 為 .svelte 文件提供語法高亮和縮進 * [coc-svelte](https://github.com/coc-extensions/coc-svelte) 通過連接到 Svelte LSP [^2] 為 Svelte 開發提供類似 IDE 的高級支持。這是 [coc.nvim](https://github.com/neoclide/coc.nvim) 自動補全插件(恰好是我最喜歡的 vim 補全插件)的擴展。 好的,現在我們已經設置好了編輯器,讓我們仔細看看我們的新 Svelte 專案。 ## 檔案結構 我們在編輯器中打開 il-pomodoro 文件夾,我們會看到一堆文件和文件夾: * 一個 `src` 文件夾,其中包含 Svelte hello world 應用程式的源程式碼 * 一個 `public` 文件夾,在 Svelte 編譯器編譯和處理後將包含我們的 Web 應用程式 * `rollup.config.js`,其中包含我們的捆綁器 ([rollup](https://rollupjs.org/)) 的配置。 Rollup 負責使用 Svelte 處理我們的源程式碼文件,以生成可以在瀏覽器中執行的開發和生產包。 對於初學者來說非常有趣的部分發生在 `src` 文件夾中,所以我們接下來要看的地方。該文件夾僅包含兩個文件: * `App.svelte` 這是我們應用程式的根元件 * `main.js`,其中包含用於初始化我們的應用程式的引導程式碼 作為我們應用程式入口點的文件是“main.js”: ``` import App from './App.svelte'; const app = new App({ target: document.body, props: { name: 'world' } }); export default app; ``` 這會建立一個新的 Svelte `App` 元件,並將其附加到 `document.body`,並使用一個名為 `title` 的屬性,其值為 `world`。 讓我們看看 `App` 到底是什麼: ``` <script> export let name; </script> <main> <h1>Hello {name}!</h1> <p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p> </main> <style> main { text-align: center; padding: 1em; max-width: 240px; margin: 0 auto; } h1 { color: #ff3e00; text-transform: uppercase; font-size: 4em; font-weight: 100; } @media (min-width: 640px) { main { max-width: none; } } </style> ``` 我懂了!所以 Svelte 元件是一些可重用的 UI,它封裝了元件的標記 (HTML)、它的行為(`<script>` 標籤內的 JavaScript)及其外觀和感覺(`<style>` 標籤內的 CSS) .涼爽的!這就說得通了。 如果我們回到標記中,我們可以理解當我們將它指向 localhost:5000 時我們在瀏覽器中看到的內容: ``` <main> <h1>Hello {name}!</h1> <p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p> </main> ``` prop `name` 在實例化時傳遞給元件,並保存在該 `name` 變數中: ``` <script> export let name; </script> ``` 然後傳播到元件的標記,並呈現在我們在瀏覽器中看到的“h1”標籤內。涼爽的!有點奇怪但熟悉的“export let name”語法必須是**Svelte 元件將其 API 定義為 props 的方式**。 ## 加入標題 讓我們開始修補一些簡單的東西,比如為應用程式的第一個視圖加入標題並將其綁定到一些資料。初始模板給了我如何做到這一點的提示。我只需要向我的元件加入一個新變數以包含該標題。因為我在原始模板中沒有用到 `name` 變數,所以我將替換它: ``` <script> export let title </script> ``` 並更新 `main.js` 以注入我的應用程式的標題: ``` import App from './App.svelte'; const app = new App({ target: document.body, props: { title: 'il Pomodoro' } }); export default app; ``` 再想一想,我真的不需要將該變數公開為道具。我們不希望此元件的用戶更改此標題,因此我們將其保留為元件內部的一部分。 讓我們重寫我們的 App 元件來執行此操作: ``` <script> let title = "il Pomodoro"; </script> ``` 最後,我將更新 HTML 模板以使用“title”而不是“name”: ``` <main> <h1>{title}</h1> </main> ``` **搞定了!** ![](https://www.barbarianmeetscoding.com/images/svelte-il-pomodoro.jpg) ## 任務列表 驚人的!讓我們繼續建立一個非常簡單的任務列表。由於這感覺像是一個完全獨立的責任,我們將把它放在它自己的元件中。 我建立了一個新文件“TaskList.svelte”來表示該新元件並加入了一些標記,以便在我從“App.svelte”中使用它時盡可能少地出錯: ``` <p>I'm a list of tasks</p> ``` 我將它加入到 `App.svelte`: ``` <script> let title = "il Pomodoro"; </script> <main> <h1>{title}</h1> <TaskList /> </main> <style> /* styles omitted for sake of clarity. They'd be here. */ </style> ``` 而且……沒用。嗯……我做錯了什麼…… VSCode 和瀏覽器都會警告我以下內容: ``` 'TaskList' is not defined. svelte(missing-declaration) ``` 這告訴我兩件事: 1. 我的 vim 設置沒有按預期工作,因為我在編輯器中沒有收到錯誤(稍後要解決的問題),並且 2.我好像忘記導入元件了! 當然!所以我將它加入到“App.svelte”元件中: ``` <script> let title = "il Pomodoro"; import TaskList from './TaskList.svelte'; </script> <main> <h1>{title}</h1> <TaskList /> </main> ``` 是的!** ![](https://www.barbarianmeetscoding.com/images/svelte-tasks-list-text.jpg) 現在讓我們加入一些任務。我今天的前 3 項任務是: ``` <script> const tasks = [ "plan some fun trip with Teo", "buy some flowers to my wife", "write an article about Svelte" ]; </script> ``` 現在我需要在列表中的螢幕上顯示這些內容。 Svelte 有一種特殊的方法來迭代模板內的列表:[{#each} 塊](https://svelte.dev/docs#each)。 它是這樣工作的: ``` <ul> {#each tasks as task} <li>{task}</li> {/each} </ul> ``` 因此,我們遍歷 tasks 列表中的每個 task 並將其放入列表項 li 元素中。我們還從列表中刪除了點,因為它們看起來很糟糕: ``` <style> ul { list-style: none; } </style> ``` 這就是我們得到的: ![](https://www.barbarianmeetscoding.com/images/svelte-tasks-list.jpg) **叮叮叮!** 番茄鐘結束了。得走了!我們將很快繼續使用更多 Svelte、交互式任務列表和番茄鐘。 > ### 尋找番茄鐘應用程式的源程式碼? > https://github.com/Vintharas/il-pomodoro-in-svelte > https://svelte.dev/repl/27164871e86d4ce1a9815489dc323500?version=3.16.7 ## 到目前為止的一些思考 驚人的!這是開始使用 Svelte 的快速方法。到目前為止,這是我的印象: * [svelte.dev](https://svelte.dev/docs) 真的很棒。 * [交互式教程](https://svelte.dev/tutorial) 有一個循序漸進的介紹,帶您了解 Svelte 的所有功能和重要概念。 * [Svelte playground](https://svelte.dev/repl) 真的很酷,它可以讓你修改 Svelte 建立多文件應用程式,保存它們並與你的朋友和同事分享。 * [開發文件非常好](https://svelte.dev/docs) 也非常全面並且有很多示例。將它們加入書籤並根據需要用作參考。 * **以上所有內容都提供了與 Svelte 的美妙初次接觸**,當您第一次進入一個新的生態系統時,您會非常感激。 * 開始新專案的方式有點奇怪。我已經習慣了所有具有 CLI 的流行框架,使用 `npx degit etc...` 來建立一個新專案有點令人困惑。但在前 5 秒的混亂之後,我只是執行命令並繼續我的生活。 * **我對文本編輯器支持的第一印象並不好**,例如,VSCode 沒有在 Svelte 模板內為我提供語句完成功能,而我希望它能工作(例如,允許我過濾“任務” `)。在我試用 Svelte 的短暫時間內,我沒有讓 Vim 設置正常工作。 * **使用 Svelte 本身就是一種非常好的體驗**。 * 初次接觸時,感覺 Web 標準非常友好,並且一切如您所願。最小驚奇原則非常適用於 Svelte。 * 我喜歡 Svelte 元件的平面結構,以及它在 HTML 標記、Javascript (`<script>`) 和 CSS (`<style>`) 中劃分元件的方式,這很有意義。樣板文件的數量幾乎可以忽略不計。 * 在標記中註入資料很簡單 * 使用 `export` 暴露 props 雖然不是標準的但很有意義並且很容易理解。 * 我想知道為什麼 Svelte 使用 `{#each tasks as task}` 而它可以使用 `{#for task of tasks}` 並減少學習 Svelte 的人的認知負荷。 (也就是需要學習更多的自定義語法) 這就是今天的全部內容!希望你喜歡這篇文章。保重並期待更多 Svelte 即將推出。 > 您是一位經驗豐富的 Svelte 用戶嗎?如果是這樣,請不要猶豫,告訴我我做事有多麼錯誤 :D 我很樂意聽取您的意見,我們都會因此變得更好。 ## 在 Vim 中修復 Svelte 經過一些故障排除後,我意識到按照 Svelte 博客中的建議,我之前使用自動命令設置 Svelte 以將 .svelte 文件的文件類型更新為 html: ``` augroup svelte au! BufNewFile,BufRead *.svelte set ft=html augroup END ``` 這意味著沒有應用 coc-vim 和 svelte 語法文件,因為它們需要 svelte 的文件類型。刪除自動命令後,一切都像在 Visual Studio Code 中一樣好用。哇哇! [^1]:查看 [這個超級古老的番茄工作法應用程式](https://www.barbarianmeetscoding.com/projects/ilpomodoro/) 我在開始進行 Web 開發的那一天使用 Knockout.js 編寫的。 [^2]: LSP 代表語言伺服器協議。 (來自維基百科)它是一個開放的、基於 JSON-RPC 的協議,用於文本編輯器或 IDE 和提供編程語言特定功能的伺服器之間。該協議的目標是允許獨立於任何給定的編輯器或 IDE 實現和分發編程語言支持。

22 個很好用的 CSS 小訣竅&特殊小技巧

**🚨🚨注:**本文分享的所有tips、tricks都是GitHub repository[【css tips tricks】](https://github.com/devsyedmohsin/css-tips-tricks)的一部分。覺得有用的話請查看資源庫並給它一個star🌟 原文出處:https://dev.to/devsyedmohsin/22-useful-css-tips-and-tricks-every-developer-should-know-13c6 ## 1. Docs Layout 僅用兩行 CSS 建立響應式文件樣式的佈局。 ``` .parent{ display: grid; grid-template-columns: minmax(150px, 25%) 1fr; } ``` ![佈局](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ojs8nvly2ugashxwqif8.png) ## 2.自定義游標 查看 github 存儲庫 [css 提示技巧](https://github.com/devsyedmohsin/css-tips-tricks) 以了解更多訊息。 ``` html{ cursor:url('no.png'), auto; } ``` ![帶有自定義光標的圖像](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ba8kist57vp6l9spw8w2.gif) ## 3. 用圖片填充文本 ``` h1{ background-image: url('images/flower.jpg'); background-clip: text; color: transparent; background-color: white; } ``` ![Air Max](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0a7my28raxr80upv77k1.png) **注意:** 在使用此技術時始終指定 `background-color`,因為這將用作後備值,以防圖像因某種原因無法加載。 ## 4. 給文本加入描邊 使用 text-stroke 屬性使文本更易讀和可見,它會向文本加入筆劃或輪廓。 ``` /* 🎨 Apply a 5px wide crimson text stroke to h1 elements */ h1 { -webkit-text-stroke: 5px crimson; text-stroke: 5px crimson; } ``` ![NETLIFY](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h9xcwsh18vxqw1uaj5h3.png) ## 5.暫停 Pseudo Class 使用 `:paused` 選擇器在暫停狀態下設置媒體元素的樣式 同樣 `:paused` 我們也有 `:playing`。 ``` /* 📢 currently, only supported in Safari */ video:paused { opacity: 0.6; } ``` ![河上的棕櫚樹](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dq1za9uri1a37kqyh1y1.gif) ## 6.強調文字 使用 text-emphasis 屬性將強調標記應用於文本元素。您可以指定任何字串,包括表情符號作為其值。 ``` h1 { text-emphasis: "⏰"; } ``` ![時間是良藥](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6l1oifo8erkkblsk7ilt.png) ## 7.樣式首字下沉 避免不必要的 `<span>`,而是使用偽元素來為您的內容設置樣式,就像 `first-letter` 偽元素一樣,我們也有 `first-line` 偽元素。 ``` h1::first-letter{ font-size: 2rem; color:#ff8A00; } ``` ![Gitpod.io](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1jtvgnx1y1xqf0sd9b7.png) ## 8.變數的回退值 ``` /* 🎨 crimson color will be applied as var(--black) is not defined */ :root { --orange: orange; --coral: coral; } h1 { color: var(--black, crimson); } ``` ![深紅色文字“說話,你很重要”](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2477mnixnrwtwn5mqun.png) ## 9. 改變書寫模式 您可以使用書寫模式屬性來指定文本在您的網站上的佈局方式,即垂直或水平。 ``` <h1>Cakes & Bakes</h1> ``` ``` /* 💡 specifies the text layout direction to sideways-lr */ h1 { writing-mode: sideways-lr; } ``` ![文本開始於](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ozqs02sh7edl70cd609a.png) ## 10.彩虹動畫 為元素建立連續循環的彩色動畫以吸引用戶注意力。閱讀 [css 提示技巧](https://github.com/devsyedmohsin/css-tips-tricks#rainbow-animation) 存儲庫以了解何時使用“prefer-reduced-motion”媒體功能 ``` button{ animation: rainbow-animation 200ms linear infinite; } @keyframes rainbow-animation { to{ filter: hue-rotate(0deg); } from{ filter: hue-rotate(360deg); } } ``` ![立即購買按鈕不斷改變顏色](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60jgrr09vgsckx9h2irl.gif) ## 11.掌握Web開發 訂閱我們的 [YouTube 頻道](https://www.youtube.com/@nisarhassan12),讓您的網絡開發技能更上一層樓。 [最近的視頻系列](https://www.youtube.com/watch?v=1nchVfpMGSg&list=PLwJBGAxcH7GzdavgKlCACbESzr-40lw3L) 之一介紹了建立以下開源[投資組合模板](https://github.com/nisarhassan12 /投資組合模板)。 ![伊蒙](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bxid827qfq1ybx2tl3q7.gif) ## 12. 懸停時縮放 ``` /* 📷 Define the height and width of the image container & hide overflow */ .img-container { height: 250px; width: 250px; overflow: hidden; } /* 🖼️ Make the image inside the container fill the container */ .img-container img { height: 100%; width: 100%; object-fit: cover; transition: transform 200m ease-in; } img:hover{ transform: scale(1.2); } ``` ![躺在灰色瓷磚上的深紅色購物袋](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cxy8ymu937e0kf14wwbc.gif) ## 13.屬性選擇器 使用屬性選擇器根據屬性選擇 HTML 元素。 ``` <a href="">HTML</a> <a>CSS</a> <a href="">JavaScript</a> ``` ``` /* 🔗 targets all a elements that have a href attribute */ a[href] { color: crimson; } ``` ![HTML CSS JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1sq2rhs58a01ayfqzexk.png) ## 14. 裁剪元素 使用 `clip-path` 屬性建立有趣的視覺效果,例如將元素剪裁成三角形或六邊形等自定義形狀。 ``` div { height: 150px; width: 150px; background-color: crimson; clip-path: polygon(50% 0%, 0% 100%, 100% 100%); } ``` ![三角形](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u9eqxif34ndhq33xvlpb.png) ## 15.檢測屬性支持 使用 CSS `@support 規則` 直接在您的 CSS 中檢測對 CSS 特性的支持。查看 [css 提示技巧](https://github.com/devsyedmohsin/css-tips-tricks#check-if-property-is-supported) 存儲庫以了解有關功能查詢的更多訊息。 ``` @supports (accent-color: #74992e) { /* code that will run if the property is supported */ blockquote { color: crimson; } } ``` ![永遠不要食言。(Hazrat Ali A.S)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ekr2fmhl4ori47xqgyf.png) ## 16. CSS 嵌套 CSS 工作組一直在研究如何向 CSS 加入嵌套。通過嵌套,您將能夠編寫更直觀、更有條理和更高效的 CSS。 ``` <header class="header"> <p class="text">Lorem ipsum, dolor</p> </header> ``` ``` /* 🎉 You can try CSS nesting now in Safari Technology Preview*/ .header{ background-color: salmon; .text{ font-size: 18px; } } ``` ## 17.箝制函數 使用 `clamp()` 函數實現響應式和流暢的排版。 ``` /* Syntax: clamp(minimum, preferred, maximum) */ h1{ font-size: clamp(2.25rem,6vw,4rem); } ``` ![gif 字體大小根據屏幕大小改變](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/upaf9jdlfapezzmufyaa.gif) ## 18. 樣式化可選字段 你可以使用 `:optional` 偽類來設置表單字段的樣式,例如 input、select 和 textarea,這些字段沒有 required 屬性。 ``` /* Selects all optional form fields on the page */ *:optional{ background-color: green; } ``` ## 19. 字間距屬性 使用 `word-spacing` 屬性指定單詞之間的空格長度。 ``` p { word-spacing: 1.245rem; } ``` ## 20. 建立漸變陰影 這就是您如何建立漸變陰影以獲得獨特的用戶體驗。 ``` :root{ --gradient: linear-gradient(to bottom right, crimson, coral); } div { height: 200px; width: 200px; background-image: var(--gradient); border-radius: 1rem; position: relative; } div::after { content: ""; position: absolute; inset: 0; background-image: var(--gradient); border-radius: inherit; filter: blur(25px) brightness(1.5); transform: translateY(15%) scale(0.95); z-index: -1; } ``` ![帶有漸變陰影的框](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7korhhx7zaj350nfzmyb.png) ## 21. 改變標題位置 使用 `caption-side` 屬性將表格標題(表格標題)放置在表格的指定一側。 ![從上到下更改表格標題側](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7t44rugi8gx3ksndq560.gif) ## 22. 建立文本列 使用列屬性為文本元素製作漂亮的列佈局。 ``` /* 🏛️ divide the content of the "p" element into 3 columns */ p{ column-count: 3; column-gap: 4.45rem; column-rule: 2px dotted crimson; } ``` ![css 提示和技巧詩](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1ryft9s27y56el3ljx4.png) --- 以上分享,希望對您有幫助!

軟體開發者推薦使用:50 個好用的 CLI 指令工具

作為開發人員,我們在終端機上花費了大量時間。有很多有用的 CLI 工具,它們可以讓您在命令行中的生活更輕鬆、更快速,而且通常更有趣。 這篇文章概述了 50 個必備的好用 CLI 工具。 原文出處:https://dev.to/lissy93/cli-tools-you-cant-live-without-57f6 --- ## 工具 ### [`thefuck`](https://github.com/nvbn/thefuck) - 自動更正錯誤輸入的命令 > `thefuck` 是您一旦嘗試過就離不開的實用程式之一。每當您輸入錯誤的命令並出現錯誤時,只需執行 `fuck`,它就會自動更正它。使用向上/向下選擇一個更正,或者只執行 `fuck --yeah` 立即執行最有可能的。 ![他媽的示例用法](https://i.ibb.co/J55hWKX/thefuck.gif) --- ### [`zoxide`](https://github.com/ajeetdsouza/zoxide) - 輕鬆導航 _(更好的 cd)_ > `z` 讓您可以跳轉到任何目錄,而無需記住或指定其完整路徑。它會記住您存取過的目錄,因此您可以快速跳轉——您甚至不需要鍵入完整的文件夾名稱。它還具有互動式選項,使用“fzf”,因此您可以即時過濾目錄結果 ![zoxide-example-usage](https://i.ibb.co/6Z960jq/zoxide.gif) --- ### [`tldr`](https://github.com/tldr-pages/tldr) - 社區維護的文件 _(更好的 `man`)_ > `tldr` 是社區維護的手冊頁的巨大集合。與傳統的手冊頁不同,它們進行了總結,包含有用的用法範例,並且配色良好,便於閱讀 ![tldr-example-usage](https://i.ibb.co/jTW9knx/tlfr.gif) --- ### [`scc`](https://github.com/boyter/scc) - 計算程式碼行數_(更好的`cloc`)_ > `scc` 為您提供了針對特定目錄以每種語言編寫的程式碼行數的細分。它還顯示了一些有趣的統計資料,例如估計的開發成本和復雜性訊息。它的速度非常快,非常準確,並且支持多種語言 ![scc-example-usage](https://i.ibb.co/NygHWXt/scc.png) --- ### [`exa`](https://github.com/ogham/exa) - 列出文件 _(更好的 `ls`)_ > `exa` 是基於 Rust 的現代替代 `ls` 命令,用於列出文件。它可以顯示文件類型圖標、顏色、文件/文件夾訊息,並有多種輸出格式——樹、網格或列表 ![exa-example-usage](https://i.ibb.co/cTs0wQ5/exa.png) --- ### [`duf`](https://github.com/muesli/duf) - 硬碟使用量 _(更好的 `df`)_ > `duf` 非常適合顯示有關已安裝硬碟的訊息和檢查可用空間。它產生清晰多彩的輸出,並包括用於排序和自定義結果的選項。 ![duf-示例用法](https://i.ibb.co/sP59DKd/duf.png) --- ### [`aria2`](https://github.com/aria2/aria2) - 下載實用程式 _(更好的 `wget`)_ > `aria2` 是一種輕量級、多協議、用於 HTTP/HTTPS、FTP、SFTP、BitTorrent 和 Metalink 的恢復下載實用程序,支持通過 RPC 接口進行控制。它的[功能豐富](https://aria2.github.io/manual/en/html/README.html)令人難以置信,並且有大量的[選項](https://aria2.github.io/manual/en/ html/aria2c.html)。還有 [ziahamza/webui-aria2](https://github.com/ziahamza/webui-aria2) - 一個不錯的網路介面搭配。 ![aria2c-example-usage](https://i.ibb.co/pJkkX6x/aria2c.png) --- ### [`bat`](https://github.com/sharkdp/bat) - 讀取文件_(更好的`cat`)_ > `bat` 是 `cat` 的複製品,但具有語法高亮顯示和 git 集成。它是用 Rust 編寫的,性能非常好,並且有多個用於自定義輸出和主題的選項。支持自動管道和文件連接 ![bat-example-usage](https://i.ibb.co/VND3Y9s/bat.png) --- ### [`diff-so-fancy`](https://github.com/so-fancy/diff-so-fancy) - 文件比較_(更好的`diff`)_ > `diff-so-fancy` 為比較字串、文件、目錄和 git 更改提供了更好看的差異。更改突出顯示使發現更改變得更加容易,並且您可以自定義輸出佈局和顏色 ![diff-so-fancy-example-usage](https://i.ibb.co/RGKLhQk/diff-so-fancy.png) --- ### [`entr`](https://github.com/eradman/entr) - 觀察變化 > `entr` 允許您在文件更改時執行任意命令。您可以傳遞一個文件、目錄、符號連結或正則表達式來指定它應該監視哪些文件。它對於自動重建專案、響應日誌、自動化測試等非常有用。與類似專案不同,它使用 kqueue(2) 或 inotify(7) 來避免輪詢,並提高性能 ![entr-example-usage](https://i.ibb.co/HHKQx2H/entr.png) --- ### [`exiftool`](https://github.com/exiftool/exiftool) - 讀取+寫入元資料 > ExifTool 是一個方便的實用程序,用於讀取、寫入、剝離和建立各種文件類型的元訊息。再次分享照片時不要不小心洩露您的位置! ![exiftool-example-usage](https://i.ibb.co/Gv5PN6v/exiftool.png) --- ### [`fdupes`](https://github.com/jbruchon/jdupes) - 重複文件查找器 > `jdupes` 用於辨識和/或刪除指定目錄中的重複文件。當您有兩個或更多相同的文件時,它對於釋放硬碟空間很有用 ![fdupes-example-usage](https://i.ibb.co/jhSY2Nn/fdupes.png) --- ### [`fzf`](https://github.com/junegunn/fzf) - 模糊文件查找器_(更好的`find`)_ > `fzf` 是一個非常強大且易於使用的模糊文件查找器和過濾工具。它允許您跨文件搜尋字串或模式。 fzf 也有可用於大多數 shell 和 IDE 的[插件](https://github.com/junegunn/fzf/wiki/Related-projects),用於在搜尋時顯示即時結果。這篇由 Alexey Samoshkin 撰寫的 [文章](https://www.freecodecamp.org/news/fzf-a-command-line-fuzzy-finder-missing-demo-a7de312403ff/) 重點介紹了它的一些用例。 ![fzf-示例用法](https://i.ibb.co/LNcwjWm/fzf.gif) --- ### [`hyperfine`](https://github.com/sharkdp/hyperfine) - 命令基準測試 > `hyperfine` 可以輕鬆準確地對任意命令或腳本進行基準測試和比較。它負責預熱執行、清除緩存以獲得準確的結果並防止來自其他程序的干擾。它還可以將結果導出為原始資料並生成圖表。 ![hyperfine-example-usage](https://i.ibb.co/tKNR5gr/hyperfine.png) --- ### [`just`](https://github.com/casey/just) - 現代命令執行器_(更好的`make`)_ > `just` 與 `make` 類似,但增加了一些不錯的功能。它讓您可以將專案命令分組到副本中,這些副本可以輕鬆列出和執行。支持別名、位置參數、不同的 shell、dot env 集成、字串插入以及幾乎所有您可能需要的東西 --- ### [`jq`](https://github.com/stedolan/jq) - JSON 處理器 > `jq` 類似於 `sed`,但對於 JSON - 您可以使用它輕鬆地切片、過濾、映射和轉換結構化資料。它可用於編寫複雜的查詢以提取或操作 JSON 資料。還有一個 [jq playground](https://jqplay.org/),您可以用來試用,或通過即時回饋制定查詢 --- ### [`most`](https://www.jedsoft.org/most/) - 多窗口滾動尋呼機_(更好的 less)_ > `most` 是一個尋呼機,用於讀取長文件或命令輸出。 `most` 支持多窗口並且可以選擇不換行 --- ### [`procs`](https://github.com/dalance/procs) - 進程查看器_(更好的 ps)_ > `procs` 是一個易於導航的流程查看器,它具有彩色突出顯示,使流程的排序和搜尋變得容易,具有樹視圖和實時更新 ![procs-example-usage](https://i.ibb.co/y6qhgDX/procs-demo.gif) --- ### [`rip`](https://github.com/nivekuil/rip) - 刪除工具_(更好的 rm)_ > `rip` 是一種安全、符合人體工程學且高性能的刪除工具。它讓您直觀地刪除文件和目錄,並輕鬆恢復已刪除的文件 ![rip-example-usage](https://i.ibb.co/10DTvT2/rip.gif) --- ### [`ripgrep`](https://github.com/BurntSushi/ripgrep) - 在文件中搜尋 _(更好的 `grep`)_ > `ripgrep` 是一種面向行的搜尋工具,可遞歸地在當前目錄中搜尋正則表達式模式。它可以忽略 .gitignore 的內容並跳過二進製文件。它能夠在壓縮檔案中搜尋,或只搜尋特定的擴展名,並使用各種編碼方法理解文件 ![ripgrep-example-usage](https://i.ibb.co/qkMgQm9/ripgrep.png) --- ### [`rsync`](https://rsync.samba.org/) - 快速、增量文件傳輸 > `rsync` 讓您可以在本地複制大文件,或將大文件複製到遠程主機或外部驅動器或從遠程主機或外部驅動器複製。它可用於保持多個位置的文件同步,非常適合建立、更新和恢復備份 --- ### [`sd`](https://github.com/chmln/sd) - 查找並替換_(更好的`sed`)_ > `sd` 是一種簡單、快速且直觀的查找和替換工具,基於字串文字。它可以在文件、整個目錄或任何管道文本上執行 ![sd-示例用法](https://i.ibb.co/G9CfcGS/sd.png) --- ### [`tre`](https://github.com/dduan/tre) - 目錄層次結構_(更好的`tree`)_ > `tre` 輸出當前目錄或指定目錄的樹形文件列表,並帶有顏色。使用“-e”選項執行時,它會為每個專案編號,並建立一個臨時別名,您可以使用該別名快速跳轉到該位置 ![tre-example-usage](https://i.ibb.co/CmMrZLB/tre.png) --- ### [`xsel`](https://github.com/kfish/xsel) - 存取剪貼板 > `xsel` 讓您通過命令行讀取和寫入 X 選擇剪貼板。它對於將命令輸出通過管道傳輸到剪貼板或將復制的資料傳輸到命令中很有用 --- ## CLI 監控和性能應用程式 ### [`bandwhich`](https://github.com/imsnif/bandwhich) - 頻寬利用率監視器 > 即時顯示頻寬使用情況、連接訊息、傳出主機和 DNS 查詢 ![bandwhich-example-usage](https://i.ibb.co/8jHHBD3/Screenshot-from-2023-01-18-22-45-32.png) --- ### [`ctop`](https://github.com/bcicen/ctop) - 容器指標和監控 > 類似於 `top`,但用於監控正在執行的(Docker 和 runC)容器的資源使用情況。它顯示實時 CPU、內存和網絡帶寬以及每個容器的名稱、狀態和 ID。還有一個內置的日誌查看器和管理(停止、啟動、執行等)容器的選項 ![ctop-example-usage](https://i.ibb.co/xGjyzZ2/ctop.gif) --- ### [`bpytop`](https://github.com/aristocratos/bpytop) - 資源監控_(更好的`htop`)_ > `bpytop` 是一種快速、交互式、可視化的資源監視器。它顯示了最熱門的執行進程、最近的 CPU、內存、磁盤和網絡歷史記錄。您可以從界面中導航、排序和搜尋——還支持自定義顏色主題 ![bpytop-example-usage](https://i.ibb.co/nj9jrhr/bpytop.gif) --- ### [`glances`](https://github.com/nicolargo/glances) - 資源監視器 + 網絡和 API > `glances` 是另一個資源監視器,但具有不同的功能集。它包括一個完全響應的 Web 視圖、一個 REST API 和歷史監控。它易於擴展,並且可以與其他服務集成 ![掃視示例用法](https://i.ibb.co/6g65Qy4/glances.gif) --- ### [`gping`](https://github.com/orf/gping) - 交互式 ping 工具 _(更好的 `ping`)_ > `gping` 可以在多個主機上執行 ping 測試,同時以實時圖形顯示結果。當與 --cmd 標誌一起使用時,它還可以用於監視執行時間 ![gping 示例用法](https://i.ibb.co/CvG6xt0/gping.gif) --- ### [`dua-cli`](https://github.com/Byron/dua-cli) - 磁盤使用分析器和監視器 _(更好的 `du`)_ > `dua-cli` 讓您以交互方式查看每個已安裝驅動器的已用和可用磁盤空間,並輕鬆釋放存儲空間 ![dua-cli-usage-example](https://i.ibb.co/x3NbDLR/dua.gif) --- ### [`speedtest-cli`](https://github.com/sivel/speedtest-cli) - 命令行速度測試實用程序 > `speedtest-cli` 只是執行網路速度測試,通過 speedtest.net - 但直接從終端 :) ![speedtest-cli-example-usage](https://i.ibb.co/25QCbdF/speedtest-cli.gif) --- ### [`dog`](https://github.com/ogham/dog) - DNS 查找客戶端_(更好的`dig`)_ > `dog` 是一個易於使用的 DNS 查找客戶端,支持 DoT 和 DoH,漂亮的彩色輸出和發出 JSON 的選項 ![dog-example-usage](https://i.ibb.co/48n617Q/dog.png) --- ## CLI 生產力應用程式 > 上網衝浪、播放音樂、查看電子郵件、管理日曆、閱讀新聞等等,無需離開終端! ### [`browsh`](https://github.com/browsh-org/browsh) - CLI 網路瀏覽器 > `browsh` 是一個完全交互的、實時的、現代的基於文本的瀏覽器,呈現給 TTY 和瀏覽器。它同時支持鼠標和鍵盤導航,並且對於純基於終端的應用程式來說功能豐富得令人吃驚。它還緩解了困擾現代瀏覽器的電池耗盡問題,並且通過對 MoSH 的支持,由於帶寬減少,您可以體驗更快的加載時間 ![browsh-example-usage](https://i.ibb.co/S7nLFX5/browsh.gif) --- ### [`books`](https://github.com/jarun/books) - 書籤管理器 > `buku` 是一個基於終端的書籤管理器,具有大量的配置、存儲和使用選項。還有一個可選的 [web UI](https://github.com/jarun/buku/tree/master/bukuserver#screenshots) 和 [瀏覽器插件](https://github.com/samhh/bukubrow-webext#installation ), 用於在終端外存取您的書籤 ![buku-example-usage](https://i.ibb.co/CWQsf1x/buku.png) --- ### [`cmus`](https://github.com/cmus/cmus) - 音樂瀏覽器/播放器 > `cmus` 是終端音樂播放器,由鍵盤快捷鍵控制。它支持廣泛的音頻格式和編解碼器,並允許將曲目組織到播放列表中並應用播放設置 ![cmus-example-usage](https://i.ibb.co/dP6b3bd/cmus.png) --- ### [`cointop`](https://github.com/cointop-sh/cointop) - 跟踪加密價格 > `cointop` 顯示當前的加密貨幣價格,並跟踪您的投資組合的價格歷史。支持價格提醒、歷史圖表、貨幣換算、模糊搜尋等。您可以通過網絡 [cointop.sh](https://cointop.sh/) 或執行 `ssh cointop.sh` 來嘗試演示 ![cointop-example-usage](https://i.ibb.co/JBf9y4y/cointop.png) --- ### [`ddgr`](https://github.com/jarun/ddgr) - 從終端搜尋網頁 > `ddgr` 類似於 [googler](https://github.com/jarun/googler),但適用於 DuckDuckGo。它快速、乾淨、簡單,支持即時回答、搜尋完成、搜尋 bangs 和高級搜尋。它默認尊重您的隱私,也有 HTTPS 代理支持,並與 Tor 一起工作 ![dggr-example-usage](https://i.ibb.co/S0H21QH/dggr.png) --- ### [`micro`](https://github.com/zyedidia/micro) - 程式碼編輯器_(更好的`nano`)_ > `micro` 是一款易於使用、快速且可擴展的程式碼編輯器,支持鼠標。由於它被打包成一個二進製文件,安裝就像`curl https://getmic.ro | 安裝一樣簡單。慶典` --- ### [`khal`](https://github.com/pimutils/khal) - 日曆客戶端 > `khal` 是一個終端日曆應用程式,它顯示即將發生的事件、月份和議程視圖。您可以將它與任何 CalDAV 日曆同步,並直接加入、編輯和刪除事件 ![khal-example-usage](https://i.ibb.co/hLCdjZW/khal.png) --- ### [`mutt`](https://gitlab.com/muttmua/mutt) - 電子郵件客戶端 > `mut` 是一個經典的、基於終端的郵件客戶端,用於發送、閱讀和管理電子郵件。它支持所有主流電子郵件協議和郵箱格式,允許附件、密件抄送/抄送、線程、郵件列表和傳遞狀態通知 ![mutt-example-usage](https://i.ibb.co/zVVsG3s/mutt.webp) --- ### [`newsboat`](https://github.com/newsboat/newsboat) - RSS / ATOM 新聞閱讀器 > `newsboat` 是一個 RSS 提要閱讀器和聚合器,用於直接從終端閱讀新聞、博客和後續更新 ![newsboat-example-usage](https://i.ibb.co/fvT4YzD/newsboat.png) --- ### [`rclone`](https://github.com/rclone/rclone) - 管理雲存儲 > `rclone` 是一個方便的實用程序,用於將文件和文件夾同步到各種雲存儲提供商。它可以直接從命令行呼叫,也可以輕鬆集成到腳本中以替代繁重的桌面同步應用程式 --- ### [`taskwarrior`](https://github.com/GothenburgBitFactory/taskwarrior) - Todo + 任務管理 > `task` 是一個 CLI 任務管理/待辦事項應用程式。它既簡單又不引人注目,但也非常強大和可擴展,內置高級組織和查詢功能。還有很多(700+!)額外的[插件](https://taskwarrior.org/tools/) 用於擴展它的功能和與第三方服務的集成 ![任務戰士示例用法](https://i.ibb.co/7k6M37g/taskwarrior.jpg) --- ### [`tuir`](https://gitlab.com/ajak/tuir) - Reddit 的終端用戶界面 > `tuir` 是一個很好的選擇,如果你想看起來像在工作,同時實際瀏覽 Reddit!它具有直觀的鍵綁定、自定義主題,還可以呈現圖像和多媒體內容。還有 [haxor](https://github.com/donnemartin/haxor-news) 用於黑客新聞 ![tuir-example-usage](https://i.ibb.co/vzSw7s5/tuir.png) --- ## CLI 開發套件 ### [`httpie`](https://github.com/httpie/httpie) - HTTP/API測試測試客戶端 > `httpie` 是一個 HTTP 客戶端,用於測試、除錯和使用 API。它支持您所期望的一切——HTTPS、代理、身份驗證、自定義標頭、持久會話、JSON 解析。具有表達語法和彩色輸出的用法很簡單。與其他 HTTP 客戶端(Postman、Hopscotch、Insomnia 等)一樣,HTTPie 也包含一個 Web UI ![httpie-示例用法](https://i.ibb.co/Wk5S19g/httpie.png) --- ### [`lazydocker`](https://github.com/jesseduffield/lazydocker) - 完整的 Docker 管理應用程式 > `lazydocker` 是一個 Docker 管理應用程式,可讓您查看所有容器和圖像、管理它們的狀態、讀取日誌、檢查資源使用情況、重新啟動/重建、分析層、修剪未使用的容器、圖像和卷等等。它使您無需記住、鍵入和連結多個 Docker 命令。 ![lazy-docker-example-usage](https://i.ibb.co/MD8MWNH/lazydocker.png) --- ### [`lazygit`](https://github.com/jesseduffield/lazygit) - 完整的 Git 管理應用程式 > `lazygit` 是一個可視化的 git 客戶端,在命令行上。輕鬆加入、提交和推送文件、解決衝突、比較差異、管理日誌以及執行壓縮和倒帶等複雜操作。一切都有鍵綁定,顏色,而且很容易配置和擴展 ![lazy-git-example-usage](https://i.ibb.co/KLF3C6s/lazygit.png) --- ### [`kdash`](https://github.com/kdash-rs/kdash/) - Kubernetes 儀表板應用程式 > `kdash` 是一個一體化的 Kubernetes 管理工具。查看節點指標、觀察資源、流容器日誌、分析上下文和管理節點、pod 和命名空間 --- ### [`gdp-dashboard`](https://github.com/cyrus-and/gdb-dashboard) - 可視化 GDP 除錯器 > `gdp-dashboard` 向 GNU 除錯器加入了一個可視元素,用於除錯 C 和 C++ 程序。輕鬆分析內存、單步執行斷點和查看寄存器 ![gdp-dashboard-example-usage](https://i.ibb.co/2g2hVLh/gdp-dashboard.png) --- ## CLI 外部服務 ### [`ngrok`](https://ngrok.com/) - 共享本地主機的反向代理 > `ngrok` 安全* 將您的本地主機暴露在唯一 URL 後面的網路上。這使您可以與遠程同事實時共享您的工作。使用[非常簡單](https://notes.aliciasykes.com/p/RUi22QSyWe),但它也有很多高級功能,例如身份驗證、webhooks、防火牆、流量檢查、自定義/通配符域等等 ![ngrok-示例用法](https://i.ibb.co/4WPZNGx/ngrok.png) --- ### [`tmate`](https://tmate.io/) - 通過網路共享終端會話 > `tmate` 讓您立即與世界其他地方的人分享實時終端會話。跨系統工作,支持存取控制/授權,可自託管,具備Tmux的所有特性 --- ### [`asciinema`](https://asciinema.org/) - 錄製+分享終端會話 > `asciinema` 對於輕鬆記錄、共享和嵌入終端會話非常有用。非常適合展示您建置的內容,或展示教程的命令行步驟。與屏幕錄製視頻不同,用戶可以復制粘貼內容、動態更改主題和控製播放 --- ### [`navi`](https://github.com/denisidoro/navi) - 交互式備忘單 > `navi` 允許您瀏覽備忘單並執行命令。參數的建議值動態顯示在列表中。減少輸入,減少錯誤,讓自己不必記住數千條命令。它集成了 [tldr](https://github.com/tldr-pages/tldr) 和 [cheat.sh](https://github.com/chubin/cheat.sh) 以獲取內容,但您也可以導入其他備忘單,甚至編寫自己的備忘單 --- ### [`transfer.sh`](https://github.com/dutchcoders/transfer.sh/) - 快速文件共享 > `transfer` 使上傳和共享文件變得非常簡單,直接從命令行即可。它是免費的,支持加密,為您提供唯一的 URL,也可以自行託管。 > 我寫了一個 Bash 輔助函數來讓使用更容易一些,你可以[在這裡找到它](https://github.com/Lissy93/dotfiles/blob/master/utils/transfer.sh) 或嘗試一下通過執行`bash <(curl -L -s https://alicia.url.lol/transfer)` ![transfer-sh-example-usage](https://i.ibb.co/cCqDb1k/transfer-sh.png) --- ### [`surge`](https://surge.sh/) - 在幾秒鐘內部署一個站點 > `surge` 是一個免費的靜態託管服務提供商,您可以通過一個命令直接從終端部署到它,只需在您的 `dist` 目錄中執行 `surge`!它支持自定義域、自動 SSL 憑證、pushState 支持、跨域資源支持——而且是免費的! ![surge-sh-example-usage](https://i.ibb.co/NynprxZ/surge-sh.png) --- ### [`wttr.in`](https://github.com/chubin/wttr.in) - 查看天氣 > `wttr.in` 是一項以命令行中易於理解的格式顯示天氣的服務。只需執行“curl wttr.in”或“curl wttr.in/London”來嘗試一下。有 URL 參數來自定義返回的資料以及格式 ![wrrt-in-example-usage](https://i.ibb.co/J2JWnYT/Screenshot-from-2023-01-18-21-10-54.png) --- ## CLI 樂趣 ### [`cowsay`](https://en.wikipedia.org/wiki/Cowsay) - 讓 ASCII 牛說出你的訊息 > `cowsay` 是一個可配置的會說話的奶牛。它基於 Tony Monroe 的[原創](https://github.com/tnalpgge/rank-amateur-cowsay) ![cowsay-example-usage](https://i.ibb.co/TRqW3jD/cowsay.png) --- ### [`figlet`](http://www.figlet.org/) - 將文本輸出為大型 ASCII 藝術文本 > `figlet` 將文本輸出為 ASCII 藝術 ![figlet-example-usage](https://i.ibb.co/fk4T7D0/figlet.png) --- ### [`lolcat`](https://github.com/busyloop/lolcat) - 使控制台輸出彩虹色 > `lolcat` 使任何傳遞給它的文本變成彩虹色 ![lolcat-example-usage](https://i.ibb.co/nfp9Ycx/lolcat.png) --- ### [`neofetch`](https://github.com/dylanaraps/neofetch) - 顯示系統資料和 ditstro 訊息 > `neofetch` 打印發行版和系統訊息(這樣你就可以靈活地在 r/unixporn 上使用 Arch btw) ![neofetch-example-usage](https://i.ibb.co/x1PHpFC/Screenshot-from-2023-01-18-22-44-28.png) 例如,我使用 `cowsay`、`figlet`、`lolcat` 和 `neofetch` 來建立一個自定義的基於時間的 MOTD,在用戶首次登錄時顯示給他們。它以他們的名字問候他們,顯示伺服器訊息和時間、日期、天氣和 IP。 [這裡是源程式碼](https://github.com/Lissy93/dotfiles/blob/master/utils/welcome-banner.sh)。 ![歡迎](https://i.ibb.co/cTg0jyn/Screenshot-from-2023-01-18-22-59-28.png) --- ## 安裝和管理 我們大多數人都有一套核心的 CLI 應用程式和我們所依賴的實用程序。設置一台新機器並單獨安裝每個程序很快就會讓人厭煩。因此,安裝和更新終端應用程式的任務非常適合自動化。 [此處](https://github.com/Lissy93/dotfiles/tree/master/scripts/installs) 是我編寫的一些示例腳本,可以輕鬆將其放入您的點文件或獨立執行以確保您永遠不會錯過一個應用程式。 對於 MacOS 用戶,最簡單的方法是使用 [Homebrew](https://brew.sh/)。只需建立一個 Brewfile(使用 `touch ~/.Brewfile`),然後列出您的每個應用程式,然後執行 `brew bundle`。您可以通過將其放入 Git 存儲庫來備份您的包列表。這是一個示例,讓您入門:https://github.com/Lissy93/Brewfile 在 Linux 上,您通常希望使用本機包管理器(例如 `pacman`、`apt`)。例如,[這裡有一個腳本](https://github.com/Lissy93/dotfiles/blob/master/scripts/installs/arch-pacman.sh) 用於在 Arch Linux 系統上安裝上述應用程式 Linux 上的桌面應用程式可以通過 Flatpak 以類似的方式進行管理。同樣,[這是一個示例腳本](https://github.com/Lissy93/dotfiles/blob/master/scripts/installs/flatpak.sh) :) --- ## 結論 ...就是這樣 - 一個方便的 CLI 應用程式列表,以及一種在您的系統中安裝和保持它們最新的方法。 希望其中一些對你們中的一些人有用:)

此篇閒聊-關於這個網站以及關於站長(+此站使用心得

因為我有個點子是搞一個梗圖的網站 就想說上網先看看人家怎麼弄的 看著就到了梗圖倉庫 欸 突然眼熟的看到站長阿川!? 稍微確認一下才知道是我們的站長 挖真的是偶像啊0.0 早我好幾百年就已經弄得票漂亮亮有聲有色  我還在那邊1+1咧 哭暈在廁所 難怪自我介紹說有經驗 相關問題都能回答 這豈止是回答 是模範 是偶像欸(跪了 是說站長人格方面可能才是我最欽佩的  為人善良熱情  低調謙虛 沒有把自己的行頭  作品都丟上來搞一個自我經歷很豐富這樣的介紹  真的很低調欸 小弟個人覺得這真的是各位學習的典範 這邊不知道會不會不太好 推薦這篇 [工程師的缺德行為:叫朋友去學C/C++](https://blog.turn.tw/?p=2568) 太中肯啦 最屌的一句話 我真心覺得屌 非吹捧 是「別擔心,這不是你的錯,是那些書寫得不夠好」 說實話要說那些書很爛嗎 也沒有 但說真的 真的不夠好 其實現在的網路課程 線上教學也是有同樣的問題 課程編排都很死 講老半天的閉包 hoisting 那些東西 不是說這些不重要 要面試 要工作恐怕那是最基本的 可是我身為一個愛好者 我沒看見那些觀念真的被套用&應用在實際狀況 舉例來說我學變數的觀念 是經由RPG製作大師 要修復做寶箱會無限開的bug 因此設定一個變數是off 打開是on 然後用if條件式去判斷 我一次學會好多東西 第一個我懂了變數 我知道需要記憶體幫我存資料 第二資料型態 Boolean 就是on跟off兩種 然後我也學會流程判斷 也就是if x=off then....這樣子 後來用CE修改器發現要找血量 是小數點 所以搜尋要用浮點數(float) 再來是玩VB要寫自動發話所以瞭解了迴圈 並知道要寫一個函式 再去call它 多麼精彩啊這些片段!每一個細節我都忘不了!全部都是畫面!全部都很有趣! 以此類推 講真的到現在 每一個語法都是我靠著自己實踐 找出來的 雖然這樣子花了十來幾年 程度還很弱 但我敢說這樣子的內容有趣 甚至我也敢說 這樣才有意義 我至今到現在常常看網路教學影片 還是一堆講課講老半天都是程式的語法 沒有實戰也就算了 先理解語法 但講解的都很生硬 完完全全都只是為了講課而解釋&示範 真正要實戰了的話也都玩那幾招 沒有變化 明明這個網路世界 程式世界是如此的繽紛 到了他們教學的手上 真的是變黑白 也難怪需要特別聰明跟有天分的人才能駕馭 因為教學資源的傾向就是科板書的教法 當然要足夠聰明 而不是有熱誠 純有熱誠也要能像我這樣十來年慢慢去搞 錯誤了沒地方搞懂 再等好幾年後發現問題 對我來說 我不是特別聰明 我一路走來也理解了 我的確偏笨 但打開書本或是課程 從VScode建置開始 慢慢開始介紹語言的歷史 我真的看不下去 無聊死了 我寧願花個十年 用我有趣的摸索去實戰 去玩 也不要聽課 對我來說 這些課不是爛 是真的不夠好 我用我的自學證明 有一套比他們的課程更生動活潑 更有愛的方法能學程式 至少對我自己來說永遠為真 嗯嗯 離題了 主要是在這個論壇 真的很棒 鼓勵大家也多多發文分享 大多數擁有聰明頭腦的人 或是自己熬過來的工程師 只會轉頭批評外行人蠢或笨 要不然就是酸 藏私 不回答你還講幹話說  這你就不懂  或是重複一次問題說  就把這個解決就好啦 優越感灌下去 見不得你好 甚至批評你是在搞東搞西 我真的遇到一個 我發問問A問題 結果有個嘴臭仔他不回答就算了 在那邊嘴說看我過去發文 過去問B過去問C 說我是搞東搞西沒屁用 叫我去系統性學 在那邊講跟我問題無關的屁話 系統性學要是能解決 我早就解決了== 要怎樣的系統 笑死 你說的系統才是系統喔 我只想知道我研究的領域 你要我系統去哪裡 真的超傻眼 雖然文長有點抒發心情 但收尾主要還是想說 這個網站的資源是不同於其他地方的 還有這個網站的站長也是很真心要提升台灣程式社群的 所以我們可以一起利用這個資源~一起好好努力~ 讓未來新加入的分子 可以看到有趣的例子、找到真的有用的問答文章~ 站長是個很熱心 很有才華想法的大家長 我認為難得的是也很善良與見解獨到 能體會我們這種熱愛程式的人的心 https://codelove.tw/@howtomakeaturn/post/VaGR3p 各位都應該去點個讚!!

自學網頁の嬰兒教材:JavaScript(三)作業分享

練習1 ── alert 示警元件 https://jsfiddle.net/birdie2019/4ur1c7xf/34/ 練習2 ── toast 吐司元件 https://jsfiddle.net/birdie2019/fmc6b8ht/49/ 研究了一下setTimeout()用法,經過自己的消化吸收寫成筆記記錄下來 分享筆記:https://hackmd.io/@birdie/SJisAlTcs 另外發現display無法做transition的效果,改用opacity 練習3 ── modal 互動視窗元件 https://jsfiddle.net/birdie2019/9p3zsthL/17/ 練習4 ── 表單驗證 https://jsfiddle.net/birdie2019/bdavsur4/91/ 練習5 ── collapse 折疊效果 https://jsfiddle.net/birdie2019/dkncrv03/43/ 認識了scrollHeight屬性,建議可以用圖去搜尋會比較好理解這個屬性 也順便學了clientHeight和offsetHeight 練習6 ── dropdown 下拉式選單 https://jsfiddle.net/birdie2019/xb0ka495/44/ 研究window.onclick怎麼使用並認識了matches() 練習7 ── carousel 輪播元件 https://jsfiddle.net/birdie2019/t6uxb9df/30/ --- 此次教材心得分享: 一開始在腦袋裡會想很複雜,憑空亂想亂打code發現不是再刪掉再亂打,但其實不可能一下就到位,後來拿筆和紙先把需要的功能和自己的邏輯想法簡單的寫和畫下來,釐清自己現在需要怎麼做,方法有幾種,若這個方法不行,還可以用什麼方法可以做,這個方法看似很沒有效率,但真的對我幫助很大且完成此次所有作業。

CSS 基本觀念:rem 跟 em 差在哪?何時該用哪個?有何注意事項?

## 簡介 CSS 是任何網站設計的重要組成部分,但理解其中一些細微差別觀念可能不容易。其中最重要的觀念之一是 rem 和 em 之間的區別,以及為什麼/何時應該使用它們。 原文出處:https://dev.to/refine/rem-vs-em-everything-you-need-to-know-5342 --- ## 預備知識 本文希望讀者對 CSS 有紮實的掌握。雖然你不必成為 CSS 大神,但如果基本的 CSS 術語你都清楚,那會好讀很多。 ## CSS 中的 em 和 rem 單位 在尋找在 CSS 中設定長度的方法時,有太多方法了。 CSS 中指定長度的所有單位都屬於兩類。 絕對長度:顧名思義,就是絕對的;它們是固定的,不會對任何事物做出反應。這意味著無論發生什麼,它們的大小都是一樣的。絕對長度包括 cm、mm、in、px、pts 和 pc。 相對長度:是指定相對於另一個單位的長度的單位,即,它們根據其他指定單位或元素做出響應。包括 %、vmax、vmin、vh、vw、ch、ex,以及我們將要討論的單位 em 和 rem。 如果您想了解更多關於這些單位的訊息,可以現在先去查一查。現在讓我們看看這兩個單位。 ## 什麼是 CSS em 就像我上面說的,CSS 中的 em 單位是用於調整網頁元素大小的相對測量單位,主要是字體大小。因為是相對於父元素的,所以1em等於父元素中設置的font-size。 這意味著如果您將父 div 中的字體大小設置為 20px,並將子 div 中的字體大小設置為 2em,則子 div 中的字體大小將等於 40px。這是一個例子。 首先,讓我們編寫 HTML ``` <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="parent"> I'm parent div set to 20px <div class="child"> I'm the child div set to 2em, i.e 40px. </div> </div> </body> </html> ``` Next, the CSS. ``` .parent{ font-size: 20px; } .child{ font-size: 2em; } p { font-size: 1.5em; } ``` 那會給我們這個。 ![](https://refine.ams3.cdn.digitaloceanspaces.com/blog/2022-12-21-em-vs-rem/em-vs-rem-1.png) em 單位很有用,因為它允許您根據先前宣告的元素的字體大小調整頁面上元素的大小,這有助於建立一致的視覺層次結構。這對於建立易於視障用戶閱讀的可存取網站非常有用。 需要注意的是,如果不指定父元素的值,則以瀏覽器的預設值作為父元素。 ``` p { font-size: 1.5em; } ``` 在此範例中,字體大小屬性設置為 1.5em,這意味著如果沒有直接父元素,`<p>` 元素中的文本大小將是瀏覽器預設字體大小大小的 1.5 倍。 由於大多數瀏覽器根據螢幕大小縮放其預設字體大小,這使您可以建立靈活且響應迅速的佈局,以適應不同的螢幕和字體大小。 使用適當的 CSS 屬性,em 單位也可用於設置其他元素的大小,例如邊距、填充和邊框。 ## 什麼是 CSS rem 現在我們知道 em 是什麼,讓我們看看 rem。 rem 是 CSS 中另一個測量長度的單位,代表“root em”。由於我們知道一個 em 等於當前字體大小的數值,因此我們可以推斷出“根 em”指的是根元素的字體大小,通常是 `<html>` 元素。 很困惑嗎?讓我們進一步拆解它。 與 em 一樣,rem 從父元素繼承其大小,但 rem 查看的父元素不是它上面的 div 或部分,而是包圍它的第一個元素,即 html 元素。讓我們用前面的程式碼做一個例子。相同的 html 程式碼,只是多了一個 div。 ``` <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="parent"> I'm parent div set to 20px <div class="child"> I'm the child div set to 2em, i.e 40px. </div> <div class="child-2"> I'm the child div set to 2em, i.e 60px. </div> </div> </body> </html> ``` 接下來,我們將以下 CSS 程式碼加入到我們的 CSS 文件中。 ``` html{ font-size: 30px; } .child-2{ font-size: 2rem; } ``` 結果會是這樣。 ![Image em](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/njnny8zjwbk3157hece0.png) 如您所見,儘管 child-2 div 在另一個 div 中,但它會一直往上找到 html 元素以繼承其字體大小。 使用“rem”單位允許以更具可擴展性和靈活性的方式來調整頁面上的元素大小,因為如果您更改根元素的字體大小,所有使用“rem”單位調整大小的元素將自動更新以保持它們的相對大小尺寸。 ## em 和 rem 單位的區別 到目前為止,您已經知道 em 和 rem 之間的區別,但為了清楚起見,我想重申一下這兩個值之間的區別。 在 CSS 中,rem 單位僅相對於文檔的根元素,而 em 單位僅相對於目標元素的直接父元素。這意味著 em 大小繼承自父元素,而 rem 大小僅繼承自根元素。 ## 何時在 CSS 中使用 em 和 rem 單位 對字體大小、邊距和填充等全局值使用 rem 單位是一個好主意,特別是如果你想為整個文檔指定一個字體大小並讓它統一縮放而不是受字體影響父元素的大小。 em 更適合特定於特定元素及其子元素的值。這使您可以建立一致且靈活的佈局,以適應不同的螢幕尺寸和字體大小。 ## 在 CSS 中使用 em 和 rem 單位的潛在問題 em 和 rem 是目前指定長度時使用的最佳單位,但就像生活中的所有事物一樣,它們並不完美。以下是您在使用 em 和 rem 時可能會遇到的幾個問題: - **複雜的計算:**使用 em 和 rem 單位會導致複雜的計算,尤其是當涉及嵌套元素時。這會使準確預測和控制頁面上元素的大小變得困難。 - **繼承問題:** 因為 em 單位是相對於其父元素的字體大小的,所以很難理解和控制如何在頁面上繼承大小。這可能會導致意外結果,需要額外除錯才能解決。 - **性能問題:**在極少數情況下,使用 em 和 rem 單位會對性能產生負面影響,尤其是在與復雜計算結合使用或在頁面上過度使用時。 總的來說,雖然 em 和 rem 單位在某些情況下會有所幫助,但重要的是要仔細考慮它們的潛在缺點以及它們是否是您專案的最佳選擇。

給網站開發者:7 個值得在 2023 年用看看的免費工具

想要在 2023 年的 **Web 開發** 旅程中一帆風順嗎?參考看看這些免費工具吧! 原文出處:https://dev.to/ruppysuppy/7-free-tools-for-the-modern-web-developers-of-2023-4lhh ## 1. [Omatsuri](https://omatsuri.app/) 一個**開源 Web 應用程式**,有 **12 個令人難以置信的前端工具**,供日常開發使用。包含的工具有: 1. 三角形生成器 2. 顏色陰影生成器 3. 梯度產生器 4. 分頁器 5. SVG壓縮器 6. SVG → JSX 轉換器 7. base64編碼 8. 假資料生成器 9. 符號收錄 10. 假文字生成器 11. CSS 游標 12. 鍵盤事件程式碼 ![omatsuri](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ubhgroj9j4butoto73r.png) ## 2. [Coolers](https://coolors.co/) **Coolers** 是為您的網站生成 **調色板** 的最佳工具。 ![Coolers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q40qayjwocnseojux08a.png) ## 3. [Keyframes](https://keyframes.app/) 就跟名字一樣,它是: > 基於瀏覽器的、適合手機的、可以讓 **CSS** 變得不那麼糟糕的工具。 它有幾個工具,例如**動畫**、**陰影**和**顏色生成器**。 ![Keyframes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6f1h2a0caeb0yzx1hsg.png) ## 4. [Roadmap.sh](https://roadmap.sh/) **Roadmap**是一系列職涯路線圖,涵蓋了**前端**、**後端**、**區塊鏈**、**網路安全**等多個路徑。 他們也有**相關資源的連結**可供學習! ![Roadmap](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ppbw4ej1fvsbc8mzpjrr.png) ## 5. [FreeCodeCamp](https://www.freecodecamp.org/) **FreeCodeCamp** 是一個**非營利組織**,由**互動式學習網路平台**、**線上社群論壇**、**聊天室**、**線上出版物**、 **本地組織**組成,旨在讓任何人都可以學習 Web 開發。 ![FreeCodeCamp](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qh7mlh9jxlui5kq6755t.png) ## 6. [Postman](https://www.postman.com/) **Postman** 是一個用於建置和使用 **API** 的 **API 平台**。它是**後端工程師**工具庫中的必備工具,對**前端開發人員**也非常有用 ![Postman](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t2q0c4046o2rrux6534y.png) ## 7. [CSS Layout](https://csslayout.io/) 它是**數百個元件**的集合,您可以將其複製貼上到您的專案中,並根據您的需要進行客製化! ![css-layout](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/owuoadb9p06wqnvg7136.png) --- **以上供您參考!**

2023 前端框架比較:Svelte vs React,該學哪一個呢?

在 Web 開發世界中,有時感覺就像每天都有新的前端框架問世!大多數來去匆匆,但有一件事是肯定的:Svelte 將繼續存在。 不過,這並不意味著您應該放下一切並在今天學習!追逐最新潮流會讓您分心和不知所措。 這篇文章將一勞永逸地回答:**我應該學習 React 還是 Svelte?**。 您將看到一些程式碼範例,這些範例解釋了為什麼 React 開發人員會為 Svelte 瘋狂,但我們也必須實際一點。 React 已經存在了很長時間。有更多的套件、支援、職缺。 Svelte 還能取代 React 嗎?讓我們找出答案! - 原文出處:https://dev.to/mikehtmlallthethings/svelte-vs-react-which-framework-to-learn-in-2023-50gf --- * 📍 什麼是 React? * 📍 什麼是 Svelte? * 📍 React 和 Svelte 的 5 個區別 * Svelte 的捆綁包尺寸更小 * Svelte 更容易學習 * Svelte 使用純 HTML、CSS 和 JavaScript 進行編譯 * React 有更多的套件 * React 有 React Native * 📍 React 是庫還是框架? * 📍逐行比較 React 和 Svelte 專案 * 📍 Svelte 比 React 快嗎? * 📍 何時從 React 切換到 Svelte * 📍 結論 ### **What is React?** 讓我們從 React 開始。 React 是一個漸進式 JavaScript 前端框架(或函式庫,具體取決於您詢問的對象),可幫助您構建複雜的 Web UI。 它由 Facebook(現為 Meta)於 2013 年創建,能夠很快在前端 Web 開發領域站穩腳跟。 React 的核心是狀態和渲染狀態,這意味著要使用它,您必須添加其他庫來處理客戶端功能和路由。 ### **What is Svelte?** Svelte 也是一個前端 JavaScript 框架,但採用了更加一體化的方法。 Svelte 具有內建的狀態管理、路由和客戶端 (DOM) 功能。 ![](https://scrimba.com/articles/content/images/size/w1600/2022/12/React-vs-Svelte-functionalities.png) React 需要第三方庫和工具,如 Redux、React Router、JSX,而 Svelte 內建了很多這樣的功能。它不太靈活,但更方便和一致。 它採用更幕後(魔術)風格的方法,它直譯非常基本的 JavaScript 程式碼並為您處理 UI 和狀態管理: ``` <script> let count = 0; function handleClick() { count += 1; } </script> <button on:click={handleClick}> Clicked {count} {count === 1 ? 'time' : 'times'} </button> ``` Svelte 由紐約時報的開發人員 Rich Harris 於 2016 年創建,用於以高效的方式處理複雜的圖表和圖形。它從那裡成長為 React 和 Vue 之類的備受喜愛的競爭對手。 ### **React 和 Svelte 之間的 5 個區別** ### **1。 Svelte 的構建包大小要小得多** 我們在下面構建的相同(功能)應用程序。部署包大小在 React 是 41.2 kB,在 Svelte 是 2.1 kB。這幾乎減少了 **20x** 🤯 為了獲得這些數字,我構建了一個在 Svelte 和 React 中具有相同功能的應用程序。我們將在 React 與 Svelte 代碼分解部分深入研究這些應用程序。 ![](https://scrimba.com/articles/content/images/size/w1600/2022/12/React-vs-Svelte-bundle-size-2.png) 我用 React 和 Svelte 構建了一個相同的應用程序。看看 Svelte 包小了多少! ### **2。 Svelte 更容易學習,因為它的語法簡單** Svelte 採用更幕後的魔術方法,允許您編寫非常少量的樣板或語法糖來完成複雜的綁定。模板語法只是帶有一些額外內容的 HTML,這與 JSX(React 等價物)有很大不同並且更容易學習。 React 變數宣告: ![](https://scrimba.com/articles/content/images/size/w1600/2022/12/React-_-React-vs-svelte_-reactive-variable-declaration.png) Svelte 變數宣告: ![](https://scrimba.com/articles/content/images/size/w1600/2022/12/Svelte-_-React-vs-svelte_-reactive-variable-declaration.png) Svelte 看起來像純 JavaScript,但它具有與 React 完全相同的功能。更新 Svelte 變數將自動更新它所在的 UI 元素。 ### **3。 Svelte 符合純 HTML、CSS 和 JavaScript** Svelte 將您編寫的程式碼編譯成基本的 HTML、CSS 和 JavaScript。它不需要像 React 那樣與你的代碼捆綁在一起! React.js 需要存在於一個 bundle 中以完成所有正確的虛擬 DOM 比較和創建,Svelte 不使用虛擬 DOM 來處理 UI。相反,它選擇了基本的 JavaScript 元素創建函數,例如 document.createElement。 ### **4。 React 擁有更多為它構建的庫和包** React 已經存在了 3 年多,也是目前 JavaScript 框架事實上的王者👑。正因為如此,它擁有大量用戶和公司創建的軟件包。 用戶創建的包通常只是為了使路由和狀態管理更容易,或者添加滑塊、燈箱等。這些並不重要,因為 Svelte 具有可靠的選項,並且兼容/適應大多數 JavaScript 套件。 有點困難的是,要跟任何其他框架之前創建的 React 套件整合時不容易。我在 Solana 和以太坊上從事 Web3 專案時經常遇到這個問題。 ### **5。 React 有 React Native** React Native 是使用率最高和受支持最多的跨平台框架之一。它提供了使用 React 創建 iOS 和 Android 應用程式的能力。全部來自同一個代碼庫。由於其成熟度,它擁有大量的庫、支援和學習資源。 儘管有 Svelte 的替代方案,例如稱為 Svelte-native 的 NativeScript 改編版,但它們不具有與 React-native 相同的可靠性和功能。 ### **React 是函示庫還是框架?** 儘管 React 通常被稱為框架,但可以說,由於其範圍,它更像是一個函式庫。它專門負責管理 UI 的狀態並使其與應用程式中的資料狀態保持同步。 因此,它需要第 3 方函式庫來處理應用程式路由 (React Router)、UI 創建 (JSX) 和元件之間的狀態管理 (Redux)。 另一方面,Svelte 內建了上述所有功能,因此更像是一個完整的 UI 管理解決方案。 你可以看到大多數人都同意這是一個函式庫,但仍有一些爭論👇 https://twitter.com/htmleverything/status/1597574223148765185 ### **逐行比較 React 和 Svelte 專案** 比較兩種 Web 技術的最佳方法是深入研究並使用它們進行構建。構建完全相同的應用程序有助於了解每個庫/框架如何處理不同的功能。 讓我們看看: * 條件渲染 * 模板循環 * 更新狀態 * 事件掛鉤 ### **我們在建造什麼?** 編碼是一項口渴的工作,因此我們將構建一個簡單的網絡應用程序,允許用戶跟踪他們全天喝了多少杯水(或🍺)。 額外的好處是顯示每杯喝醉的歷史和時間。 我們將保持 UI 簡單,以更多地關注底層框架。 (見下面的用戶界面) https://codesandbox.io/embed/react-water-example-scrimba-ny5q0m?fontsize=14&hidenavigation=1&theme=dark ### **React** 為了分解代碼,首先讓我們深入了解一些 React 概念和術語👇 React 有幾種類型的語法你需要學習。鉤子、狀態和模板 (JSX) 是主要的。 鉤子 - 允許您進入應用程序的生命週期 State - 允許您根據數據的變化更新 UI 元素。它將“狀態”(或更簡單的變量)更改與 UI 更新聯繫起來 模板 - 允許您直接在 HTML 中使用變量和 JavaScript React 組件的樣式通常由單獨的 .css(或 .scss)文件處理。 ### **React 代碼分解** https://codesandbox.io/embed/react-water-example-scrimba-ny5q0m?fontsize=14&hidenavigation=1&theme=dark&view=editor 變數是使用 useState 掛鉤設置的,它允許更新變量並讓 UI 動態呈現這些更新。 `useEffect` 用於在加載應用程序時設置今天的日期。 JSX 模板使用基本的“{}”符號以及 HTML 中的標準 JavaScript 函數,允許顯示變量和循環數組(使用“.map”)。 ### **Svelte** Svelte 採用不同的方法,採用更“幕後魔術”的風格。邏輯看起來很像純 JavaScript。在後台,代碼做的事情幾乎與 React 代碼做的一樣。 Svelte 仍然有像 `onMount` 和 `onDestroy` 這樣的鉤子,但是簡單地分配一個變量並讓它完全響應並在模板 (HTML) 中可訪問不需要任何特殊的語法糖。 另一個很大的區別是您可以直接在 Svelte 組件中編寫 CSS/SCSS。這只是一個選項,因為您仍然可以像在 React 中一樣導入樣式,但我注意到大多數 Svelte 項目都使用樣式內組件。 ### **Svelte 代碼分解** https://codesandbox.io/embed/svelte-water-example-scrimba-2vsoid?fontsize=14&hidenavigation=1&module=%2FApp.svelte&theme=dark&view=editor 上面的代碼實例化了一個 cupsOfWater 數組,將新的日期變量設置為當前日期。 聲明一個函數來創建一個新日期並將其存儲在一個名為 cup 的變量中,然後將其添加到 cupsOfWater 數組中。 模板部分更接近 HTML 並增加了一些功能。再次使用“{}”表示法,您可以從“<script>”部分引用任何聲明的變量。您還可以使用事件偵聽器(如 `on:click`)、條件(如 `{#if}`)和使用 `{#each}` 循環。 ### **Svelte 比 React 快嗎?** 是的,從快速的 HTML 生成到更快的構建和開發環境,Svelte 的性能都大大優於 React。 * 生成 HTML * 根據狀態更新 UI * 第一次內容豐富的渲染 * 互動時間 * 速度指數 所有這些都看到了可衡量的差異,而 Svelte 具有優勢。您的應用程序越大越複雜,差異就越明顯。 在 Zeitspace 的一篇文章中可以看到性能比較 https://www.zeitspace.com/blog/we-built-an-app-with-svelte.-heres-what-we-learned ### **Svelte 比 React 好嗎?** 當開始一個新專案時,Svelte 有足夠的優勢,它應該始終是一個考慮因素。 話雖如此,React 在使用率方面仍然絕對勝過 Svelte。這可能會導致專案的第 3 方插件支持、僱用和壽命問題。 不過,為了應對這一點,Svelte 語法的易用性使其非常容易上手,尤其是對於 React 開發人員而言。這是公司在招聘 Svelte 項目時可以藉鑑的東西(不要將自己局限於 Svelte 開發人員)。 ### **何時從 React 切換到 Svelte** Svelte 是構建複雜網站或 Web 應用程序的絕佳選擇。許多老牌公司已經開始將 Svelte 用於內部和外部應用程序: * 1Password * Avast * Chess.com * Alaska Airlines * Fusion Charts * Rakuten * GoDaddy * IBM * Square * 紐約時報 * 飛利浦 但這並不意味著您必須將當前的 React 應用程序放入垃圾桶! 那麼什麼時候是接觸 Svelte 的合適時機? 如果您的應用/網站: * 由於頻寬限制,需要較小的包大小 * 需要盡可能快 * 需要快速建造 When is not the right time to reach for Svelte? 什麼時候不適合使用 Svelte? 如果您的應用/網站: * 嚴重依賴第 3 方集成/工具 * 需要轉換為移動應用程序 這些很快就不會成為問題,但在投入之前確實需要進行一些研究和盡職調查。 ### **結論** 建議投入其中並嘗試在 Svelte 中構建一些東西。如果你來自 React,我幾乎可以向你保證你會喜歡它的簡單性和速度。

寫 React 時必備的幾個 VS Code Extensions:新手推薦

來看看一些對 React 開發人員最有用的 VS Code 外掛吧! - 原文網址:https://dev.to/devland/vs-code-extensions-you-should-use-as-a-react-developer-2f6i ## ES7 React/Redux/GraphQL/React-Native snippets ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qoxlb7rz6gzkx906xfr5.jpg) 最流行的外掛之一,由 React 開發人員提供,也由 React-Native 開發人員參與。它帶有許多速記前綴,您可以輕鬆使用它來加快開發過程。 這個外掛提供了很多你可能不知道的功能。一旦你安裝了這個驚人的外掛,創建一個新文件並輸入 rfce 然後按回車鍵,這將生成一個 React 功能組件,導入 React 並導出元件。 ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8m942g0szndpv3bwprrb.jpg) 它還允許您在幾秒鐘內創建不同的 es7 片段,只需輸入前綴簡寫並按 enter。 此外,如果您使用的是 Redux 或 GraphQL,此外掛也為它們提供了程式碼片段。 ## VSCode React Refactor ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aa1etaf6lasubpmsjxgf.jpg) 簡單,但非常有用。允許您將 JSX 部分提取到新元件、文件等。使用類別、函數和箭頭函數並支持 TypeScript 和 TSX。 ## Prettier ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7tddr5birva6pja6ygoa.jpg) 經過多年使用 Prettier,我認為它是任何專案的都好用的外掛。這是一個自動為你格式化程式碼的工具。它有助於保持程式庫的一致性,因為無論團隊中的開發人員有什麼個人偏好,所有程式碼都將以相同的方式格式化。 ## Eslint ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6l039819s4qx6ngf0e8i.jpg) 用於查找程式碼中的錯誤和缺陷。它可以幫助開發人員編寫沒有錯誤和警告的優質程式碼。 此外,它可以自動修復錯誤和警告。 ## Stylelint ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ufskyyg4id7ets3rcjnt.jpg) 和ESLint類似,也是一個linter,但是針對樣式。它可以檢測並突出顯示不正確的樣式,並有助於保持樣式一致和有序。更重要的是,它適用於純 CSS 以及 SCSS 和 LESS 等預處理器。 ## GitLens ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6wmh3we9qrykvxari4mo.jpg) 增強了 Visual Studio Code 中內置的 Git 功能。它可以幫助您通過 Git 責備註釋和 code lens 一目了然地可視化代碼作者身份,無縫導航和探索 Git 存儲庫。 ## Git History ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzsboqxicv3bs8f0n7p1.jpg) 允許您查看 git 日誌和文件歷史記錄,並比較分支或提交。 ## Settings sync ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iphz26rbvb85pnuzcijf.jpg) 您是否曾經重新安裝作業系統或更改您編寫程式碼的設備、繼續安裝 VS Code、然後發現您需要重新安裝所有外掛?它可以自動保存你的外掛和 VS Code 設置,然後在另一台設備上安裝和配置它們。 ## Bracket Pair Colorization Toggler ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xw0embc8ohxzmaw54fq.jpg) 非常簡單但有用的擴展。突出顯示匹配的括號對。 ## Auto Close Tag ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yda8pr1303sn1kdzwoz8.jpg) 一個簡單但最有用的 React 外掛之一。它所做的是一件非常簡單的事情。 Auto close tag,顧名思義,為元素創建一個結束標籤,這意味著開發人員不需要編寫結束標籤。這可能看起來很簡單,但實際上,自動關閉標籤非常有用。 ## Auto Rename Tag ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7kjq4bz8u1ccgxgk2w9t.jpg) 自動重命名成對的 HTML/XML 標籤。 ## Auto Import ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zy56itc3bb5jvecscf2v.jpg) 自動為所有可用導入查找、解析並提供代碼操作和代碼完成。適用於 TypeScript 和 TSX。 ## Import Cost ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wxw0io8difxgthdan5c.jpg) 在 React 中,安裝和導入套件是非常常見和必要的。導入大量套件可能會導致性能問題,因為其中一些包可能很重。此外掛在編輯器中顯示套件的大小。 ## Jumpy ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cp8cldekpyxyesyz1o8j.jpg) 您通常如何從一行程式碼轉到幾行和空格之外的特定關鍵字?多次使用鍵盤箭頭或單擊滑鼠?使用 Jumpy,您可以更有效率,因為它可以讓您快速跳轉到特定單詞。 ## i18n Ally ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jmqx39hkds4lbeoytb1p.jpg) 如果您的應用程序支持多種語言,就非常好用。 Formatting toggle ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fhhj774y6xeapll2tomq.jpg) 在某些情況下,我們希望暫時禁用像 Prettier 這樣的代碼格式化程序。這可以通過 Formatting toggle 外掛來完成,無需修改編輯器設置。 ## Npm intellisense ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75wl3nmlkporzfsnxl6g.jpg) 為導入語句中的 npm 模塊提供自動完成功能。 ## Web Accessibility ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3lni8zqwdh4ngwyk1rm.jpg) 用於提高 Web 應用程序可訪問性的出色插件。它突出顯示了您應該考慮更改的元素,還提供了有關如何更新它們的提示。 ## Live Share ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74okun8atu01lphpjo7c.jpg) 您願意與其他人協作編寫您的代碼嗎? 此外掛使您能夠與他人實時編輯和調試代碼。 ## Better comments ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/odj7yo1a5sntmhkl4x57.jpg) 用於在您的代碼中創建更人性化的註釋。它可以將評論分類為警報、查詢、待辦事項和突出顯示,並以不同的顏色顯示它們。 ## Docker ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/patpizcxw2hs6gu823em.jpg) 如果您的應用程序是使用 Docker 部署的,您可以考慮使用來簡化構建、管理和部署來自 VS Code 的容器化應用程序。 ## Remote — SSH ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kk6amn6yubsmio7uen68.jpg) 您是否需要訪問服務器才能遠程編輯文件?遠程 SSH 讓您可以使用任何帶有 SSH 服務器的遠程機器作為您的開發環境。您可以輕鬆地在遠程和本地開發環境之間切換。 ## WSL ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kd4n337eomix1ba0tn7.jpg) 如果您更喜歡在 Linux 上開發您的應用程序,但您的主要操作系統是 Windows,您可以考慮使用 Windows 子系統 Linux (WSL)。如果這樣做,那麼您可能會發現 WSL 擴展很有用,因為它可以讓您在 Windows 上使用 Vs Code構建 Linux 應用程序。在使用基於 Linux 的工具、運行時和實用程序進行開發時,您可以獲得 Windows 的所有生產力。 ## 實時服務器 ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzaylae1618ndvty1agf.jpg) 如果您需要在文件更改時通過實時瀏覽器重新加載來快速啟動實時服務器,很推薦。 ## Debugger for Chrome and Debugger for Firefox ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5hqzk58hdihl2syoctg5.jpg) 調試器提供了許多有用的功能,例如在斷點處暫停代碼執行、變量檢查等。這些擴展提供了 VS Code 編輯器內部的調試功能。 ## Change-case ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qeoqoevy2a6d646ht1ir.jpg) 顧名思義,此擴展允許您更改當前選擇或當前單詞的大小寫。如果您有很長的文本或想將多個變量轉換為相同的大小寫,這將非常有用。 ## Regex Previewer ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pr4eesyhl5bpj0afhhll.jpg) 大多數開發人員很少編寫 Regex 表達式。但是,如果必須,此擴展可能會非常方便。它在並排文檔中顯示當前正則表達式的匹配項。 ## DotENV ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19cpgt5rvygiysu87qi8.jpg) _.env_ 文件的語法突出顯示。 ## 結論 希望對您有幫助!

關於 TypeScript 中 Utility Types 的小知識:新手推薦

TypeScript 的型別系統很強大,大部分專案都在用。此外,在 TypeScript 中,其實有提供一些 Utility Types 來輔助我們進行型別定義與操作。今天與您分享其中五個。 - 原文出處:https://dev.to/murillonahvs/a-little-about-typescript-utility-types-1epd ### Summary - Pick - Omit - ReadOnly - Partial - Required --- ## 1. Pick(Type, Keys) Pick utility type 是從現有型別中選取某些屬性來生成新的型別。 基本上,Pick 從指定型別中刪除除指定鍵之外的所有鍵。 ``` type Person = { name: string lastName: string age: number hobbies: string } type SomePerson = Pick<Person, "name" | "age"> // type SomePerson = { // name: string; // age: number; // } ``` --- ## 2. Omit(Type, Keys) Omit utili type 與 Pick 型別相反,Omit 是寫出要省略的屬性,而不是要保留的屬性。 ``` type Person = { name: string lastName: string age: number hobbies: string } type SomePerson = Omit<Person, "lastName" | "hobbies"> // type SomePerson = { // name: string; // age: number; // } ``` --- ## 3. Readonly(Type) Readonly utility type 用於所有屬性都設置成唯讀的型別。無法為屬性分配新值,不然就跳 TypeScript 警告。 ``` type Person = { name: string } type ReadOnlyPerson = Readonly<Person> const person: ReadOnlyPerson = { name: "Fizz", } person.name = "Buzz" // Cannot assign to 'name' because it is a read-only property. ``` --- ## 4. Partial(Type) Partial utility type 用於所有屬性都設置為選填的型別。 ``` type Person = { name: string lastName: string age: number address: string } type PartialPerson = Partial<Person> // type PartialPerson = { // name?: string | undefined; // lastName?: string | undefined; // age?: number | undefined; // address?: string | undefined; // } ``` --- ## 5. Required(Type) Required utility type 與 Partial 相反。要求要定義好所有屬性。可用來避免選填屬性出現在此型別中。 ``` type Person = { name?: string lastName?: string age?: number address?: string } type RequiredPerson = Required<Person> // type RequiredPerson = { // name: string; // lastName: string; // age: number; // address: string; // } ``` --- 以上,簡單舉例五個分享,有很多好用的 utility type,歡迎查看官網了解更多: https://www.typescriptlang.org/docs/handbook/utility-types.html

快速複習 React 基本觀念&實務範例:推薦新手參考

React 作為一個強大的前端工具,有很多需要熟悉的基本觀念&語法。 這篇文章做一個快速的全面整理,方便工作時,可以隨時翻閱,希望您喜歡。 - 原文出處:https://dev.to/reedbarger/the-react-cheatsheet-for-2020-real-world-examples-4hgg ## 核心概念 ### 元素和 JSX - React 元素的基本語法 ``` // In a nutshell, JSX allows us to write HTML in our JS // JSX can use any valid html tags (i.e. div/span, h1-h6, form/input, etc) <div>Hello React</div> ``` - JSX 元素就是一段表達式 ``` // as an expression, JSX can be assigned to variables... const greeting = <div>Hello React</div>; const isNewToReact = true; // ... or can be displayed conditionally function sayGreeting() { if (isNewToReact) { // ... or returned from functions, etc. return greeting; // displays: Hello React } else { return <div>Hi again, React</div>; } } ``` - JSX 允許我們嵌套表達式 ``` const year = 2020; // we can insert primitive JS values in curly braces: {} const greeting = <div>Hello React in {year}</div>; // trying to insert objects will result in an error ``` - JSX 允許我們嵌套元素 ``` // to write JSX on multiple lines, wrap in parentheses: () const greeting = ( // div is the parent element <div> {/* h1 and p are child elements */} <h1>Hello!</h1> <p>Welcome to React</p> </div> ); // 'parents' and 'children' are how we describe JSX elements in relation // to one another, like we would talk about HTML elements ``` - HTML 和 JSX 的語法略有不同 ``` // Empty div is not <div></div> (HTML), but <div/> (JSX) <div/> // A single tag element like input is not <input> (HTML), but <input/> (JSX) <input name="email" /> // Attributes are written in camelcase for JSX (like JS variables <button className="submit-button">Submit</button> // not 'class' (HTML) ``` - 最基本的 React 應用程式需要三樣東西: - 1. ReactDOM.render() 渲染我們的應用程序 - 2. 一個 JSX 元素(在此情況下,稱為根節點) - 3. 一個用於掛載應用程式的 DOM 元素(通常是 index.html 文件中 id 為 root 的 div) ``` // imports needed if using NPM package; not if from CDN links import React from "react"; import ReactDOM from "react-dom"; const greeting = <h1>Hello React</h1>; // ReactDOM.render(root node, mounting point) ReactDOM.render(greeting, document.getElementById("root")); ``` ### 元件和 Props - 基本 React 元件的語法 ``` import React from "react"; // 1st component type: function component function Header() { // function components must be capitalized unlike normal JS functions // note the capitalized name here: 'Header' return <h1>Hello React</h1>; } // function components with arrow functions are also valid const Header = () => <h1>Hello React</h1>; // 2nd component type: class component // (classes are another type of function) class Header extends React.Component { // class components have more boilerplate (with extends and render method) render() { return <h1>Hello React</h1>; } } ``` - 如何使用元件 ``` // do we call these function components like normal functions? // No, to execute them and display the JSX they return... const Header = () => <h1>Hello React</h1>; // ...we use them as 'custom' JSX elements ReactDOM.render(<Header />, document.getElementById("root")); // renders: <h1>Hello React</h1> ``` - 元件可以在我們的應用程式中重複使用 ``` // for example, this Header component can be reused in any app page // this component shown for the '/' route function IndexPage() { return ( <div> <Header /> <Hero /> <Footer /> </div> ); } // shown for the '/about' route function AboutPage() { return ( <div> <Header /> <About /> <Testimonials /> <Footer /> </div> ); } ``` - 資料可以通過 props 動態傳遞給元件 ``` // What if we want to pass data to our component from a parent? // I.e. to pass a user's name to display in our Header? const username = "John"; // we add custom 'attributes' called props ReactDOM.render( <Header username={username} />, document.getElementById("root") ); // we called this prop 'username', but can use any valid JS identifier // props is the object that every component receives as an argument function Header(props) { // the props we make on the component (i.e. username) // become properties on the props object return <h1>Hello {props.username}</h1>; } ``` - Props 不可直接改變(mutate) ``` // Components must ideally be 'pure' functions. // That is, for every input, we be able to expect the same output // we cannot do the following with props: function Header(props) { // we cannot mutate the props object, we can only read from it props.username = "Doug"; return <h1>Hello {props.username}</h1>; } // But what if we want to modify a prop value that comes in? // That's where we would use state (see the useState section) ``` - 如果我們想將元素/元件作為 props 傳遞給其它元件,可以用 children props ``` // Can we accept React elements (or components) as props? // Yes, through a special property on the props object called 'children' function Layout(props) { return <div className="container">{props.children}</div>; } // The children prop is very useful for when you want the same // component (such as a Layout component) to wrap all other components: function IndexPage() { return ( <Layout> <Header /> <Hero /> <Footer /> </Layout> ); } // different page, but uses same Layout component (thanks to children prop) function AboutPage() { return ( <Layout> <About /> <Footer /> </Layout> ); } ``` - 可以用三元運算子來條件顯示元件 ``` // if-statements are fine to conditionally show , however... // ...only ternaries (seen below) allow us to insert these conditionals // in JSX, however function Header() { const isAuthenticated = checkAuth(); return ( <nav> <Logo /> {/* if isAuth is true, show AuthLinks. If false, Login */} {isAuthenticated ? <AuthLinks /> : <Login />} {/* if isAuth is true, show Greeting. If false, nothing. */} {isAuthenticated && <Greeting />} </nav> ); } ``` - Fragments 是用來顯示多個元件的特殊元件,無需向 DOM 添加額外的元素 - Fragments 適合用在條件邏輯 ``` // we can improve the logic in the previous example // if isAuthenticated is true, how do we display both AuthLinks and Greeting? function Header() { const isAuthenticated = checkAuth(); return ( <nav> <Logo /> {/* we can render both components with a fragment */} {/* fragments are very concise: <> </> */} {isAuthenticated ? ( <> <AuthLinks /> <Greeting /> </> ) : ( <Login /> )} </nav> ); } ``` ### 列表和 keys - 使用 .map() 將資料列表(陣列)轉換為元素列表 ``` const people = ["John", "Bob", "Fred"]; const peopleList = people.map(person => <p>{person}</p>); ``` - .map() 也可用來轉換為元件列表 ``` function App() { const people = ['John', 'Bob', 'Fred']; // can interpolate returned list of elements in {} return ( <ul> {/* we're passing each array element as props */} {people.map(person => <Person name={person} />} </ul> ); } function Person({ name }) { // gets 'name' prop using object destructuring return <p>this person's name is: {name}</p>; } ``` - 迭代的每個 React 元素都需要一個特殊的 `key` prop - key 對於 React 來說是必須的,以便能夠追蹤每個正在用 map 迭代的元素 - 沒有 key,當資料改變時,React 較難弄清楚元素應該如何更新 - key 應該是唯一值,才能讓 React 知道如何分辨 ``` function App() { const people = ['John', 'Bob', 'Fred']; return ( <ul> {/* keys need to be primitive values, ideally a generated id */} {people.map(person => <Person key={person} name={person} />)} </ul> ); } // If you don't have ids with your set of data or unique primitive values, // you can use the second parameter of .map() to get each elements index function App() { const people = ['John', 'Bob', 'Fred']; return ( <ul> {/* use array element index for key */} {people.map((person, i) => <Person key={i} name={person} />)} </ul> ); } ``` ### 事件和事件處理器 - React 和 HTML 中的事件略有不同 ``` // Note: most event handler functions start with 'handle' function handleToggleTheme() { // code to toggle app theme } // in html, onclick is all lowercase <button onclick="handleToggleTheme()"> Submit </button> // in JSX, onClick is camelcase, like attributes / props // we also pass a reference to the function with curly braces <button onClick={handleToggleTheme}> Submit </button> ``` - 最該先學的 React 事件是 onClick 和 onChange - onClick 處理 JSX 元素上的點擊事件(也就是按鈕動作) - onChange 處理鍵盤事件(也就是打字動作) ``` function App() { function handleChange(event) { // when passing the function to an event handler, like onChange // we get access to data about the event (an object) const inputText = event.target.value; const inputName = event.target.name; // myInput // we get the text typed in and other data from event.target } function handleSubmit() { // on click doesn't usually need event data } return ( <div> <input type="text" name="myInput" onChange={handleChange} /> <button onClick={handleSubmit}>Submit</button> </div> ); } ``` ## React Hooks ### State and useState - useState 為我們提供 function component 中的本地狀態 ``` import React from 'react'; // create state variable // syntax: const [stateVariable] = React.useState(defaultValue); function App() { const [language] = React.useState('javascript'); // we use array destructuring to declare state variable return <div>I am learning {language}</div>; } ``` - 注意:此段文章中的任何 hook 都來自 React 套件,且可以單獨導入 ``` import React, { useState } from "react"; function App() { const [language] = useState("javascript"); return <div>I am learning {language}</div>; } ``` - useState 還為我們提供了一個 `setter` 函數來更新它的狀態 ``` function App() { // the setter function is always the second destructured value const [language, setLanguage] = React.useState("python"); // the convention for the setter name is 'setStateVariable' return ( <div> {/* why use an arrow function here instead onClick={setterFn()} ? */} <button onClick={() => setLanguage("javascript")}> Change language to JS </button> {/* if not, setLanguage would be called immediately and not on click */} <p>I am now learning {language}</p> </div> ); } // note that whenever the setter function is called, the state updates, // and the App component re-renders to display the new state ``` - useState 可以在單個元件中使用一次或多次 ``` function App() { const [language, setLanguage] = React.useState("python"); const [yearsExperience, setYearsExperience] = React.useState(0); return ( <div> <button onClick={() => setLanguage("javascript")}> Change language to JS </button> <input type="number" value={yearsExperience} onChange={event => setYearsExperience(event.target.value)} /> <p>I am now learning {language}</p> <p>I have {yearsExperience} years of experience</p> </div> ); } ``` - useState 可以接受 primitive value 或物件 ``` // we have the option to organize state using whatever is the // most appropriate data type, according to the data we're tracking function App() { const [developer, setDeveloper] = React.useState({ language: "", yearsExperience: 0 }); function handleChangeYearsExperience(event) { const years = event.target.value; // we must pass in the previous state object we had with the spread operator setDeveloper({ ...developer, yearsExperience: years }); } return ( <div> {/* no need to get prev state here; we are replacing the entire object */} <button onClick={() => setDeveloper({ language: "javascript", yearsExperience: 0 }) } > Change language to JS </button> {/* we can also pass a reference to the function */} <input type="number" value={developer.yearsExperience} onChange={handleChangeYearsExperience} /> <p>I am now learning {developer.language}</p> <p>I have {developer.yearsExperience} years of experience</p> </div> ); } ``` - 如果新狀態依賴於之前的狀態,我們可以在 setter 函數中使用一個函數來為我們提供之前狀態的值 ``` function App() { const [developer, setDeveloper] = React.useState({ language: "", yearsExperience: 0, isEmployed: false }); function handleToggleEmployment(event) { // we get the previous state variable's value in the parameters // we can name 'prevState' however we like setDeveloper(prevState => { return { ...prevState, isEmployed: !prevState.isEmployed }; // it is essential to return the new state from this function }); } return ( <button onClick={handleToggleEmployment}>Toggle Employment Status</button> ); } ``` ### side effects 和 useEffect - useEffect 讓我們在 function component 中執行副作用。什麼是副作用? - 副作用是我們需要接觸外部世界的地方。例如,從 API 獲取資料或操作 DOM。 - 副作用是可能以不可預測的方式,改變我們元件狀態的操作(導致「副作用」)。 - useEffect 接受 callback function(稱為 effect 函數),預設情況下,每次重新渲染時都會運行 - useEffect 在我們的元件載入後運行,可以準確在元件的各個生命週期觸發 ``` // what does our code do? Picks a color from the colors array // and makes it the background color function App() { const [colorIndex, setColorIndex] = React.useState(0); const colors = ["blue", "green", "red", "orange"]; // we are performing a 'side effect' since we are working with an API // we are working with the DOM, a browser API outside of React useEffect(() => { document.body.style.backgroundColor = colors[colorIndex]; }); // whenever state is updated, App re-renders and useEffect runs function handleChangeIndex() { const next = colorIndex + 1 === colors.length ? 0 : colorIndex + 1; setColorIndex(next); } return <button onClick={handleChangeIndex}>Change background color</button>; } ``` - 如果不想在每次渲染後都執行 callback function,可以在第二個參數傳一個空陣列 ``` function App() { ... // now our button doesn't work no matter how many times we click it... useEffect(() => { document.body.style.backgroundColor = colors[colorIndex]; }, []); // the background color is only set once, upon mount // how do we not have the effect function run for every state update... // but still have it work whenever the button is clicked? return ( <button onClick={handleChangeIndex}> Change background color </button> ); } ``` - useEffect 讓我們能夠在 dependencies 陣列的內容改變時,才執行 - dependencies 陣列是第二個參數,如果陣列中的任何一個值發生變化,effect function 將再次運行 ``` function App() { const [colorIndex, setColorIndex] = React.useState(0); const colors = ["blue", "green", "red", "orange"]; // we add colorIndex to our dependencies array // when colorIndex changes, useEffect will execute the effect fn again useEffect(() => { document.body.style.backgroundColor = colors[colorIndex]; // when we use useEffect, we must think about what state values // we want our side effect to sync with }, [colorIndex]); function handleChangeIndex() { const next = colorIndex + 1 === colors.length ? 0 : colorIndex + 1; setColorIndex(next); } return <button onClick={handleChangeIndex}>Change background color</button>; } ``` - 可以在 useEffect 最後回傳一個函數,來取消訂閱某些效果 ``` function MouseTracker() { const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 }); React.useEffect(() => { // .addEventListener() sets up an active listener... window.addEventListener("mousemove", handleMouseMove); // ...so when we navigate away from this page, it needs to be // removed to stop listening. Otherwise, it will try to set // state in a component that doesn't exist (causing an error) // We unsubscribe any subscriptions / listeners w/ this 'cleanup function' return () => { window.removeEventListener("mousemove", handleMouseMove); }; }, []); function handleMouseMove(event) { setMousePosition({ x: event.pageX, y: event.pageY }); } return ( <div> <h1>The current mouse position is:</h1> <p> X: {mousePosition.x}, Y: {mousePosition.y} </p> </div> ); } // Note: we could extract the reused logic in the callbacks to // their own function, but I believe this is more readable ``` - 使用 useEffect 撈取資料 - 請注意,如果要使用更簡潔的 async/awit 語法處理 promise,則需要建立一個單獨的函數(因為 effect callback function 不能是 async) ``` const endpoint = "https://api.github.com/users/codeartistryio"; // with promises: function App() { const [user, setUser] = React.useState(null); React.useEffect(() => { // promises work in callback fetch(endpoint) .then(response => response.json()) .then(data => setUser(data)); }, []); } // with async / await syntax for promise: function App() { const [user, setUser] = React.useState(null); // cannot make useEffect callback function async React.useEffect(() => { getUser(); }, []); // instead, use async / await in separate function, then call // function back in useEffect async function getUser() { const response = await fetch("https://api.github.com/codeartistryio"); const data = await response.json(); setUser(data); } } ``` ### 效能和 useCallback - useCallback 是一個用來提高元件性能的 hook - 如果你有一個經常重新渲染的元件,useCallback 可以防止元件內的 callback function 在每次元件重新渲染時都重新創建(導致元件重新運行) - useCallback 僅在其依賴項之一改變時重新運行 ``` // in Timer, we are calculating the date and putting it in state a lot // this results in a re-render for every state update // we had a function handleIncrementCount to increment the state 'count'... function Timer() { const [time, setTime] = React.useState(); const [count, setCount] = React.useState(0); // ... but unless we wrap it in useCallback, the function is // recreated for every single re-render (bad performance hit) // useCallback hook returns a callback that isn't recreated every time const inc = React.useCallback( function handleIncrementCount() { setCount(prevCount => prevCount + 1); }, // useCallback accepts a second arg of a dependencies array like useEffect // useCallback will only run if any dependency changes (here it's 'setCount') [setCount] ); React.useEffect(() => { const timeout = setTimeout(() => { const currentTime = JSON.stringify(new Date(Date.now())); setTime(currentTime); }, 300); return () => { clearTimeout(timeout); }; }, [time]); return ( <div> <p>The current time is: {time}</p> <p>Count: {count}</p> <button onClick={inc}>+</button> </div> ); } ``` ### Memoization 和 useMemo - useMemo 和 useCallback 非常相似,都是為了提高效能。但就不是為了暫存 callback function,而是為了暫存耗費效能的運算結果 - useMemo 允許我們「記憶」已經為某些輸入進行了昂貴計算的結果(之後就不用重新計算了) - useMemo 從計算中回傳一個值,而不是 callback 函數(但可以是一個函數) ``` // useMemo is useful when we need a lot of computing resources // to perform an operation, but don't want to repeat it on each re-render function App() { // state to select a word in 'words' array below const [wordIndex, setWordIndex] = useState(0); // state for counter const [count, setCount] = useState(0); // words we'll use to calculate letter count const words = ["i", "am", "learning", "react"]; const word = words[wordIndex]; function getLetterCount(word) { // we mimic expensive calculation with a very long (unnecessary) loop let i = 0; while (i < 1000000) i++; return word.length; } // Memoize expensive function to return previous value if input was the same // only perform calculation if new word without a cached value const letterCount = React.useMemo(() => getLetterCount(word), [word]); // if calculation was done without useMemo, like so: // const letterCount = getLetterCount(word); // there would be a delay in updating the counter // we would have to wait for the expensive function to finish function handleChangeIndex() { // flip from one word in the array to the next const next = wordIndex + 1 === words.length ? 0 : wordIndex + 1; setWordIndex(next); } return ( <div> <p> {word} has {letterCount} letters </p> <button onClick={handleChangeIndex}>Next word</button> <p>Counter: {count}</p> <button onClick={() => setCount(count + 1)}>+</button> </div> ); } ``` ### Refs 和 useRef - Refs 是所有 React 組件都可用的特殊屬性。允許我們在元件安裝時,創建針對特定元素/元件的引用 - useRef 允許我們輕鬆使用 React refs - 我們在元件開頭呼叫 useRef,並將回傳值附加到元素的 ref 屬性來引用它 - 一旦我們創建了一個引用,就可以用它來改變元素的屬性,或者可以呼叫該元素上的任何可用方法(比如用 .focus() 來聚焦) ``` function App() { const [query, setQuery] = React.useState("react hooks"); // we can pass useRef a default value // we don't need it here, so we pass in null to ref an empty object const searchInput = useRef(null); function handleClearSearch() { // current references the text input once App mounts searchInput.current.value = ""; // useRef can store basically any value in its .current property searchInput.current.focus(); } return ( <form> <input type="text" onChange={event => setQuery(event.target.value)} ref={searchInput} /> <button type="submit">Search</button> <button type="button" onClick={handleClearSearch}> Clear </button> </form> ); } ``` ## 進階 Hook ### Context 和 useContext - 在 React 中,盡量避免創建多個 props 來將資料從父元件向下傳遞兩個或多個層級 ``` // Context helps us avoid creating multiple duplicate props // This pattern is also called props drilling: function App() { // we want to pass user data down to Header const [user] = React.useState({ name: "Fred" }); return ( // first 'user' prop <Main user={user} /> ); } const Main = ({ user }) => ( <> {/* second 'user' prop */} <Header user={user} /> <div>Main app content...</div> </> ); const Header = ({ user }) => <header>Welcome, {user.name}!</header>; ``` - Context 有助於將 props 從父組件向下傳遞到多個層級的子元件 ``` // Here is the previous example rewritten with Context // First we create context, where we can pass in default values const UserContext = React.createContext(); // we call this 'UserContext' because that's what data we're passing down function App() { // we want to pass user data down to Header const [user] = React.useState({ name: "Fred" }); return ( {/* we wrap the parent component with the provider property */} {/* we pass data down the computer tree w/ value prop */} <UserContext.Provider value={user}> <Main /> </UserContext.Provider> ); } const Main = () => ( <> <Header /> <div>Main app content...</div> </> ); // we can remove the two 'user' props, we can just use consumer // to consume the data where we need it const Header = () => ( {/* we use this pattern called render props to get access to the data*/} <UserContext.Consumer> {user => <header>Welcome, {user.name}!</header>} </UserContext.Consumer> ); ``` - useContext hook 可以移除這種看起來很怪的 props 渲染模式,同時又能在各種 function component 中隨意使用 ``` const Header = () => { // we pass in the entire context object to consume it const user = React.useContext(UserContext); // and we can remove the Consumer tags return <header>Welcome, {user.name}!</header>; }; ``` ### Reducers 和 useReducer - Reducers 是簡單、可預測的(純)函數,它接受一個先前的狀態物件和一個動作物件,並回傳一個新的狀態物件。例如: ``` // let's say this reducer manages user state in our app: function reducer(state, action) { // reducers often use a switch statement to update state // in one way or another based on the action's type property switch (action.type) { // if action.type has the string 'LOGIN' on it case "LOGIN": // we get data from the payload object on action return { username: action.payload.username, isAuth: true }; case "SIGNOUT": return { username: "", isAuth: false }; default: // if no case matches, return previous state return state; } } ``` - Reducers 是一種強大的狀態管理模式,用於流行的 Redux 狀態管理套件(這套很常與 React 一起使用) - 與 useState(用於本地元件狀態)相比,Reducers 可以通過 useReducer hook 在 React 中使用,以便管理我們應用程序的狀態 - useReducer 可以與 useContext 配對來管理資料並輕鬆地將資料傳遞給元件 - useReducer + useContext 可以當成應用程式的整套狀態管理系統 ``` const initialState = { username: "", isAuth: false }; function reducer(state, action) { switch (action.type) { case "LOGIN": return { username: action.payload.username, isAuth: true }; case "SIGNOUT": // could also spread in initialState here return { username: "", isAuth: false }; default: return state; } } function App() { // useReducer requires a reducer function to use and an initialState const [state, dispatch] = useReducer(reducer, initialState); // we get the current result of the reducer on 'state' // we use dispatch to 'dispatch' actions, to run our reducer // with the data it needs (the action object) function handleLogin() { dispatch({ type: "LOGIN", payload: { username: "Ted" } }); } function handleSignout() { dispatch({ type: "SIGNOUT" }); } return ( <> Current user: {state.username}, isAuthenticated: {state.isAuth} <button onClick={handleLogin}>Login</button> <button onClick={handleSignout}>Signout</button> </> ); } ``` ### 編寫 custom hooks - 創建 hook 就能輕鬆在元件之間重用某些行為 - hook 是一種比以前的 class component 更容易理解的模式,例如 higher-order components 或者 render props - 根據需要,隨時可以自創一些 hook ``` // here's a custom hook that is used to fetch data from an API function useAPI(endpoint) { const [value, setValue] = React.useState([]); React.useEffect(() => { getData(); }, []); async function getData() { const response = await fetch(endpoint); const data = await response.json(); setValue(data); }; return value; }; // this is a working example! try it yourself (i.e. in codesandbox.io) function App() { const todos = useAPI("https://todos-dsequjaojf.now.sh/todos"); return ( <ul> {todos.map(todo => <li key={todo.id}>{todo.text}</li>)} </ul> ); } ``` ### Hooks 規則 - 使用 React hooks 有兩個核心規則,要遵守才能正常運作: - 1. Hooks 只能在元件開頭呼叫 - Hooks 不能放在條件、迴圈或嵌套函數中 - 2. Hooks只能在 function component 內部使用 - Hooks 不能放在普通的 JavaScript 函數或 class component 中 ``` function checkAuth() { // Rule 2 Violated! Hooks cannot be used in normal functions, only components React.useEffect(() => { getUser(); }, []); } function App() { // this is the only validly executed hook in this component const [user, setUser] = React.useState(null); // Rule 1 violated! Hooks cannot be used within conditionals (or loops) if (!user) { React.useEffect(() => { setUser({ isAuth: false }); // if you want to conditionally execute an effect, use the // dependencies array for useEffect }, []); } checkAuth(); // Rule 1 violated! Hooks cannot be used in nested functions return <div onClick={() => React.useMemo(() => doStuff(), [])}>Our app</div>; } ``` --- 以上是快速整理,希望對您有幫助!

React 生態系中,5個比較少見,但很好用的套件

我很喜歡在 NPM 目錄到處逛、尋找優質小套件。今天跟你分享五個我的近期發現! - 原文出處:https://dev.to/naubit/5-small-and-hidden-react-libraries-you-should-already-be-using-nb5 ## 1. Urlcat Urlcat 是一個小型的 Javascript 套件,可以非常方便地建立 URL、預防常見錯誤。 你當然可以直接用 URL API 來建立網址,但這種做法需要你手動處理一些細節。 Urlcat 就方便多了,隨插即用,不用花一堆時間讀文件,就能直接開始用。 https://github.com/balazsbotond/urlcat ## 2. UseHooks-ts ![](https://imgur.com/n7DL06Z.png) 如果你是 React 開發者、有在用 hook,很多時候你需要替一大堆小東西寫 custom hook。像是處理深色模式、處理視窗大小變化事件,等等。 UseHooks 是一個小套件,針對各種小案例都有現成的 hook,而且文件齊全、支援 TypeScript。 https://github.com/juliencrn/usehooks-ts ## 3. Logt ![](https://imgur.com/PU6eNCJ.gif) 我喜歡到處都有日誌,當需要知道發生了什麼時,就可以檢查。 當我寫前端時,**我也想要那些日誌**。但有一些先決條件: - 必須有完整的型別(這樣我就可以在 Typescript 中方便使用) - 必須很小 - 必須有彩色標籤(所以我很快就知道日誌類型) - 必須有分日誌級別 - 必須有一些方法,可以根據條件隱藏一些日誌(比如是否在正式環境) - 必須可以將這些日誌發送到其他地方(比如 Sentry) 經過大量時間研究(我都快自己開始寫了)我找到了 Logt,**它滿足我的所有要求**。 100% 推薦! https://github.com/sidhantpanda/logt ## 4. Loadable Components ![](https://imgur.com/H6eoKeF.png) 如果你正在嘗試優化 React 應用程式,**你可能正在使用 React.lazy** 和 Suspense 來延遲載入元件。 雖然也是可以,但還有更好的方法!比如這個套件。我無法在此完整說明原因,但請參考以下比較: https://loadable-components.com/docs/loadable-vs-react-lazy/ 基本上,它支持 **SSR**(_Server Side Rendering_)、**Library Splitting**,甚至 **完全動態導入**。還不錯吧? 此外,它真的很容易使用。**幾乎即插即用。**所以,試試吧! https://github.com/gregberge/loadable-components ## 5. Emoji Mart ![](https://imgur.com/jBA63Iu.png) 在處理不同的專案時,**我總是要處理表情符號。**現在到處都在使用它。而且我通常必須在專案中添加一些表情符號選擇器元件。 這還不算難。但是隨後開始收到更多要求:它必須**延遲載入表情符號**,它必須支持**國際化**,它必須允許**搜尋**,它必須允許使用**與 slack 相同的查詢縮寫**… 這些是可以做,但還是花時間在專案本身比較好吧。 所以,來使用 Emoji Mart 吧! https://github.com/missive/emoji-mart --- 以上是五個好用但是還不知名的小套件,希望你喜歡!

開發 React 時,推薦使用這些 Best Practices

在開發 React App 時,遵循一些 best practices 會使您的程式碼品質提高,這篇文章列出一些給您參考。 - 原文出處:https://dev.to/iambilalriaz/react-best-practices-ege # 強烈推薦 VS Code 作為 IDE Visual Studio Code 有幾個超好用的 React 功能。強大的外掛生態系,對開發者大有幫助: - Prettier - ES Lint - JavaScript (ES6) code snippets - Reactjs code snippets - Auto import # 使用 ES6 語法 程式碼越漂亮越好。在 JavaScript 中,採用 ES6 語法可以讓程式碼更簡潔。 ## Arrow Functions ``` // ES5 function getSum(a, b) { return a + b; } // ES6 const getSum = (a, b) => a + b; ``` ## Template Literal ``` // ES5 var name = "Bilal"; console.log("My name is " + name); // ES6 const name = "Bilal"; console.log(`My name is ${name}`); ``` ## const $ let const $ let 有各自的變數作用域。const 宣告的變數不能修改,let 宣告的變數可以修改。 ``` // ES5 var fruits = ["apple", "banana"]; // ES6 let fruits = ["apple", "banana"]; fruits.push("mango"); const workingHours = 8; ``` ## Object Destructuring ``` var person = { name: "John", age: 40, }; // ES5 var name = person.name; var age = person.age; // ES6 const { name, age } = person; ``` ## Defining Objects ``` var name = "John"; var age = 40; var designations = "Full Stack Developer"; var workingHours = 8; // ES5 var person = { name: name, age: age, designation: designation, workingHours: workingHours, }; // ES6 const person = { name, age, designation, workingHours }; ``` ES6 的語法特性、彈性,很多值得您一試。 # JSX 使用 map 時記得加上 key array map 時,永遠記得替每個元素加上獨立的 key 值。 ``` const students = [{id: 1, name: 'Bilal'}, {id: 2, name: 'Haris'}]; // in return function of component <ul> {students.map(({id, name}) => ( <li key={id}>{name}</li> ))} </ul>; ``` # 元件名稱使用 PascalCase ``` const helloText = () => <div>Hello</div>; // wrong const HelloText = () => <div>Hello</div>; // correct ``` # 變數和函數名稱使用 camelCase ``` const working_hours = 10; // bad approach const workingHours = 10; // good approach const get_sum = (a, b) => a + b; // bad approach const getSum = (a, b) => a + b; // good approach ``` # ID 和 css class 名稱使用 kebab-case ``` <!--bad approach--> <div className="hello_word" id="hello_world">Hello World</div> <!--good approach --> <div className="hello-word" id="hello-world">Hello World</div> ``` # 永遠要檢查物件&陣列的 null & undefined 忘記檢查的話,常常會導致一堆錯誤。 所以要保持檢查的習慣。 ``` const person = { name: "Haris", city: "Lahore", }; console.log("Age", person.age); // error console.log("Age", person.age ? person.age : 20); // correct console.log("Age", person.age ?? 20); //correct const oddNumbers = undefined; console.log(oddNumbers.length); // error console.log(oddNumbers.length ? oddNumbers.length : "Array is undefined"); // correct console.log(oddNumbers.length ?? "Array is undefined"); // correct ``` # 避免 Inline Styling Inline styling 會讓 jsx 程式碼變得很亂。用單獨的 css 文件拆分出來比較好。 ``` const text = <div style={{ fontWeight: "bold" }}>Happy Learing!</div>; // bad approach const text = <div className="learning-text">Happy Learing!</div>; // good approach ``` 在 .css 文件中: ``` .learning-text { font-weight: bold; } ``` # 避免 DOM 操作 用 React state 為主,別用 DOM 操作 糟糕做法: ``` <div id="error-msg">Please enter a valid value</div> ``` ``` document.getElementById("error-msg").visibility = visible; ``` 推薦做法: ``` const [isValid, setIsValid] = useState(false); <div hidden={isValid}>Please enter a valid value</div>; ``` 使用 isValid 來管理 UI 顯示邏輯。 # 在 useEffect 記得清乾淨每個事件監聽器 加過的事件監聽器,都要記得清乾淨: ``` const printHello = () => console.log("HELLO"); useEffect(() => { document.addEventListener("click", printHello); return () => document.removeEventListener("click", printHello); }); ``` # 避免重複開發,多寫通用元件 讓程式碼越乾淨越好。相似的東西可以寫通用元件。再根據 props 內容傳遞來處理相異處即可: ``` const Input=(props)=>{ const [inputValue, setInputValue]=useState(''); return( <label>{props.thing}</label> <input type='text' value={inputValue} onChange={(e)=>setInputValue(e.target.value)} /> ) } ``` 在其他元件中,就能這樣用: ``` <div> <Input thing="First Name" /> <Input thing="Second Name" /> </div> ``` # 檔案要分類一下 相關檔案可以分類成一個資料夾。 例如在 React 寫一個導覽列,那就可以開一個資料夾,相關的 .js 與 .css 檔案放裡面。 # 寫 functional components 為主 簡單顯示一些東西、沒用到 state 的話,那寫 functional components 比寫 class components 好。 如果你會寫 react hooks 的話,那就連 state 都完全不成問題。 # 養成編寫輔助函數的習慣 有時你在 React App 中會需要一些通用功能。 這種情況,可以開一個 `helper-functions.js` 檔案,在裡面寫輔助函數,就可以到處使用了。 ## 使用三元運算子代替 if/else if 使用 `if/else if` 語句會使程式碼變得龐大。使用三元運算子,就簡潔、清楚多了: ``` // Bad approach if (name === "Ali") { return 1; } else if (name === "Bilal") { return 2; } else { return 3; } // Good approach name === "Ali" ? 1 : name === "Bilal" ? 2 : 3; ``` # 新增 index.js 檔案,讓匯入元件更簡單 如果你在 actions 資料夾中有一個 index.js 檔案,當你想在元件中導入時,會像這樣: ``` import { actionName } from "src/redux/actions"; ``` actions 後面的 index.js 可以省略不寫,就不用這樣囉唆了: ``` import { actionName } from "src/redux/actions/index"; ``` # Destructuring of Props 物件屬性名稱可以拆出來,後面用起來比較方便。 假設你的元件有 `name`、`age` 和 `designation` 這些 props: ``` // Bad approach const Details = (props) => { return ( <div> <p>{props.name}</p> <p>{props.age}</p> <p>{props.designation}</p> </div> ); }; // Good approach const Details = ({ name, age, designation }) => { return ( <div> <p>{name}</p> <p>{age}</p> <p>{designation}</p> </div> ); }; ``` # 不要嘗試在同一函數中,去碰修改過的 state 變數 在一個函數中,如果你正在為一個狀態變數賦值,在同一個函數中,是拿不到新值的 ``` const Message = () => { const [message, setMessage] = useState("Hello World"); const changeMessage = (messageText) => { setMessage("Happy Learning"); console.log(message); // It will print Hello World on console }; return <div>{message}</div>; }; ``` # 使用 === 運算子代替 == 在比較兩個值時,嚴格檢查變數型別比較好: ``` "2" == 2 ? true : false; // true "2" === 2 ? true : false; // false ``` --- 以上 Best Practices 供您參考,祝福您不斷變強!

7個超特別的工程師作品集網頁:讓您大開眼界

工程師要怎麼設計作品集網頁呢?來看看這些人的網頁,或許能給你一些靈感! - 原文出處:https://dev.to/ruppysuppy/7-developer-portfolio-for-inspiration-4no7 # 1. Bruno Simon 如果您有試過開發 3D 網站,那你一定聽過 Bruno Simon。他是 Three.js Journey 的作者。從他的作品集就可看出為什麼他是這個領域的高手。 他的作品集網站,本身就是一個電玩遊戲。你可以在裡面控制吉普車,在 3D 世界裡面開車,然後可在裡面探索他的作品集世界。這網站可說是作品集網站的巔峰之作。 https://bruno-simon.com/ ![](https://imgur.com/kqpLGNH.png) # 2. Robby Leonardi 另一個超厲害的作品集網站!Robby Leonardi 的作品集是一個互動式的履歷表,往下滑就可以瀏覽他的作品、看到更多個人資訊。 http://www.rleonardi.com/interactive-resume/ ![](https://imgur.com/tZ6QJcX.png) # 3. Nitin Ranganath 一個有創意、又很新潮的網站!整個作品集頁面,看起來就像是 VS Code 編輯器! https://vscode-portfolio.vercel.app/ ![](https://imgur.com/4ePEkBe.png) # 4. Dejan Markovic 與傳統網頁設計的風格大相徑庭,但實際操作起來,卻非常順暢、巧妙! https://www.dejan.works/ ![](https://imgur.com/w0jf0i6.png) # 5. Hype4 極簡主義風格的網站,具有超級簡潔、專業的設計感。 https://hype4.com/ ![](https://imgur.com/FhT8j3c.png) # 6. Jacek Jeznach 利用微互動來提高留存率的絕佳範例。雖然網站上的廣告很煩人,但對於互動細節的設計,值得您親自見識一下! https://jacekjeznach.com/ ![](https://imgur.com/NR7v2KV.png) # 7. Tapajyoti Bose 最後一個範例讓我老王賣瓜一下!😜 我做了一個帶有滾動特效的單頁式作品集網站! https://tapajyoti-bose.vercel.app/ ![](https://imgur.com/GpmgsPC.png) --- 以上,希望大家覺得有趣、有啓發性!

寫出優雅 JavaScript 程式碼的 8 個簡單技巧

Javascript 是一個很棒的程式語言,但是,要寫出乾淨的 javascript 程式碼可不簡單,即便是資深工程師也一樣。 乾淨的 JavaScript 程式碼該長怎樣?它應該要: - 易於閱讀 - 易於測試 - 高效和高性能 以下是您可以使用的優質工具和技巧,可將您的 Javascript 功力提升到全新水平: - 原文出處:https://dev.to/alexomeyer/8-must-know-tips-for-writing-clean-code-with-javascript-i4 # 1. 對所有 api 請求和 JSON 方法使用 try catch 發出 api 請求來撈資料時,許多事情都可能出錯,因此必須注意這些情況。在處理 JSON 時,不要自動信任拿到的資料格式,請試著處理可能出乎意料的格式,來讓您的程式碼更健壯。 ![](https://imgur.com/KVzrdd0.png) # 2. 使用 linter (ESLint) linter 是一種靜態程式碼分析工具,可根據一組預定義的規則和配置檢查程式和風格錯誤。簡而言之,它將改進您的 Javascript/Typescript 程式碼品質,並讓風格更加一致。 # 3. 在編輯器中​追蹤 Javascript issues 保持 Javascript 程式庫簡潔的一個重要方式,是能夠輕易追蹤和查看程式碼本身的問題。在編輯器中追蹤 issues 允許工程師: - 全面了解技術債等更大的問題 - 查看每問題的上下文 - 減少上下文前後查看的頻率 - 持續地處理技術債 您可以使用各種工具來追蹤您的技術債,但最快速、最簡單的入門方法是使用與 Jira、Linear、Asana 和其他專案管理工具整合的 VSCode 或 JetBrains 的免費 Stepsize 外掛。 # 4.使用模板字符串 模板字符串讓您在保留格式的同時將值注入字符串,並且程式碼比字串運算更容易閱讀。 ![](https://imgur.com/ccagbwx.png) # 5. 需要搜尋字串時,使用正規表示式 正規表示式雖然乍看之下很深奧,但它是非常強大的字串解析工具,允許您建立複雜的模式來解決各種困難的字串配對情境。 # 6. 使用可選串連運算子 停止使用冗長的邏輯運算子,使用可選串連運算子來簡化您的程式碼。 ![](https://imgur.com/4TtpBdm.png) # 7.避免巢狀結構 巢狀結構絕對會增加程式碼的複雜度,也讓它更難閱讀、更難理解。如果深度超過兩層,請考慮重構,改成在根層就有條件回傳、使用更短小的區塊、並將巢狀邏輯抽像化成獨立的函式。 # 8. 替所有特殊程式碼寫註解,但不要讓它取代程式碼可讀性 有時需要針對特殊情境寫專門處理。替這段程式碼寫註解,解釋它的功能與上下文的由來,這對其他工程師幫助會很大。也能幫助未來重讀這段的自己。但讓程式碼本身就很易讀還是最優先,不要習慣用寫註解來偷懶!