「19800円」を「19,800円」にしたいとかいうこと、よくありますよね。
3桁ごとのカンマ区切りにしたいと。
PHPであればnumber_formatという関数がビルトインで用意されていますが、
Vue.jsのテンプレートでこれを行うには自前のフィルタを作成する必要があります。
(1.x系にはあったみたいですが、2.x系で撤廃されてしまったようです)
このフィルタの作り方・使い方をご紹介します。
たとえば商品一覧画面の価格表示
味もそっけもなくて恐縮なんですが、たとえばこういう商品一覧がいい例です。
この画面のVue.jsテンプレートは以下のようになっています。
<template> <div> <p>商品一覧</p> <router-link tag="button" v-bind:to="{ path : '/products/edit/'}">新規登録</router-link> <ul v-for="item in items"> <li> {{item.name}} </li> <li> {{item.price}}円 </li> <router-link tag="button" v-bind:to="{ path : '/products/edit/' + item.id}">編集</router-link> <button v-on:click="removeItem(item)">削除</button> </ul> </div> </template>
{{item.price}}円 が価格表示部分。何もしていないのでitem.priceの中身がそのまま表示されます。
ここに、新しくフィルタをつくって適用します。
Vue.jsで独自フィルタを登録する方法
Vue.jsのフィルタは、コンポーネントごとに登録するかグローバルに登録するか選択できるのですが、今回はどこでも使うようなフィルタなのでグローバルに登録します。
書き方は以下のとおり。
Vue.filter('number_format', function (value) { if (!value.match(/^\d+$/)) { return value; } let formatter = new Intl.NumberFormat('ja-JP'); return formatter.format(value); });
Vue.filter() がフィルタ登録関数です。
第一引数にフィルタ名を、第二引数にfunctionを入れます。
functionの引数(value)にフィルタをかける対象の文字列だったり数値だったりが入ってくるので、その値を加工してreturnするという仕組みになっています。
functionではまず数値として扱えるかを正規表現でチェック。
数値扱いでOKであればフィルタ処理をかけて返します。
3桁区切り処理自体は Intl.NumberFormat というのを使う方法を採用しました。
昔は正規表現の置換とかでやってましたね。
そして、これをどこに書くかですが、とりあえずapp.jsに書けばOKです。
require('./bootstrap'); window.Vue = require('vue'); import http from './services/http'; import router from './router'; Vue.use(require('vuex')); Vue.filter('number_format', function (value) { if (!value.match(/^\d+$/)) { return value; } let formatter = new Intl.NumberFormat('ja-JP'); return formatter.format(value); }); const store = require('./store/').default; const app = new Vue({ router, store, created() { http.init(); }, el: '#app' });
余計な文もそのまま入っててちょっと見づらいかもですが、こういう感じです。
window.Vue = require(‘vue’); の後であればどこでも大丈夫です。
テンプレート側でフィルタ適用
これでnumber_formatという名前のフィルタがグローバルに登録されたので、どこのテンプレートからでも自由に使えます。
さっきの
{{item.price}}円
この記述を
{{item.price | number_format}}円
このようにパイプ構文でフィルタを適用してあげます。
結果
ばっちり3桁区切りになりました。
フィルタを外部ファイルにまとめる場合
Vue.filter('number_format', function (value) { if (!value.match(/^\d+$/)) { return value; } let formatter = new Intl.NumberFormat('ja-JP'); return formatter.format(value); });
この部分をまるっと別ファイル(resources/assets/js/filter.js)にして、
require('./filter');
app.jsのほうはこのように、そのfilter.jsをrequireする形に置き換えてしまえばOKです。