如何在Vue中将min / max属性应用于v-model?

时间:2017-04-07 19:39:19

标签: validation input vuejs2

由于实施min的方式,maxv-on的当前约束未得到遵守:

<input id="passwordLength"
       class="form-control form-control-sm"
       type="number"
       min="5"
       max="35"
       v-model="options.length">
<span class="input-group-btn" v-on:click="options.length+=1">
  <button class="btn btn-secondary" type="button">
    <i class="fa fa-plus"></i>
  </button>
</span>

问题

我如何尊重约束并仍保持优雅的实施?

3 个答案:

答案 0 :(得分:2)

您可以为v-model指令添加自定义修饰符:

// function that gets the min and max values for the element and prevents the value of the model from going below the min or above the max
function bindNumberInRange(el, binding, vnode) {
  let model = binding.expression;
  let min = parseInt(el.min);
  let max = parseInt(el.max);
  let val = parseInt(binding.value);

  if ((min !== NaN) && (min >= val)) {
    vnode.context[model] = min;
  } else if ((max !== NaN) && (max <= val)) {
    vnode.context[model] = max;
  }

  el.value = val;
}

// get the original reference to the v-model directive
let modelDirective = Vue.directive('model')

// set a new definition of the v-model directive
Vue.directive('model', {
  bind: function(el, binding, vnode) { 
    // first fire the original v-model bind hook
    modelDirective.bind(el, binding, vnode);

    if (binding.modifiers.range) {
      bindNumberInRange(el, binding, vnode)
    }
  },
  componentUpdated: function(el, binding, vnode) {
    // first fire the original v-model componentUpdated hook
    modelDirective.componentUpdated(el, binding, vnode);

    if (binding.modifiers.range) {
      bindNumberInRange(el, binding, vnode)
    }
  }
})

然后,当您希望模型尊重受影响元素的.rangev-model属性时,您需要做的就是向min添加max修饰符:

<input type="number" min="4" max="10" v-model.range="foo">

这是CodePen Example

这是Vue(半缺乏)documentation on directives

答案 1 :(得分:0)

我做了一些基本的事情:

用法

<span class="input-group-btn" 
    v-on:click="options.length=decrement(options.length, {min: 5, max: 35})">
    <button class="btn btn-secondary" type="button">
        <i class="fa fa-minus"></i>
    </button>
</span>

服务测试

import test from "ava";
import formValidator from "../src/services/form-validator";

test("formValidator.increment()", t => {
  t.is(formValidator.increment(1, { min: 0, max: 10 }), 2);
  t.is(formValidator.increment(9, { min: 0, max: 10 }), 10);
  t.is(formValidator.increment(10, { min: 0, max: 10 }), 10);
  t.is(formValidator.increment(-1, { min: 0, max: 10 }), 0);
  t.is(formValidator.increment(-5, { min: 0, max: 10 }), 0);
  t.is(formValidator.increment(5, { min: 0 }), 6);
});

test("formValidator.decrement()", t => {
  t.is(formValidator.decrement(2, { min: 0, max: 10 }), 1);
  t.is(formValidator.decrement(1, { min: 0, max: 10 }), 0);
  t.is(formValidator.decrement(0, { min: 0, max: 10 }), 0);
  t.is(formValidator.decrement(-1, { min: 0, max: 10 }), 0);
  t.is(formValidator.decrement(15, { min: 0, max: 10 }), 10);
});

服务代码

export default {
  increment(value, { min = 0, max }) {
    let newValue = value + 1;

    if (newValue < min) return min;
    if (typeof max === "undefined" || newValue <= max) return newValue;
    return value;
  },
  decrement(value, { min, max }) {
    let newValue = value - 1;

    if (newValue < min) return min;
    if (newValue > max) return max;
    if (newValue >= min) return newValue;
    return value;
  }
};

答案 2 :(得分:0)

使用@Focus将最大和最小编号验证应用于您的:rules。确保将最大值设置为较大的默认值。最大和最小默认值都会在关注特定输入框时进行更新。 (此文本字段是通过循环创建的)

<v-text-field type="number" 
 @focus="validateWhenFocused(item)"
 :rules="numberRules"
 :label="item.questionName"
 v-model="item.value"
 outline>
</v-text-field>

export default {
 data() {
  return {
   numberRules: [
    v => !!v || "Input is required!",
    v =>
      v < this.maxLength ||
      `${this.errorName} must be less than ${this.maxLength} numbers`,
    v =>
      v > this.minLength ||
      `${this.errorName} must be greater than ${this.minLength} numbers`
   ],
   maxLength: 100,
   minLength: 0,
   errorName: "",
  },
  methods: {
   validateWhenFocused(item){
    this.maxLength = item.maxValue
    this.minLength = item.minValue;
    this.errorName = item.questionName

    }
  }
}