2024年4月24日 星期三

tailwindcss3換皮要怎麼做呢

前言

早在多年之前,我看過奶綠大大一篇網誌提到,tailwindcss可以做到更換語系並伴隨修改文字大小,且可以在10分鐘搞定,原理是靠檢測body上的一些property,然後對tailwindcss的ultility進行覆寫,架設text-lg是1rem,當遇到body[lang="en"]時text-lg就會變成0.75rem,這樣的效果。然而~我怎麼樣都找不到這篇文章,正確來說是找到了,但是點進去看看不到關鍵字(應該是基於某些原因部分內容被刪掉了)。因此只好自己開始摸索

原本想說只是檢測上層class應該是不難做到,結果官網看來看去也沒半點消息,只有一個darkMode的文件應該可以做到我要的需求。但這樣需要在每個要變換顏色的class加上不同膚色的前綴,例如text-primary, dark:text-primary, yellow:text-primary...,不是這樣開發效能非常不佳,因此列入備案,繼續尋找答案。

在苦思無果後上網發文,網路大神果然很熱心的回覆了,除了上述darkMode的方法,還另外得到了三個解法,記錄一下給大家參考

方法一,原生變數解法

// src/main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

.main {
--theme-main: #D53737
}
.test {
--theme-main: #007712
}

// tailwind.config.js
/** @type {import('tailwindcss').Config} */

export default {
content: ["./index.html", "./src/**/*.{vue,js,ts}"],
theme: {
extend: {
colors: {
"theme-main": "var(--theme-main)",
},
spacing: {
mobile: "600px",
},
},
},
plugins: [],
}

// src/App.vue
div(class="max-w-mobile mx-auto my-0 h-full", :class="'test'") // or main
div(class="bg-theme-main") what is my bg color

第二種解法也相當容易,使用tw-colors的tailwindcss套件

// yarn add -D tw-colors
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
const { createThemes } = require("tw-colors")

export default {
content: ["./index.html", "./src/**/*.{vue,js,ts}"],
theme: {
extend: {
spacing: {
mobile: "600px",
},
},
},
plugins: [
createThemes({
main: {
"theme-main": "#D53737",
},
test: {
"theme-main": "#007712",
},
}),
],
}

架構方法類似,使用方法一樣,我就不多做介紹

最後介紹第三種,同樣是使用套件,叫daisyUI

// yarn add -D daisyui@latest
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
const { createThemes } = require("tw-colors")

export default {
daisyui: {
themes: ["light", "dark", {
"main": {
"theme-main": "#a991f7",
"primary": "#a991f7",
"secondary": "#f6d860",
"accent": "#37cdbe",
"neutral": "#3d4451",
"base-100": "#ffffff",
},
}],
},
  plugins: [require("daisyui")],
}

<div data-theme="main">
This div will always use light theme
<span class="text-theme-main">This span will always use retro theme!</span>
</div>

至於還有一些奇怪招數,原生土法煉鋼法及NODE_ENV修改大法

.main {
text-theme-main: #b42222;
bg-theme-main: #b42222;
......
};
.test {
text-theme-main: #007712;
bg-theme-main: #007712;
......
}


/** @type {import('tailwindcss').Config} */
const { createThemes } = require("tw-colors")

export default {
content: ["./index.html", "./src/**/*.{vue,js,ts}"],
theme: {
extend: {
     colors: {
       "theme-main": NODE_ENV == "prod" ? "#D53737" : "#007712",
      },
spacing: {
mobile: "600px",
},
},
},
}


恩.....我就不多解釋了

最終我選擇了tw-colors套件解法,原因就是夠簡單,當然靠css原生變數那招也很吸引我,且不用另外裝套件,但唯一缺點就是要分兩個檔案維護,開發上不夠直覺。至於daisyUI,看官網這應該是個滿強大的套件,但很多東西應該都制定好了,但感覺有點重,應該是適合當後台開發使用,前台設計師應該不會讓我這麼輕易不照他給的色碼開發,所以還是選用最簡單的tw-colors,好了,又完美解決了一次事件,祝大家有個美好的一天。

好文分享,如果你docker desktop跑得很慢的話,可以考慮OrbStack

參考網站 

小記

雖然我自從換成m2 pro之後就沒有這樣的困擾了,不過還是值得記錄一下

2024年4月18日 星期四

typescript中的map,How to get types from arrays

前言

