如何在Vue的计算属性中重复使用带参数的函数?

5
我有一个Vue实例,其中有五个计算属性函数,它们针对不同的值做相同的事情。我重复了很多次,并想知道是否有更清晰的方法来减少这种重复。
在HTML模板中,我有五个输入字段,每个输入字段限制为25个字符,我想显示一个字符计数器:
        <div class='field is-grouped'>
        <p class='control is-expanded'>
            <input 
                class="input" 
                placeholder="Trophy engraving line 1 (25 character limit)" 
                v-model='engraving.line1' 
                v-validate="'required'"
                :class="{'input': true, 'is-danger': errors.has('engraving.line1') }" 
                name='engraving.line1'>
        </p>
        <p class='control'>
            <span>{{ line1count }}</span>
        </p>
    </div>

我有五个与此完全相同的字段,除了它们说engraving.line2engraving.line3engraving.line4engraving.line5

然后,在我的组件JavaScript中,我定义了刻字对象,并为每个字段使用相同的计算方法。

export default {
    data(){
        return {
            engraving: {
                line1: '',
                line2: '',
                line3: '',
                line4: '',
                line5: '',
            }
        };
    },
    computed: {
        line1count() {
            var chars = this.engraving.line1.length,
                limit = 25;

            return (limit - chars) + "/" + limit + " characters remaining";
        },
        line2count(){
            var chars = this.engraving.line2.length,
                limit = 25;

            return (limit - chars) + "/" + limit + " characters remaining";
        },
        line3count(){
            var chars = this.engraving.line3.length,
                limit = 25;

            return (limit - chars) + "/" + limit + " characters remaining";
        },
        line4count(){
            var chars = this.engraving.line4.length,
                limit = 25;

            return (limit - chars) + "/" + limit + " characters remaining";
        },
        line5count(){
            var chars = this.engraving.line5.length,
                limit = 25;

            return (limit - chars) + "/" + limit + " characters remaining";
        }
    },

我如何重复利用此函数以接受数据参数,从而避免冗余代码?


2
这就是使得一个伟大的小组件的那种东西。 - Bert
2个回答

4
通常情况下,我会创建一个小型组件来完成这个功能。下面的示例移除了验证(仅为了使示例更简单),但与常规输入元素完全相同。
使用组件的优点是您想要执行的验证仅限于单个元素,并且它们很容易被重复使用。

console.clear()

Vue.component("engraving-line",{
  props:["value", "placeholder", "limit"],
  template:`
    <div class='field is-grouped'>
        <p class='control is-expanded'>
            <input 
                class="input" 
                :placeholder="placeholder" 
                v-model='internalValue'>
        </p>
        <p class='control'>
            <span>{{ lineCount }}</span>
        </p>
    </div>
  `,
  computed:{
    internalValue:{
      get() {return this.value},
      set(v) {this.$emit("input", v)}
    },
    lineCount(){
      return `${this.limit - this.value.length}/${this.limit} characters remaining`
    }
  }
})

new Vue({
  el: "#app",
  data:{
    line1: "",
    line2: "",
    line3: "",
    line4: "",
    lineLimit: 25
  }
})
<script src="https://unpkg.com/vue@2.4.2"></script>
<div id="app">
  <engraving-line :limit="lineLimit" 
                  v-model="line1" 
                  placeholder="Trophy engraving line 1 (25 character limit)">
  </engraving-line>
    <engraving-line :limit="lineLimit" 
                  v-model="line2" 
                  placeholder="Trophy engraving line 2 (25 character limit)">
  </engraving-line>
    <engraving-line :limit="lineLimit" 
                  v-model="line3" 
                  placeholder="Trophy engraving line 3 (25 character limit)">
  </engraving-line>
    <engraving-line :limit="lineLimit" 
                  v-model="line4" 
                  placeholder="Trophy engraving line 4 (25 character limit)">
  </engraving-line>
</div>


这个模式有没有名称?我真的很喜欢这个解决方案。 - ricardoorellana
1
@RicardoOrellana 我不确定是否有特定的模式可以指出,除了识别可重复使用的UI元素。在这种情况下,基本上我们想要一个输入元素,但带有一些额外的UI,显示一些附加信息。就像将代码分解为可重用函数一样,使用Vue(或其他基于组件的框架,如React),您将开始识别将UI分解为可重用组件的机会。 - Bert

4
你可以使用一个方法:
methods: {
    linecount(line, limit) {
        var chars = this.engraving.line[line].length,
        return (limit - chars) + "/" + limit + " characters remaining";
    },
}

然后在你的HTML中引用它:

<p class='control'>
     <span>{{ linecount(1,25) }}</span>
</p>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接