如何将最小/最大属性应用于Vue中的v模型? [英] How to apply min/max attribute to v-model in Vue?

查看:156
本文介绍了如何将最小/最大属性应用于Vue中的v模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于实现v-on的方式,未遵守minmax的当前约束条件:

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

问题

我如何尊重约束并保持良好的实现?

解决方案

您可以在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)
    }
  }
})

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

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

这是一个 CodePen示例.

这是Vue的(半缺失)关于指令的文档.

Current constraint of min and max are not respected due to the way v-on is implemented:

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

Question

How can I respect the constrain and still keep an elegant implementation?

解决方案

You could add a custom modifier to the v-model directive:

// 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)
    }
  }
})

Then, all you would need to do is add a .range modifier to v-model when you want the model to respect the min and max attributes of the affected element:

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

Here's a CodePen Example.

Here's Vue's (semi-lacking) documentation on directives.

这篇关于如何将最小/最大属性应用于Vue中的v模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