iT邦幫忙

2021 iThome 鐵人賽

DAY 7
0
Modern Web

前端工程師在工作中的各種實戰技能 (Vue 3)系列 第 7

[Day07] Vue i18n - Datetime Formatting

在本地化 (localize) 專案時,我們可能會遇到需要處理日期時間顯示的問題,因為日期時間的顯示方式可能會因為每個國家而有所不同,例如:

<p>Apr 19, 2017</p>
<p>2017年4月19日(水) 午前2:19</p>

所以今天我們要來分享的就是 vue i18n 可以幫我們達到這件事的 Datetime Formatting,事實上 Datetime Formatting 背後的實踐方式是透過原生 JS 的 Intl.DateTimeFormat 來做到的,所以 Datetime Formatting 所擁有的屬性基本上和 Intl.DateTimeFormat 是一樣的。

屬性選項

這裡我們只針對常使用的屬性做介紹,詳細完整的可參考 Intl.DateTimeFormat() constructor

dateStyle 要使用的日期格式樣式

  • long - September 9, 2021
  • medium - Sep 9, 2021
  • short - 9/9/21

timeStyle 要使用的時間格式樣式

  • full - at 5:43:38 AM Taipei Standard Time
  • long - at 5:43:38 AM GMT+8
  • medium - 5:43:38 AM
  • short - 5:43 AM

timeZone 要使用的時區,例如 Asia/Taipei ,完整的時區名稱可以參考 List of tz database time zones

hour12 是否使用 12 小時制,反之則為 24 小時制。

weekday 工作日的顯示格式

  • long - Thursday
  • short - Thu
  • narrow - T

year 年份的顯示格式

  • numeric - 2021
  • 2-digit - 21

month 月份的顯示格式

  • numeric - 9
  • 2-digit - 09
  • long - September
  • short - Sep
  • narrow - S

day 日期的顯示格式

  • numeric - 9
  • 2-digit - 09

hour 小時的顯示格式

  • numeric - 9
  • 2-digit - 09

minute 分鐘的顯示格式,選項和 hour 相同

second 秒鐘的顯示格式,選項和 hour 相同

需要特別注意的是,如果設定了 dateStyle 或是 timeStyle 就不能再設定 weekday, year, month, day, hour, minute 和 second ,但兩者是可以同時設定的。

基本用法

datetime formatting 所使用的 translation api 是 $d(value, key, locale)

  • value - 要本地化的數值。
  • key - 指的是 en 物件下一層自己的 key,如下面程式碼中的 short 或 long。
  • locale - 指定要用哪一個語系來本地化,預設會是全局的 locale 值。
export default createI18n({
  ...,
  datetimeFormats: {
	en: {
	  short: {
	    year: 'numeric',
	    month: 'short',
	    day: 'numeric'
	  },
	  long: {
	    year: 'numeric',
	    month: 'short',
	    day: 'numeric',
	    weekday: 'short',
	    hour: 'numeric',
	    minute: 'numeric'
	  }
	}
}})

所以在 template 的寫法會是:

<p>{{ $d(new Date(), 'short') }}</p>
<p>{{ $d(new Date(), 'long') }}</p>

得到的結果是:

<p>Sep 9, 2021</p>
<p>Thu, Sep 9, 2021, 6:28 AM</p>

Custom Formatting

由於 $d 會直接回傳格式化的字串結果,我們只能作為一整體去使用,但有的時候我們會需要針對其中一部分去設定不同的樣式,所以為了應對這種情況 vue i18n 有提供我們 NumberFormat 組件 (i18n-d) 來達到這件事。

i18n-d 的基本用法如下。 (此時得到的結果和用 $d 的結果一樣)

<i18n-d tag="span" :value="new Date()" format="long" locale="en">

i18n-d 有四個 props :

tag 選擇根節點的 HTML tag。

value 要本地化的日期時間值。

format 選用哪一個定義好的格式的 key (同 $d(value, key) 中的 key)。

locale 指定要用哪一個語系來本地化,預設會是全局的 locale 值。

如果想要個別控制每一個部分做到上面圖示中的樣子,我們要透過 slots 的方式,像是:

<i18n-d tag="span" :value="new Date()" format="long">
  <template #year="props">
    <span class="year">{{ props.year }}</span>
  </template>
  <template #month="props">
    <span class="month">{{ props.month }}</span>
  </template>
  <template #day="props">
    <span class="day">{{ props.day }}</span>
  </template>
  <template #weekday="props">
    <span class="weekday">{{ props.weekday }}</span>
  </template>
  <template #hour="props">
    <span class="hour">{{ props.hour }}</span>
  </template>
  <template #minute="props">
    <span class="minute">{{ props.minute }}</span>
  </template>
  <template #literal="props">
    <span class="literal">{{ props.literal }}</span>
  </template>
  <template #dayPeriod="props">
    <span class="dayPeriod">{{ props.dayPeriod }}</span>
  </template>
</i18n-d>

這樣得到的結果會是

// Thu, Sep 9, 2021, 7:28 AM
<span >
  <span class="weekday">Thu</span>
  <span class="literal">, </span>
  <span class="month">Sep</span>
  <span class="literal"> </span>
  <span class="day">9</span>
  <span class="literal">, </span>
  <span class="year">2021</span>
  <span class="literal">, </span>
  <span class="hour">7</span>
  <span class="literal">:</span>
  <span class="minute">21</span>
  <span class="literal"> </span>
  <span class="dayPeriod">AM</span>
</span>

參考資料


今天的分享就到這邊,如果大家對我分享的內容有興趣歡迎點擊追蹤 & 訂閱系列文章,如果對內容有任何疑問,或是文章內容有錯誤,都非常歡迎留言討論或指教的!

明天要來分享的是新的主題 Storybook,那我們明天見!


上一篇
[Day06] Vue i18n - Number Formatting (Currency 貨幣)
下一篇
[Day08] Storybook - 基本介紹 & 安裝
系列文
前端工程師在工作中的各種實戰技能 (Vue 3)30

1 則留言

0
TD
iT邦新手 5 級 ‧ 2021-09-23 16:48:38

除了 shortlong 這些固定的 key 之外,我們可以自定義不同的 key 來當作不同的 formatting 組合嗎?

Mia Yang iT邦新手 5 級 ‧ 2021-09-24 01:02:04 檢舉

TD 不是固定的 key 是我們可以自由定義的!

TD iT邦新手 5 級 ‧ 2021-09-24 09:16:47 檢舉

原來如此,感謝!

我要留言

立即登入留言