Vue 3 中的 Vue JS @change 和 @keydown 事件
Vue JS @change and @keydown events in Vue 3
我想弄清楚 keydown
和 change
事件如何在 Vue.js (Vue 3) 中协同工作。设置非常简单。我在一个组件中有一个文本输入,我希望能够在文本输入字段中输入一个数字。从那里,我希望能够使用箭头键(向上和向下)来增加或减少输入中的值。当输入失去焦点时,它应该触发@change
然后更新模型。
我遇到的这个问题是,当我使用 @keydown
更新输入中的值时,它的行为方式与可打印字符的按键行为不同。更新 @keydown
上的值不会导致在控件失去焦点时触发 @change
事件。
如果有帮助,我在 playground 中设置了一个示例,但这是代码:
App.vue
<script>
import NumberInput from './NumberInput.vue'
export default {
components: {
NumberInput
},
data() {
return {
number: 100
}
}
}
</script>
<template>
<p>
Model should only be updated when focus leaves the text box.
</p>
<p>
This works fine when you type in a number and focus off the text box.
</p>
<p>
However, when you <b>only</b> use the arrow keys to modify a value, the `@change` event doesn't fire.
</p>
<br />
<div style="padding:10px; border:1px solid #aaaaaa">
<NumberInput v-model="number" />
Number: {{ number }}
</div>
</template>
NumberInput.vue
<script>
export default {
props: ['modelValue'],
data() {
return {
number: this.modelValue
}
},
methods: {
incrementOrDecrementNumber: function(e) {
const isUpKey = (e.key === "ArrowUp");
const isDownKey = (e.key === "ArrowDown");
let x = parseInt(this.number, 10);
if (x == NaN)
x = 0;
if (isUpKey || isDownKey) {
if (isUpKey)
x++;
else
x--;
this.number = x;
e.preventDefault();
}
},
numberChanged: function(e) {
this.$emit("update:modelValue", this.number);
}
}
}
</script>
<template>
<div>
Enter a number (press up or down to modify): <input type="text" v-model="number" @change="numberChanged($event);" @keydown="incrementOrDecrementNumber($event);" />
</div>
</template>
是否可以在组件中更新 this.number
并让它在输入失去焦点时触发 @change
事件?
谢谢!
您 运行 遇到的问题不是由于“keydown
和 change
事件如何在 Vue.js 中协同工作”,实际上与此无关Vue.js 本身,而是 HTML 和 JavaScript 的基本潜在问题。如果用户通过直接与网页中的字段交互更改输入字段的数据,将在输入字段中触发更改事件,因为这会将元素的“脏”标志设置为 true
.
在您的代码中,当用户的按键动作触发更改时,输入值正在内部通过JavaScript更改,这不会触发更改事件,无论是通过 Vue.js 还是通过普通 JavaScript.
进行更改
要触发更改事件,您可以通过特定方式更改输入值,例如根据 this answer 在输入元素上使用 setAttribute(value,...)
或直接调用更改事件。
在您自己的代码中,@blur="numberChanged($event)"
可以像我评论中指出的那样工作:
<input
type="text"
v-model="number"
@change="numberChanged($event)"
@blur="numberChanged($event)"
/>
或者您可以根据 Vue.js documentation 使输入值成为组件的“模型”。我还将输入类型设置为数字,以便本机提供输入 up-down 箭头键响应:
<script>
export default {
props: ["modelValue"],
emits: ["update:modelValue"],
},
};
</script>
<template>
<div>
<p>
Enter a number (press up or down to modify):
<input
type="number"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</p>
</div>
</template>
我想弄清楚 keydown
和 change
事件如何在 Vue.js (Vue 3) 中协同工作。设置非常简单。我在一个组件中有一个文本输入,我希望能够在文本输入字段中输入一个数字。从那里,我希望能够使用箭头键(向上和向下)来增加或减少输入中的值。当输入失去焦点时,它应该触发@change
然后更新模型。
我遇到的这个问题是,当我使用 @keydown
更新输入中的值时,它的行为方式与可打印字符的按键行为不同。更新 @keydown
上的值不会导致在控件失去焦点时触发 @change
事件。
如果有帮助,我在 playground 中设置了一个示例,但这是代码:
App.vue
<script>
import NumberInput from './NumberInput.vue'
export default {
components: {
NumberInput
},
data() {
return {
number: 100
}
}
}
</script>
<template>
<p>
Model should only be updated when focus leaves the text box.
</p>
<p>
This works fine when you type in a number and focus off the text box.
</p>
<p>
However, when you <b>only</b> use the arrow keys to modify a value, the `@change` event doesn't fire.
</p>
<br />
<div style="padding:10px; border:1px solid #aaaaaa">
<NumberInput v-model="number" />
Number: {{ number }}
</div>
</template>
NumberInput.vue
<script>
export default {
props: ['modelValue'],
data() {
return {
number: this.modelValue
}
},
methods: {
incrementOrDecrementNumber: function(e) {
const isUpKey = (e.key === "ArrowUp");
const isDownKey = (e.key === "ArrowDown");
let x = parseInt(this.number, 10);
if (x == NaN)
x = 0;
if (isUpKey || isDownKey) {
if (isUpKey)
x++;
else
x--;
this.number = x;
e.preventDefault();
}
},
numberChanged: function(e) {
this.$emit("update:modelValue", this.number);
}
}
}
</script>
<template>
<div>
Enter a number (press up or down to modify): <input type="text" v-model="number" @change="numberChanged($event);" @keydown="incrementOrDecrementNumber($event);" />
</div>
</template>
是否可以在组件中更新 this.number
并让它在输入失去焦点时触发 @change
事件?
谢谢!
您 运行 遇到的问题不是由于“keydown
和 change
事件如何在 Vue.js 中协同工作”,实际上与此无关Vue.js 本身,而是 HTML 和 JavaScript 的基本潜在问题。如果用户通过直接与网页中的字段交互更改输入字段的数据,将在输入字段中触发更改事件,因为这会将元素的“脏”标志设置为 true
.
在您的代码中,当用户的按键动作触发更改时,输入值正在内部通过JavaScript更改,这不会触发更改事件,无论是通过 Vue.js 还是通过普通 JavaScript.
进行更改要触发更改事件,您可以通过特定方式更改输入值,例如根据 this answer 在输入元素上使用 setAttribute(value,...)
或直接调用更改事件。
在您自己的代码中,@blur="numberChanged($event)"
可以像我评论中指出的那样工作:
<input
type="text"
v-model="number"
@change="numberChanged($event)"
@blur="numberChanged($event)"
/>
或者您可以根据 Vue.js documentation 使输入值成为组件的“模型”。我还将输入类型设置为数字,以便本机提供输入 up-down 箭头键响应:
<script>
export default {
props: ["modelValue"],
emits: ["update:modelValue"],
},
};
</script>
<template>
<div>
<p>
Enter a number (press up or down to modify):
<input
type="number"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</p>
</div>
</template>