rafafan2010
rafafan2010

Reputation: 1579

Computed Setter as validator

I'm trying to use a computed property to monitor the value in ElementUI's el-input component, but the value I want is not being displayed in the component. Specifically, when the user types an input, I want to limit the length to three characters without having the input show more. For example, I don't want behavior where the user types 5 characters, and then when the el-input is not in focus, the value gets corrected. I realize that there is a maxlength attribute, but I want to make the validation more general. As an extension to this, I want to be able to call any kind of function on the content of the el-input and show the result of that function. This is what I'm doing right now:

template:

    <el-input
        :placeholder="placeholder"
        :value="inputValue"
        @keypress.enter.native="$emit('keypress-enter',event)"
        @input="input"
        :disabled="disabled"
        :autosize="true"
        :readonly="readonly"
        :type="inputType"
        :rows="rows"
        v-model="inputValue"
        > 
    </el-input>

script:

computed: {
    inputValue: {
        get: function(){
            return this.temp;
            // This is what I eventually want to do
            // return this.validationFunction.f(this.temp);
        },
        set: function(newVal) {
            // This is what I'm doing right now to test
            this.temp = "";
            this.temp = (newVal.length > 3) ? newVal.slice(0,3) : newVal;
        }
    },
},
data: {
    return {
        temp: ""
    }
}

What is the best way to get the desired behavior?

Upvotes: 1

Views: 1722

Answers (1)

Roy J
Roy J

Reputation: 43899

The setter is working but the el-input doesn't know it. The problem is that when the value of inputValue stops changing, Vue figures it doesn't need to notify anybody.

So you have to change the value, then in $nextTick change it to what you want it to be. That way the notifications always happen. There is, unfortunately, no way I know of to simply tell Vue to send notifications about a computed or data item.

new Vue({
  el: '#app',
  data: {
    temp: 'a'
  },
  computed: {
    inputValue: {
      get() {
        return this.temp;
      },
      set(newValue) {
        this.temp = newValue;
        this.$nextTick(() => {
          this.temp = newValue.substr(0, 3);
        });
      }
    }
  }
});
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui/lib/index.js"></script>

<div id="app">
  <el-input v-model="inputValue"></el-input>
  Actual value: {{ temp }}
</div>

Upvotes: 2

Related Questions