【问题标题】:Select Vue filter based on variable根据变量选择Vue过滤器
【发布时间】:2017-09-22 21:30:51
【问题描述】:

我有什么

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

<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]) 之类的东西,但是重新实现已经存在的东西没有多大意义。如果有一种方法可以访问过滤器的底层功能而又不会使其过于混乱,我可以这样做,但这似乎并不理想。

我想要什么

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

【问题讨论】:

    标签: javascript html vue.js vuejs2


    【解决方案1】:

    这将允许您保留数据格式并使用现有过滤器。

    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.

    【讨论】:

    • 这就是我要找的。 Vue.filter(filter)(value) 是我缺少的让解决方法变得干净整洁的部分。
    • @3ocene 是的,Vue.filter() 只是过滤器的名称返回过滤器本身。 vuejs.org/v2/api/#Vue-filter
    【解决方案2】:

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

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

    您可以通过向组件添加一个包罗万象的过滤器并将类型作为参数传递来使其更简洁:

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

    然后在你的模板中:

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

    【讨论】:

    • 这是一个很好的答案。我会同意这个,但@Bert Evan 的回答中的Vue.filter(filter)(value) 电话只是更干净一点的IMO。
    • 是的,我不知道。如果您想将格式化程序本身用作过滤器,那绝对是要走的路。如果你愿意,你也可以用我的回答返回Vue.filter(type)(value)。只是取决于你想如何在模板中写出来。
    【解决方案3】:

    使用

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

    并创建自己的过滤器

    【讨论】:

    • 这个答案并没有真正解释任何事情。您可能应该添加更多细节,也许是一个例子,以及为什么我应该做我说过我不想做的事情的理由。
    • 这正是您所需要的,我不知道您以前从未创建过过滤器。除了您创建自己的过滤器的部分之外,它与其他 2 个答案的提示相同。
    • 我不需要编写过滤器,这不是“我需要的”。我特别说,“我当然可以编写自己的格式化函数,然后使用this.formatters[row[3]](row[1]) 之类的东西,但是重新实现已经存在的东西没有多大意义”。你刚刚告诉我我应该在一个新的过滤器中重新实现这些功能。更重要的是,其他答案提供了一个推理,而不仅仅是告诉我做某事。那是属于 SO 的内容类型,而不是没有解释或推理的小 sn-ps 代码。
    猜你喜欢
    • 2020-10-09
    • 1970-01-01
    • 2017-06-25
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多