Vue.js: <input> 的@input 不适用于 v-for
Vue.js: @input for <input> not working with v-for
我正在创建自己的自定义 <input>
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
时正常工作,即对于整数元素。但是方法filterInput
在isArray = true
时是永远不会被调用的,对于错误的输入也没有限制。有什么问题?
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>
一些注意事项:
- 我已将
num
更改为由 arr[0]
支持的计算 属性。这简化了过滤逻辑,因为它只需要为两种类型的输入考虑 arr
。它可以进一步简化,例如该模板实际上并不需要处理两种情况,它可以像对待多值一样对待单值,但 array-size
为 1。只有发出的值(不包含在我的代码中)才真正需要对于单值情况有不同的行为。稍加重构 num
可能会被完全删除。
- 实现是有状态的。如果您想从外部传入值,您将 运行 陷入困境。
- 与其将值设置为
''
,我建议使用 replace
删除不允许的字符。我没有在我的代码中进行此更改,我想保留原始示例中的行为。
- 结束
</input>
标签无效,我已将其删除。
- 我试图删除的
filterInput
方法中有很多重复项。它现在检查 arr
数组中的所有条目。似乎没有必要针对已更改的特定输入。
this.$set
用于按索引更新数组,否则反应系统将无法检测到(操作数组的标准警告)。
我正在创建自己的自定义 <input>
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
时正常工作,即对于整数元素。但是方法filterInput
在isArray = true
时是永远不会被调用的,对于错误的输入也没有限制。有什么问题?
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>
一些注意事项:
- 我已将
num
更改为由arr[0]
支持的计算 属性。这简化了过滤逻辑,因为它只需要为两种类型的输入考虑arr
。它可以进一步简化,例如该模板实际上并不需要处理两种情况,它可以像对待多值一样对待单值,但array-size
为 1。只有发出的值(不包含在我的代码中)才真正需要对于单值情况有不同的行为。稍加重构num
可能会被完全删除。 - 实现是有状态的。如果您想从外部传入值,您将 运行 陷入困境。
- 与其将值设置为
''
,我建议使用replace
删除不允许的字符。我没有在我的代码中进行此更改,我想保留原始示例中的行为。 - 结束
</input>
标签无效,我已将其删除。 - 我试图删除的
filterInput
方法中有很多重复项。它现在检查arr
数组中的所有条目。似乎没有必要针对已更改的特定输入。 this.$set
用于按索引更新数组,否则反应系统将无法检测到(操作数组的标准警告)。