# 过滤器

过滤器是一种在模板中处理数据的便捷方式,而且经常会在其它模板语言中见到。它们特别适合对字符串和数字进行简单的显示变化。例如,将字符串变为正确的大小写格式,或者用更容易阅读的格式显示数字。

过滤器『只可以』在插值表达式和 v-bind 指令中使用。

<div id="app" v-cloak>
  <p>商品一花费了:¥{{ (productOneCost / 100).toFixed(2) }}</p>
  <p>商品二花费了:¥{{ (productTwoCost / 100).toFixed(2) }}</p>
  <p>商品三花费了:¥{{ (productThreeCost / 100).toFixed(2) }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
  const vm = new Vue({
    el: '#app',
    data() {
      return {
        productOneCost: 10086,
        productTwoCost: 365,
        productThreeCost: 9527
      }
    }
  });
</script>

这段代码可以正常工作,但是存在很多重复:对于每一项商品我们都要进行下面的计算,将价格单位从分转换为元、格式化为两位小数,同时添加货币符号。

我们可以把这一逻辑拆分为过滤器:

<div id="app" v-cloak>
  <p>商品一花费了:{{ productOneCost | formatCost }}</p>
  <p>商品二花费了:{{ productTwoCost | formatCost }}</p>
  <p>商品三花费了:{{ productThreeCost | formatCost }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
  const vm = new Vue({
    el: '#app',
    data() {
      return {
        productOneCost: 10086,
        productTwoCost: 365,
        productThreeCost: 9527
      }
    },
    filters: {
      formatCost(value) {
        return '¥' + (value / 100).toFixed(2);
      }
    }
  });
</script>

这样代码会好很多:代码重复更少、更加易读,同时维护性也更好。

可以用链式调用方式在一个表达式中使用多个过滤器。例如,

假设我们有一个 round 过滤器可以将数字四舍五入到整数,那么可以用 的方式同时使用两个过滤器。

过滤器同样可以接受参数。下面这个例子中,输入的字符串,即 '$',会作为第二个参数传递给过滤器函数:

<div id="app" v-cloak>
  <p>商品一花费了:{{ productOneCost | formatCost('$') }}</p>
  <p>商品二花费了:{{ productTwoCost | formatCost('$') }}</p>
  <p>商品三花费了:{{ productThreeCost | formatCost('$') }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
  const vm = new Vue({
    el: '#app',
    data() {
      return {
        productOneCost: 10086,
        productTwoCost: 365,
        productThreeCost: 9527
      }
    },
    filters: {
      formatCost(value, symbol) {
        return symbol + (value / 100).toFixed(2);
      }
    }
  });
</script>

注意,过滤器的第一个参数,已经被规定死了,永远都是过滤器管道符前面传递过来的数据。

在过滤器中不能使用 this 来访问数据和方法。关于这个现象我们在《专项问题》中讲解。这是规定、是语法,不是问题,没有解决方案。