根据变量选择Vue过滤器

时间:2017-04-25 18:02:37

标签: javascript html vue.js vuejs2

我有什么

我正在基于Vue2中的2D数组生成一个表。我可以让表格在正确的位置显示所有值,但我在格式化方面遇到问题。模板看起来像这样:

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Column 1</th>
      <th>Column 2</th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="row in data">
      <td>{{row[0]}}</td>
      <td>{{row[3]+row[1]+row[4]}}</td>
      <td>{{row[3]+row[2]+row[4]}}</td>
    </tr>
  </tbody>
</table>

数据看起来像这样:

var data = [
  ['revenue', 123.4, 153.48, '$'],
  ['cost', 93.26, 109.48, '$'],
  ['profit', 30.14, 44, '$'],
  ['margin', 24.425, 28.668, '', '%']
];

我失败了

这有效......是的。我可以拥有我想要的任何行,我可以指定单位 - 前缀或后缀 - 但它并不完美。最大的问题是货币有不同的小数位数。我可以将这些值存储为字符串,但其中一些值会在计算中重复使用,这意味着我必须解析它们。

我尝试了什么

就在这时,我遇到过滤器。由于我继承的这个项目已经内置了一堆,看起来它们将完全符合我的要求。我可以将其更改为{{row[1] | currency}}并将其全部格式化。唯一的问题是我有混合数据类型。在示例中,revenuecostprofit都是货币值,但margin是百分比。

理想情况下,我想在每个数组的第4个索引中指定过滤器:

var data = [
  ['revenue', 123.4, 153.48, 'currency'],
  ['cost', 93.26, 109.48, 'currency'],
  ['profit', 30.14, 44, 'currency'],
  ['margin', 24.425, 28.668, 'percent']
];

然后使用类似的东西吐出值:

<td>{{row[1] | row[3]}}</td>
<td>{{row[2] | row[3]}}</td>

但是,这似乎不起作用。我还尝试了filters[row[3]]和其他一些变体,但似乎它的语法不存在。我当然可以编写自己的格式化函数,然后使用this.formatters[row[3]](row[1])之类的东西,但重新实现已存在的东西并没有多大意义。如果有一种方法可以访问过滤器的基础功能而不会使它太乱,我可以这样做,但它似乎并不理想。

我想要什么

理想的解决方案是使用现有过滤器来格式化表中的所有输出。直接调用值上的函数也没关系。如果做不到这一点,我可以预先格式化这些值,并使用现有函数将它们作为字符串存储在单独的对象中,但这并不理想。

3 个答案:

答案 0 :(得分:3)

这样您就可以保留数据格式并使用现有的过滤器。

new Vue({
  el:"#app",
  data:{
    data: [
      ['revenue', 123.4, 153.48, "currency"],
      ['cost', 93.26, 109.48, "currency"],
      ['profit', 30.14, 44, "currency"],
      ['margin', 24.425, 28.668,  "percent"]
    ]
  },
  methods:{
    format(value, filter){
      return Vue.filter(filter)(value)
    }
  }
})

模板

  <tr v-for="row in data">
    <td>{{row[0]}}</td>
    <td>{{format(row[1], row[3])}}</td>
    <td>{{format(row[1], row[3])}}</td>
  </tr>

Example

答案 1 :(得分:1)

缺少documentation on Vue filters,但您显然无法像想要的那样动态访问过滤器。

您最好的选择是将格式化功能保存在您建议的对象中。

您可以通过向组件添加catchall过滤器并将类型作为参数传递来使其更清洁:

filters: {
  format(value, type) {
    return this.formatters[type](value);
  }
}

然后在你的模板中:

<td>{{row[2] | format(row[3]) }}</td>

答案 2 :(得分:-3)

使用

{{row[2] | rowFilter(row[3])}} 

并创建自己的过滤器