如何在 VueJS 中将一长串“手表”转换为功能方式?

Posted

技术标签:

【中文标题】如何在 VueJS 中将一长串“手表”转换为功能方式?【英文标题】:How can I convert a long list of 'watch' into a functional way in VueJS? 【发布时间】:2019-05-22 23:43:31 【问题描述】:

我是 vueJS 的新手。 我有一长串观察名单。都是一样的。 但我不知道如何将它们转换成函数式。

它们都是用于在输入标签和v-model中添加逗号。 它工作得很好。但是代码看起来很笨,因为它们完全一样,但不是它们的名字。

new Vue(
  data: 
    tmp_price1: '',
    tmp_price2: '',
    tmp_price3: '',
    tmp_a_price: '',
    tmp_b_price: '',
  ,

  watch: 
   tmp_price1: function(newValue) 
     if (newValue != '') 
       const result = newValue.replace(/\D/g, "").replace(/\B(?=(\d3)+(?!\d))/g, ",");
       Vue.nextTick(() => this.tmp_price1 = result);
     
   ,
   tmp_price2: function(newValue) 
     if (newValue != '') 
       const result = newValue.replace(/\D/g, "").replace(/\B(?=(\d3)+(?!\d))/g, ",");
       Vue.nextTick(() => this.tmp_price2 = result);
     
   ,

  ....(repeat)

  ,

请帮助我有效地改进这些愚蠢的代码。

【问题讨论】:

你试过我的答案了吗? 事实上,我尝试了两次你的答案,因为它看起来最简单。但我今晚会再试一次。 (对不起,这是一个正在运行的服务,所以我现在不能这样做..!_!) 【参考方案1】:

这可能看起来像是过度设计,但我可能会制作一个组件来封装令人愉悦的行为。该组件将在其中计算出一个可设置的值,该值会发出 commafied 值供父级在更新时使用。

new Vue(
  el: '#app',
  data: 
    tmp_price1: '',
    tmp_price2: '',
    tmp_price3: '',
    tmp_a_price: '',
    tmp_b_price: '',
  ,
  components: 
    commafiedInput: 
      props: ['value'],
      template: '<input v-model="commaValue">',
      computed: 
        commaValue: 
          get() 
            return this.value;
          ,
          set(newValue) 
            this.$emit('input', this.addCommas(newValue));
          
        
      ,
      methods: 
        addCommas(v) 
          return v.replace(/\D/g, '').replace(/\B(?=(\d3)+(?!\d))/g, ",");
        
      
    
  
);
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <div> tmp_price1
    <commafied-input v-model="tmp_price1"></commafied-input>
  </div>
  <commafied-input v-model="tmp_price2"></commafied-input>
  <commafied-input v-model="tmp_price3"></commafied-input>
  <commafied-input v-model="tmp_a_price"></commafied-input>
  <commafied-input v-model="tmp_b_price"></commafied-input>
</div>

【讨论】:

感谢您的回答。我尝试了这个解决方案,但没有奏效....我想我犯了一个错误。它不断给我一条错误消息,例如“未捕获的 TypeError:this.addCommas is not a function..”。 我从这里复制了整个“组件”部分并将其粘贴到我的代码中......我在这里错过了什么......? 我不知道。 commafiedInput 之外的东西调用addCommas 吗? 天啊..我又试了一次,它突然神奇地起作用了!我之前可能犯过一些错误。谢谢! 我可以再问一个问题吗?如果我有一个像 'tmp_prices' 这样的变量作为数组,我该如何更改呢?【参考方案2】:

只显示值的格式化版本可以通过一个简单的过滤器来完成:

new Vue(
  el: '#app',
  data: 
    tmp_price1: '123123',
    tmp_price2: '',
    tmp_price3: ''
  ,
  filters: 
    myFilter(v) 
      return v.replace(/\D/g, '').replace(/\B(?=(\d3)+(?!\d))/g, ",");
       
  
);
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <div><input v-model="tmp_price1">tmp_price1 | myFilter</div>
  <div><input v-model="tmp_price2">tmp_price2 | myFilter</div>
  <div><input v-model="tmp_price3">tmp_price3 | myFilter</div>
  
</div>

...但这对于输入字段来说还不够;您不能只在v-model 属性上添加过滤器。 Roy J's answer 中描述的子组件可能是处理该问题的最佳和最可重用的方法,但是如果您可以接受一些快速和肮脏的东西(但不是脏)您可以在问题上抛出一个更改处理程序:

new Vue(
  el: '#app',
  data: 
    tmp_price1: '123123',
    tmp_price2: '',
    tmp_price3: ''
  ,
  methods: 
    myFormatter(fieldname) 
      /* replace the user's input with the formatted value.
      
          There's probably some clever way to read the v-model 
          name from the input field instead of passing it to the 
          method as a string, but I'm not going to mess around 
          with that for what is after all a quick-and-dirty technique */
      this[fieldname] = this[fieldname].replace(/\D/g, "").replace(/\B(?=(\d3)+(?!\d))/g, ",");
    
  ,
  mounted() 
    // if the initial values aren't always empty, you'll need to run the
    // formatter function on component load as well as on user input:
    ['tmp_price1', 'tmp_price2', 'tmp_price3'].forEach(f => 
      this.myFormatter(f);
    );
  
);
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <div><input v-model="tmp_price1" @input="myFormatter('tmp_price1')">tmp_price1</div>
  <div><input v-model="tmp_price2" @input="myFormatter('tmp_price2')">tmp_price2</div>
  <div><input v-model="tmp_price3" @input="myFormatter('tmp_price3')">tmp_price3</div>
</div>

(或者作为另一种变体,this answer 对类似问题使用基本相同的技术,但将其包装在 Vue 指令中以绑定输入事件而不是附加 @input 处理程序。)

请注意,在“过滤器”版本中,v-model 值仍然是原始用户输入;过滤器只影响显示的值。在第二个示例中,格式应用于v-modeled 值本身,因此如果您将这些值传递到其他地方,您将获得格式化版本。这两种技术都可能有用,具体取决于具体情况。 (或者您甚至可以组合使用它们——例如,删除 v-model 中的非数字,然后通过过滤器添加逗号以供显示。)

【讨论】:

以上是关于如何在 VueJS 中将一长串“手表”转换为功能方式?的主要内容,如果未能解决你的问题,请参考以下文章

str.Format(_T("%lf"),n1),转换的字符串会出现小数点后的一长串零,怎么去掉?

如何在 vuejs 中将美分转换为单位?

如何在 selectInput R Shiny 中为一长串选项设置值

如何搜索一长串属性并将其与 fontawesome 图标匹配?

在 Powershell 中过滤一长串列表

在c中制作一长串加密的子串