vue.js - 如何在 Vue 中创建一个数字输入组件,其限制不允许超出限制范围

标签 vue.js vuejs2

我正在尝试在 Vue 中创建一个数字输入组件,其最小值和最大值不允许在没有成功的情况下输入外部限制:

<template id="custom-input">
  <div>
    <input :value="value" type="number" @input="onInput">
  </div>
</template>

<div id="app">
  <div>
    <span>Value: {{ value }}</span>
    <custom-input v-model="value" :max-value="50"/>
  </div>
</div>

Vue.component('custom-input', {
  template: '#custom-input',
  props: {
    value: Number,
    maxValue: Number
  },
  methods: {
    onInput(event) {
      const newValue = parseInt(event.target.value)
      const clampedValue = Math.min(newValue, this.maxValue)
      this.$emit('input', clampedValue)
    }
  }
})

new Vue({
  el: "#app",
  data: {
    value: 5
  }
})

在这里 fiddle :https://jsfiddle.net/8dzhy5bk/6/

在前面的示例中,最大值设置为 50。如果我输入 60,它会在输入中自动转换为 50,但如果我输入第三个数字,它允许继续输入。传递给父级的值被限制,但我还需要限制输入,以便不能输入更多数字。

最佳答案

当 input 的值大于 10 时,它总是会向父组件发出 10,但值 保持不变 (总是=10)所以它不会触发 react 性 .

一种解决方案 , 总是先发出实际值 (= parseInt(event.target.value) ),然后发出最大值 (= Math.min(newValue, this.maxValue) ) 在 vm.$nextTick()

另一个解决方案 正在使用 this.$forceUpdate() .

下面是演示 $nextTick .

Vue.component('custom-input', {
  template: '#custom-input',
  props: {
    value: Number,
    maxValue: Number
  },
  methods: {
    onInput(event) {
      const newValue = parseInt(event.target.value)
      const clampedValue = Math.min(newValue, this.maxValue)
      this.$emit('input', newValue)
      this.$nextTick(()=>{
      	this.$emit('input', clampedValue)
      })
    }
  }
})

new Vue({
  el: "#app",
  data: {
    value: 5
  },
  methods: {
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>

<template id="custom-input">
  <div>
    <input 
      :value="value" 
      type="number" 
      @input="onInput" 
     >
  </div>
</template>

<div id="app">
  <div>
    <span>Value: {{ value }}</span>
    <custom-input v-model="value" :max-value="10"/>
  </div>
</div>


下面是演示 vm.$forceUpdate .

Vue.component('custom-input', {
  template: '#custom-input',
  props: {
    value: Number,
    maxValue: Number
  },
  methods: {
    onInput(event) {
      const newValue = parseInt(event.target.value)
      const clampedValue = Math.min(newValue, this.maxValue)
      this.$emit('input', clampedValue)
      this.$forceUpdate()
    }
  }
})

new Vue({
  el: "#app",
  data: {
    value: 5
  },
  methods: {
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>

<template id="custom-input">
  <div>
    <input 
      :value="value" 
      type="number" 
      @input="onInput" 
     >
  </div>
</template>

<div id="app">
  <div>
    <span>Value: {{ value }}</span>
    <custom-input v-model="value" :max-value="10"/>
  </div>
</div>

关于vue.js - 如何在 Vue 中创建一个数字输入组件,其限制不允许超出限制范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52542383/

相关文章:

webpack - 从变量动态加载 Vue 组件

vue.js - 在 vue3 中通过 props 传递的组件

vue.js - 为什么将 name 与 router-link 一起使用比仅将 to 与路径一起使用更好?

html - Vue.js 2 - 从 body 标签中删除初始边距

javascript - 如何防止用户提交远程 api 中已存在的文本?

vue.js - 如何使用 nuxt 和 nuxt-i18n 生成本地化动态路由?

node.js - 带有集成 REST API 后端的 SSR Nuxt.js

node.js - 使用 socket.io 和 vue 的 Express Session 在每次页面加载时都会重置

javascript - VueJS 中的秒到分钟

vue.js - 让 Autoprefixer 与 TailwindCSS 和 Gridsome 一起工作