最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to reuse function with parameters in Vue computed properties? - Stack Overflow

programmeradmin0浏览0评论

I have a Vue instance with five puted property functions that do the same things for different values. I repeat myself quite a bit and am wondering about a cleaner way to do this without repeating myself so much.

In the HTML template I have five input fields, each input field is limited to 25 characters and I would like to display I display a character counter:

        <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>

I have five fields that look exactly like that except they say engraving.line2, engraving.line3, engraving.line4 and engraving.line5.

Then my ponent javascript I define the engraving object and have the same puted method for each field.

export default {
    data(){
        return {
            engraving: {
                line1: '',
                line2: '',
                line3: '',
                line4: '',
                line5: '',
            }
        };
    },
    puted: {
        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";
        }
    },

How can I resuse this function to accept a data parameter and not repeat myself so much?

I have a Vue instance with five puted property functions that do the same things for different values. I repeat myself quite a bit and am wondering about a cleaner way to do this without repeating myself so much.

In the HTML template I have five input fields, each input field is limited to 25 characters and I would like to display I display a character counter:

        <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>

I have five fields that look exactly like that except they say engraving.line2, engraving.line3, engraving.line4 and engraving.line5.

Then my ponent javascript I define the engraving object and have the same puted method for each field.

export default {
    data(){
        return {
            engraving: {
                line1: '',
                line2: '',
                line3: '',
                line4: '',
                line5: '',
            }
        };
    },
    puted: {
        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";
        }
    },

How can I resuse this function to accept a data parameter and not repeat myself so much?

Share Improve this question asked Oct 11, 2017 at 17:23 Connor LeechConnor Leech 18.9k32 gold badges110 silver badges160 bronze badges 1
  • 2 This is the kind of thing that makes a great small ponent. – Bert Commented Oct 11, 2017 at 17:31
Add a ment  | 

2 Answers 2

Reset to default 4

You could use a method:

methods: {
    linecount(line, limit) {
        var chars = this.engraving.line[line].length,
        return (limit - chars) + "/" + limit + " characters remaining";
    },
}

And then in your html just reference it:

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

Typically for this kind of thing I would make a small ponent. The below example removes the validation (just to make the example easier) but works just like a regular input element.

The advantage of using ponents is things like the validation you want to do are scoped to the individual elements and they are easily re-usable.

console.clear()

Vue.ponent("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>
  `,
  puted:{
    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./[email protected]"></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>

发布评论

评论列表(0)

  1. 暂无评论