自定義過濾器(Custom Filter)

by vivid 21. 八月 2019 07:56

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:
N190821002
出刊日期:2019/8/21

Vue可以允許你自定義過濾器(Custom Filter),針對文字來進行格式化的動作,或在{{}}符號中,進行字串插值處理,也可以搭配「v-bind」表達式(expression)來使用。自定義過濾器(Custom Filter)要使用「|」(pipe)符號,套用在JavaScript表達式後方。

自定義過濾器(Custom Filter)包含兩種類型:全域過濾器(Global Filter)與區域過濾器(Local Filter),在這篇文章中,我們將介紹如何定義、註冊以及使用過濾器。

全域過濾器(Global Filter)

在Vue之中,若想要自定義過濾器(Custom Filter),很簡單,只需要使用短短一行程式碼,直接叫用「Vue.filter」函式便可達成。參考以下範例程式碼,定義了兩個自定義過濾器(Custom Filter):

  • 「tofull」:可以將「0」到「9」的半型字串轉成全形。
  • 「tohalf」:可以將「0」到「9」的全型字串轉成半形。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
  <style>
  </style>
</head>

<body>
  <div id="divMsg">
    <h1> Custom Filters </h1>
    <div> {{ msg1 }} To Full : {{ msg1 | tofull}} </div>
    <div> {{ msg2 }} To Half : {{ msg2 | tohalf }} </div>
  </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>

    Vue.filter('tofull', function (value) {
      var t = "";
      for (var i = 0; i < value.length; i++) {
        var cc = value.charCodeAt(i);
        if (cc <= 57 && cc >= 48) {
          cc += 65248;
        }
        t = t + String.fromCharCode(cc);
      }
      return t;
    });
    Vue.filter('tohalf', function (value) {
      var t = "";
      for (var i = 0; i < value.length; i++) {
        var cc = value.charCodeAt(i);
        if (cc <= 65305 && cc >= 65296) {
          cc -= 65248;
        }
        t = t + String.fromCharCode(cc);
      }
      return t;
    });
    var vm = new Vue({
      el: '#divMsg',
      data: {
        msg1: '0123456789',
        msg2: '0123456789'
      }
    });
  </script>
</body>

</html>

我們使用「Vue.filter」函式將這兩個自定義過濾器(Custom Filter)註冊到全域(Global)區段。「Vue.filter」函式第二個參數是一個函式,會接收表達式傳遞過來的值,即範例中的「msg1」與「msg2」。

這個範例的執行結果參考如下:

clip_image002

圖 1:套用轉半型與轉全型的過濾器。

為了方便管理與在其它專案重複使用,非常建議將過濾器的程式碼放在外部檔案,每一個過濾器的程式碼儲存成一個個別的檔案,並統一放在「filters」資料夾下,這樣在叫用「Vue.filter」函式時,就需要利用「require」函式來載入外部過濾器的程式碼。

 

區域過濾器(Local Filter)

我們也可以將過濾器註冊為區域過濾器(Local Filter),以在一個網頁或一個組件(Component)之中使用。例如改寫上例轉半型與轉全型的過濾器程式碼如下,改為區域過濾器(Local Filter)版本:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
  <style>
  </style>
</head>

<body>
  <div id="divMsg">
    <h1> Custom Filters </h1>
    <div> {{ msg1 }} To Full : {{ msg1 | tofull}} </div>
    <div> {{ msg2 }} To Half : {{ msg2 | tohalf }} </div>
  </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>

    var vm = new Vue({
      el: '#divMsg',
      data: {
        msg1: '0123456789',
        msg2: '0123456789'
      },
      filters: {
        tofull: function (value) {
          var t = "";
          for (var i = 0; i < value.length; i++) {
            var cc = value.charCodeAt(i);
            if (cc <= 57 && cc >= 48) {
              cc += 65248;
            }
            t = t + String.fromCharCode(cc);
          }
          return t;
        },
        tohalf: function (value) {
          var t = "";
          for (var i = 0; i < value.length; i++) {
            var cc = value.charCodeAt(i);
            if (cc <= 65305 && cc >= 65296) {
              cc -= 65248;
            }
            t = t + String.fromCharCode(cc);
          }
          return t;
        }
      }
    });
  </script>
</body>

</html>

這個範例的執行結果和上圖一樣。

數值轉換貨幣格式過濾器

我們來看另外一個例子,以下範例程式碼中,定義一個「tocurrency」過濾器,(expression),將數值資料轉換成包含貨弊符號與千分位的格式:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
  <style>
  </style>
</head>
<body>
  <div id="divMsg">
    <h1> Custom Filters </h1>
    <div> {{ num }} To Currency : {{ num | tocurrency}} </div>
  </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    Vue.filter('tocurrency', function (value) {
      return value.toLocaleString("zh", { style: 'currency', currency: "TWD" });
    });
    var vm = new Vue({
      el: '#divMsg',
      data: {
        num: 123456789
      }
    });
  </script>
</body>

</html>

 

「toLocaleString」第一個參數為語系(locale),第二個參數是一個選擇性的options物件,可以設定格式與貨幣符號。這個範例程式的執行結果參考如下:

clip_image004

圖 2:轉換貨幣格式。

貨幣符號的代碼可以參考以下網站:https://en.wikipedia.org/wiki/ISO_4217

搭配「v-bind」表達式(expression)