我們都知道要把自定義物件轉成型別在ts裡面要使用typeof,

const config = {
"self": {
"method": "get",
"uri": "self"
},
"login": {
"method": "post",
"uri": "backend/login"
},
"logout": {
"method": "get",
"uri": "logout"
}
}
const keys = keyof type config // "self" | "login" | "logout"

但假設今天是一個陣列,例如

const datas = [
{
"key": "collect",
"value": "Collect"
},
{
"key": "ffc",
"value": "FFC"
},{
"key": "switch",
"value": "Switch"
},
]

那我要把所有的key取出來變成類別該怎麼寫呢,總不能真的用js的map吧,實際上就是,你上網找ts map也只會找到集合的Map,所以該怎麼寫呢,我們直接看code

let key = (typeof datas)[number]["key"]

沒錯,就是這麼簡單,最後你就會發現key的類別是string.....那我幹嘛這麼大費周章,寫這麽多字只為了宣告string!!

先別急,我們要再做一點調整,不過不是類別宣告,而是資料

const datas = [
{
key: "collect",
value: "Collect",
},
{
key: "ffc",
value: "FFC",
},
{
key: "switch",
value: "Switch",
},
] as const
let key = (typeof datas)[number]["key"] // "collect" | "ffc" | "switch"

加上一個 as const資料就會被定型,在取用key時就可以取道固定的值了。

不過const資料之後,或許還是會產生其他的問題,例如realonly {...}不符合Rcord<string, any>之類的,這些問題......改天再說吧!以上,下班!

參考網站


2024年4月17日 星期三

vue要產生一個component在body要怎麼做

前言

相信很多小夥伴跟我有相同的疑問,或是使用過modal這個套件,會在body增加一個可控制的component,我一直以為是createElement相關的方法去做到的,一直到今天.......

今天在線上抗到一個component,來人我們直接上範例

<teleport to="body">
<p> 移動我到 body </p>
</teleport>

最終結果就會是

<body>
<div id="app">......</div>
<p> 移動我到 body </p>
</body>

關於teleport有兩個屬性to跟disabled,to就是要移到哪裡去,支援css選擇器,disabled就是有沒有生肖,亦或是留在原地

以上簡短分享

2024年4月16日 星期二

在vue裡面寫pug真的有這麼恐怖嗎?

前言

許久之前有開過一個vue3專案,template我使用pug來寫,基本上用得還算順利。除了一開始不會自動排版,但也靠vetur解決了(雖然vetur那時跟volar打架,但後來也還算完美落幕)。一直到這兩天我從心起了一個專案,憑藉對ts及vue的熟悉,我突然感覺到不太對勁:不光是template幾乎不會報錯、ts不會自動跳出提示,連格式化也失靈了。因此我開始上網求助

網路大神果然不會讓我失望,清一色都是叫我儘早放棄,把pug說的要多糟有多糟,支援要多差有多差。



洨編連團隊的道歉信都寫好了,準備要把所有template改回html,最終看到圖片中那則留言,想說斯馬當活馬醫吧。再試一回,結果真讓我試出來了。以下來記錄一下

備註一下,以下小編都是使用vscode及相關套件進行處理

首先是format的部分(prettiers extension請先安裝好)

yarn add -D prettier @prettier/plugin-pug
// .prettierrc
{
"semi": false,
"trailingComma": "es5",
"singleQuote": false,
"printWidth": 150,
"tabWidth": 2,
"pugClassNotation": "attribute",
"pugExplicitDiv": true,
"pugSortAttributes": "asc",
"pugSortAttributesBeginning": [],
"pugSortAttributesEnd": [
"v-for",
"^:",
"^@",
"^v-"
],
"plugins": ["@prettier/plugin-pug"]
}

這樣就可以使用prettier進行format了(我還以為prettier什麼都支援,原來需要外掛),後面那些設定大家可以自行調整,洨編是依照個人喜好設定

再來是vscode typescript compiler的部分

yarn add -D @vue/language-plugin-pug
// tsconfig.json
{
  "vueCompilerOptions": {
"plugins": ["@vue/language-plugin-pug"]
}
}

這樣類別及型別錯誤什麼的就可以正常辨識了。

不過網路大神講得這麼恐怖,或許其中還有什麼未知的問題等待我去挖掘,總之我提出的三個問題暫時是解決了,至於未來.....的事交給未來的我去解決吧!

又過了驚險的一天,收工下班!