在本地化 (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
要使用的日期格式樣式
timeStyle
要使用的時間格式樣式
timeZone
要使用的時區,例如 Asia/Taipei ,完整的時區名稱可以參考 List of tz database time zones。
hour12
是否使用 12 小時制,反之則為 24 小時制。
weekday
工作日的顯示格式
year
年份的顯示格式
month
月份的顯示格式
day
日期的顯示格式
hour
小時的顯示格式
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>
由於 $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,那我們明天見!
除了 short
和 long
這些固定的 key 之外,我們可以自定義不同的 key 來當作不同的 formatting 組合嗎?
TD 不是固定的 key 是我們可以自由定義的!
原來如此,感謝!