過濾器也可以搭配「v-bind」表達式(expression)來使用,可以針對HTML項目的Attribute來做處理。讓我們改上個將數值資料轉換成包含貨弊符號與千分位的格式之過濾器範例如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
  <style>
  </style>
</head>

<body>
  <div id="divMsg">
    <h1> Custom Filters </h1>
    <div v-bind:data-num=" num| tocurrency">{{num | tocurrency }}</div>
    <div :data-num=" num| tocurrency">{{num | tocurrency}}</div>
  </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    Vue.filter('tocurrency', function (value) {
      return value.toLocaleString("zh", { style: 'currency', currency: "TWD" });
    });
    var vm = new Vue({
      el: '#divMsg',
      data: {
        num: 123456789
      }
    });
  </script>
</body>

</html>

 

這個範例程式的執行結果參考如下,網頁執行後,使用瀏覽器的除錯畫面進行觀察,便可以看到HTML Attribute格式化完的結果:

clip_image006

圖 3:使用「v-bind」表達式。

串接過濾器

過濾器可以利用「|」號串接在一起使用,語法如下:

{{ 原始資料 | 過濾器1 | 過濾器2 | 過濾器n}}

過濾器1將會接收到原始資料,而過濾器2將會接收到過濾器1處理完的結果,依此類推。參考以下範例程式碼,利用「tofull」過濾器將「0123456789」轉換成「0123456789」的字串,然後再利用「tohalf」過濾器將「0123456789」轉換回「0123456789」:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
  <style>
  </style>
</head>

<body>
  <div id="divMsg">
    <h1> Custom Filters </h1>
    <div> Original : {{ msg }} </div>
    <div> {{ msg }} To Full : {{ msg | tofull}} </div>
    <div> {{ msg }} To Full and to Half : {{ msg | tofull | tohalf }} </div>
  </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>

    Vue.filter('tofull', function (value) {
      var t = "";
      for (var i = 0; i < value.length; i++) {
        var cc = value.charCodeAt(i);
        if (cc <= 57 && cc >= 48) {
          cc += 65248;
        }
        t = t + String.fromCharCode(cc);
      }
      return t;
    });
    Vue.filter('tohalf', function (value) {
      var t = "";
      for (var i = 0; i < value.length; i++) {
        var cc = value.charCodeAt(i);
        if (cc <= 65305 && cc >= 65296) {
          cc -= 65248;
        }
        t = t + String.fromCharCode(cc);
      }
      return t;
    });
    var vm = new Vue({
      el: '#divMsg',
      data: {
        msg: '0123456789'
      }
    });
  </script>
</body>

</html>

 

這個範例程式的執行結果參考如下:

clip_image008

圖 4:串接過濾器。

而以下的範例程式碼,則是將「0123456789」全型字串,轉換成「0123456789」半型字串,再利用「tocurrency」格式化成包含貨幣格式的字串。因為傳入「tocurrency」過濾器的值(0123456789)是字串型別,因此要先轉換成數值型別,才能叫用「toLocaleString」函式將其格式化:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
  <style>
  </style>
</head>

<body>
  <div id="divMsg">
    <h1> Custom Filters </h1>
    <div> Original : {{ msg }} </div>
    <div> {{ msg }} To Half : {{ msg | tohalf }} </div>
    <div> {{ msg }} To Half and to Currency : {{ msg | tohalf | tocurrency }} </div>
  </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>

    Vue.filter('tocurrency', function (value) {
      console.log(typeof value) // string
      return (+value).toLocaleString("zh", { style: 'currency', currency: "TWD" });
    });

    Vue.filter('tohalf', function (value) {
      var t = "";
      for (var i = 0; i < value.length; i++) {
        var cc = value.charCodeAt(i);
        if (cc <= 65305 && cc >= 65296) {
          cc -= 65248;
        }
        t = t + String.fromCharCode(cc);
      }
      return t;
    });
    var vm = new Vue({
      el: '#divMsg',
      data: {
        msg: '0123456789'
      }
    });
  </script>
</body>

</html>

這個範例程式的執行結果參考如下:

clip_image010

圖 5:串接過濾器。

傳遞參數

過濾器基本上就是JavaScript中的函式,因此也可以傳遞參數(arguments)。在以下的範例程式碼中,「tocurrency」是一個函式,接收3個參數,「num」變數的值將會傳入「tocurrency」函式的第一個參數;而「locales」的值將會傳入「tocurrency」函式的第二個參數「loc」;「currency」的值將會傳入「tocurrency」函式的第二個參數「cur」;

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
  <style>
  </style>
</head>

<body>
  <div id="divMsg">
    <h1> Custom Filters </h1>
    <div> {{ num }} To Currency TWD: {{ num | tocurrency( locales, currency )}} </div>
    <div> {{ num }} To Currency JPY: {{ num | tocurrency( locales2, currency2 )}} </div>
  </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    Vue.filter('tocurrency', function (value, loc, cur) {
      return value.toLocaleString(loc, { style: 'currency', currency: cur });
    });
    var vm = new Vue({
      el: '#divMsg',
      data: {
        num: 123456789,
        locales: 'zh',
        currency: "TWD",
        locales2: 'ja',
        currency2: "JPY"
      }
    });
  </script>
</body>

</html>

 

這個範例程式的執行結果參考如下:

clip_image012

圖 6:參數傳遞。

Tags:

.NET Magazine國際中文電子雜誌 | JavaScript | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List