【问题标题】:Vue.js: @input for <input> not working with v-forVue.js:<input> 的 @input 不适用于 v-for
【发布时间】:2019-09-14 13:06:34
【问题描述】:

我正在创建自己的自定义 &lt;input&gt; Vue 组件。我正在做的是用户永远不能输入错误的输入类型。为此,我在每个输入端都使用regex.test()

这是我的 Vue 组件的代码,用于获取整数元素或整数数组:

<template>
    <div>
        <label>{{ label }}
            <template v-if="isArray">
                <input 
                    v-model="arr[i - 1]" 
                    @input="filterInput" 
                    :disabled="disableWhen" 
                    v-for="i in arraySize" 
                    :key="i">
                </input>
            </template>
            <template v-else>
                <input 
                    v-model="num" 
                    @input="filterInput" 
                    :disabled="disableWhen">
                </input>
            </template>
        </label>
        <el-button 
            type="success" 
            icon="el-icon-check" 
            circle 
            @click="confirm" 
            :disabled="disableWhen">
        </el-button>
    </div>
</template>

<script>
    export default {
        props: {
            label: String,
            nonNegative: Boolean,
            disableWhen: Boolean,
            isArray: Boolean,
            arraySize: Number
        },
        data() {
            return {
                num: '',
                arr: []
            }
        },
        methods: {
            filterInput() {
                if (this.nonNegative) {
                    if (!/^[0-9]*$/.test(this.num)) {
                        this.num = '';
                    }
                } else if (!/^(-)?[0-9]*$/.test(this.num)) {
                    this.num = '';
                }
            },
            confirm() {
                if (this.isArray) {
                    let validArrayInput = true;
                    for (let i = 0; i < this.arraySize; i++) {
                        if (!this.validInput(this.arr[i])) {
                            validArrayInput = false;
                        }
                    }
                    if (validArrayInput) {
                        this.$emit('confirm', this.arr);
                    }
                } else if (this.validInput(this.num)) {
                    this.$emit('confirm', this.num);
                }
            },
            validInput(x) {
                return (x !== '' && x !== '-' && typeof x !== "undefined");
            }
        }
    }
</script>

代码在isArray = false 时正常工作,即对于整数元素。但是isArray = true时永远不会调用方法filterInput,并且对错误输入没有限制。有什么问题?

【问题讨论】:

  • arr 被设置为一个空数组,并且在发布的代码中没有任何地方改变。

标签: vue.js html-input v-for


【解决方案1】:

filterInput 对于两种类型的输入都可以正常调用,但它只会尝试操纵 num,不会更改 arr

这是我实现这一点的尝试:

const MyInput = {
  template: `
    <div>
      <label>{{ label }}
        <template v-if="isArray">
          <input 
            v-for="i in arraySize" 
            v-model="arr[i - 1]" 
            :disabled="disableWhen" 
            :key="i"
            @input="filterInput" 
          >
        </template>
        <template v-else>
          <input 
            v-model="num" 
            :disabled="disableWhen"
            @input="filterInput"
          >
        </template>
      </label>
    </div>  
  `,

  props: {
    label: String,
    nonNegative: Boolean,
    disableWhen: Boolean,
    isArray: Boolean,
    arraySize: Number
  },
  
  data() {
    return {
      arr: []
    }
  },
  
  computed: {
    num: {
      get () {
        return this.arr[0]
      },
      
      set (num) {
        this.arr[0] = num
      }
    }
  },
  
  methods: {
    filterInput() {
      const arr = this.arr
      const re = this.nonNegative ? /^\d*$/ : /^-?\d*$/
      
      for (let index = 0; index < arr.length; ++index) {
        if (!re.test(arr[index])) {
          this.$set(arr, index, '')
        }
      }
    }
  }
}

new Vue({
  el: '#app',
  
  components: {
    MyInput
  }
})
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>

<div id="app">
  <my-input label="Single"></my-input>
  <br>
  <my-input label="Multiple" is-array :array-size="3"></my-input>
</div>

几点说明:

  1. 我已将num 更改为由arr[0] 支持的计算属性。这简化了过滤逻辑,因为它只需要为两种类型的输入考虑arr。它可以进一步简化,例如模板实际上并不需要处理两种情况,它可以将单值视为与多值相同,但 array-size 为 1。只有发出的值(未包含在我的代码中)真正需要不同单值情况下的行为。通过一点重构,num 可能会被完全删除。
  2. 实现是痛苦的有状态的。如果您想从外部传递值,您将会遇到困难。
  3. 我建议不要将值设置为'',而是使用replace 去除不允许的字符。我没有在我的代码中进行此更改,我想保留原始示例中的行为。
  4. 关闭 &lt;/input&gt; 标记无效,我已将其删除。
  5. 您的filterInput 方法中有很多重复项,我已尝试将其删除。它现在检查arr 数组中的所有条目。似乎没有必要针对已更改的特定输入。
  6. this.$set 用于按索引更新数组,否则反应系统将无法检测到(操作数组的标准警告)。

【讨论】:

    猜你喜欢
    • 2020-02-25
    • 1970-01-01
    • 2019-04-26
    • 1970-01-01
    • 2016-05-23
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多