PM2 常用指令筆記

以檔名啟動程式
$ pm2 start 檔名 --name app_name

以指令啟動程式
$ pm2 start '指令' --name app_name
指令因為有空白,要用引號包起來,或者也可以把指令做成sh檔,就可以以檔名啟動的方式來做。

觀察檔案變動重啟程式
$ pm2 start 檔名 --watch

顯示所有執行中或已停止的程序列表
$ pm2 ls

停止並移除程序
$ pm2 delete 'id or name'

停止/重啟程序
$ pm2 stop 'id or name'
$ pm2 restart 'id or name'

在CSS GRID Layout實現colspan, rowspan

善用 display: grid 來處理排版真的非常方便,不但可以簡化html巢狀結構,在處理RWD的時候,也增加了更多排版的彈性跟可能性。例如可以用 grid-template-areas 來隨意調整排版的位置順序等等。

說到 colspan 的話,上述提到的 grid-template-areas 也可以輕鬆達到這個需求,例如以下範例:

<style>
  .grid {
    display: grid;
    grid-template-areas: "col-1 col-2 col-3 col-4" "col-5 col-5 col-5 col-4";
  }

  .col-1 {
    grid-area: col-1;
  }
  .col-2 {
    grid-area: col-2;
  }
  .col-3 {
    grid-area: col-3;
  }
  .col-4 {
    grid-area: col-4;
  }
  .col-5 {
    grid-area: col-5;
  }
</style>

<div class="grid">
  <div class="col-1">1</div>
  <div class="col-2">2</div>
  <div class="col-3">3</div>
  <div class="col-4">4</div>
  <div class="col-5">5</div>
</div>

可以得到以下結果:

但這個作法只限於在父層,並且內部的數量是固定的。也就是說如果今天是一個無法預估數量的列表型態,就無法用這個做法。

假設現在有一個商品列表,排列為左右兩欄的方式向下排,商品數量不固定,並且在中間需要插入一則廣告,廣告寬度為左右兩欄的寬度,那該怎麼辦呢?

我們可以在子層,也就是設為 grid 的內層,使用 grid-column 這個 property,例如以下範例:

<style>
  .grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }

  .ad {
    grid-column: 1 / span 2;
  }
</style>

<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div class="ad">ad</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
  <div>10</div>
  <div>11</div>
  <div>12</div>
</div>

可以得到以下結果:

所以我們只要將廣告安排在奇數欄,就可以順利呈現。若廣告不慎安插在複數欄時,也會直接在下一列呈現,不會破壞 grid 欄數設定,相當方便。

grid-column 是 grid-column-start 跟 grid-column-end 前後值以斜線分隔的簡寫方式,所以也可以寫成:

.ad {
  grid-column-start: 1;
  grid-column-end: span 2;
}

span 代表的是從start的欄位開始,要合併到的欄位的末端,所以end也可以寫成 3,變成 grid-column: 1 / 3,會得到一樣的結果。

關於CSS權重的筆記

關於權重的計算,在W3C的網頁上的介紹是:

A selector’s specificity is calculated as follows

  • count the number of ID selectors in the selector (= a)
  • count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)
  • count the number of type selectors and pseudo-elements in the selector (= c)
  • ignore the universal selector

翻譯一下

  • ID selector的數量為a
  • class, attr, 偽類別為b
  • tag跟偽元素為c
  • 星號直接無視

範例

*               /* a=0 b=0 c=0 -> specificity = 0-0-0 */
LI              /* a=0 b=0 c=1 -> specificity = 0-0-1 */
UL LI           /* a=0 b=0 c=2 -> specificity = 0-0-2 */
UL OL+LI        /* a=0 b=0 c=3 -> specificity = 0-0-3 */
H1 + *[REL=up]  /* a=0 b=1 c=1 -> specificity = 0-1-1 */
UL OL LI.red    /* a=0 b=1 c=3 -> specificity = 0-1-3 */
LI.red.level    /* a=0 b=2 c=1 -> specificity = 0-2-1 */
#x34y           /* a=1 b=0 c=0 -> specificity = 1-0-0 */
#s12:not(FOO)   /* a=1 b=0 c=1 -> specificity = 1-0-1 */

計算結果的比較方式

從a比較到c,且abc各自獨立,無法進位。inline style 跟 !important 則不在計算範圍中。

inline style 跟 !important 的權重

inline style 的權重大於所有樣式表內容。!important 則是在權重計算時給予最優先權,權重越大的 !important 也會覆寫權重小的 !important。也因此,在inline style中加上 !important,也會覆寫在樣式表中加的 !important,例如:

css

.class1 {
  color: #f00 !important;
}

html

<div class="class1" style="color: #0f0 !important>
  我會是綠色
</div>

CSS :is, :where Selector

:is() 跟 :where() 是什麼?

常常在一些情況之下,css selector有可能會需要寫很長,尤其是剛開始在寫sass, scss時,巢狀寫的很開心,結果compile出來的東西有可能會像下面這樣:

.container .class1 article,
.container .class2 article,
.container .class3 article,
.container .class4 article {
  color: #f00;
}

而 :is() 跟 :where() 就是用來解決這個問題。在is:() or :where() 中可以帶入逗點分格的selector,讓原本多行且重複的結構簡化為一行:

.container :is(.class1, .class2, .class3, .class4) article {
  color: #f00;
}

/* or */

.container :where(.class1, .class2, .class3, .class4) article {
  color: #f00;
}

:is() 跟 :where() 的不同

基本上是完全一樣,唯一的差異是 :where() 的權重是0,因此可以被輕易複寫。

Nuxt asyncData與fetch的不同

首先是this,fetch 的 this 指的就是component本身,asyncData 的this是undefined…

fetch可以被component本身用 this.$fetch() 再次呼叫,而asyncData不行

顯示的效果也有差。server-side render感覺不出來,不過在client side render時,就有明顯差異。使用asyncData的話,會先取資料,取完資料才換頁。使用fetch的話,取資料前就會先換頁,等到資料取完後,才會填入資料。所以使用fetch的話,體驗會比較像Facebook App在loadiing那樣,勢必要處理當頁面沒有任何東西時,要顯示的替代內容。例如替代標題或內文的灰色色條,或是loading中的icon。

簡單來說,我覺得要做得比較像app的話,應該是用fetch。如果要像一般傳統頁面的感覺,也不需要重複fetch資料的情況,用asyncData應該就可以了。