前端開發
用 moment.js 搭配 Vue 2 全域 filter 做日期格式化
記錄安裝 moment.js、註冊成 Vue 2 全域 filter,在模板裡用管線符號格式化日期的做法,包含處理 UTC 時區轉換的版本,並記下這個做法的兩個代價:套件體積與物件可變性。
W
日期格式要在很多地方重複用到,整理成 Vue 2 的全域 filter,模板裡用管線符號直接套用。
安裝
npm install moment
註冊成全域 filter
// plugins/filter.js
import Vue from 'vue';
import moment from 'moment';
Vue.filter('dateFormat', (value, format = 'YYYY-MM-DD') => {
const datetime = moment(value);
return datetime.format(format);
});
Vue.filter('dateFormatFromUTC', (value, format = 'YYYY-MM-DD') => {
const utc = moment.tz(value, 'UTC');
const timezone = moment.tz.guess();
return utc.clone().tz(timezone).format(format);
});
nuxt.config.js 註冊這支 plugin:
export default {
plugins: [{ src: '~plugins/filter', ssr: false }],
};
使用方式
在模板裡用管線符號 | 串接 filter:
<span>{{ data.item.paid_date | dateFormat('YYYY.MM.DD') }}</span>
在 methods 裡也能直接呼叫 moment():
this.tempCoupon.due_date = moment(this.tempCoupon.due_date).format('YYYY-MM-DD');
這個做法的代價
Moment.js 的兩個設計選擇,在它剛推出的年代不是問題,規模用大之後會慢慢感覺到包袱:體積龐大(連同常用的 locale 動輒 200KB 以上);物件是可變的(moment().add(1, 'day') 會直接修改原本的物件,多處共用同一個 moment 實例時容易出現意外的副作用)。
Vue 的全域 filter 語法本身也有限制——filter 能做的事,computed 或一般方法幾乎都能做,多維護一套語意相近的機制,長期看來是重複的心智負擔。
這兩件事後來都有了新的做法,整理在《day.js 搭配 Vue 3 的日期格式化》。