从聚焦到失去焦点,以下事件会根据情况,先后判断是否会执行。
onfocus -> 键盘输入 -> onkeydown -> onkeypress -> onkeyup -> oninput -> 失去焦点 -> onchange -> onblur
无论是用户主动的聚焦行为还是代码的强制聚焦,只要是由失去焦点的状态变为聚焦的状态都会触发这一事件。
<template>
<div class="hello">
<input type="text" @focus="onfocus" ref="input1">
<button @click="focusbtn"> foucs </button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
methods: {
onfocus () {
console.log('聚焦执行')
},
focusbtn () {
// 代码控制聚焦
this.$refs.input1.focus()
}
}
}
</script>
如果本身就是聚焦状态,多次执行聚焦则不会执行
<template>
<div class="hello">
<input type="text" @focus="onfoucs" ref="input1">
<button @click="foucsbtn"> foucs </button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
methods: {
onfoucs () {
console.log('聚焦执行')
},
foucsbtn () {
// 代码控制聚焦,onfoucs只会执行一次
this.$refs.input1.focus()
this.$refs.input1.focus()
this.$refs.input1.focus()
}
}
}
</script>
<template>
<div class="hello">
<input type="text" @focus="onfoucs" ref="input1">
<button @click="foucsbtn"> foucs </button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
methods: {
onfoucs () {
console.log('聚焦执行')
},
foucsbtn () {
// 代码控制聚焦
this.$refs.input1.focus()
this.$refs.input1.blur()
// 失去焦点后再聚焦,onfoucs则会再执行一次
this.$refs.input1.focus()
}
}
}
</script>
这也又一次应证了,只有从失去焦点状态变为聚焦,@focus才会执行。
每一个键的触发都有三个步骤 按下keydown,按住press,抬起keyup,如果有按键输入,keydown会率先触发
<template>
<div class="hello">
<input type="text" @keydown="keydown" @keypress="keypress" @keyup="keyup">
<button @click="foucsbtn"> foucs </button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
methods: {
keydown () {
console.log('按下')
},
keypress () {
console.log('按住')
},
keyup () {
console.log('抬起')
}
}
}
</script>
效果
但是,如果一直按住按键不松手,keydown也会一直执行
每一个键的触发都有三个步骤 按下keydown,按住press,抬起keyup,如果有按键输入,keydown触发后,只要不松开按键,onkeypress 会和onkeydown一起一直触发
每一个键的触发都有三个步骤 按下keydown,按住press,抬起keyup,如果有按键输入,松开按键的一瞬间会触发一次onkeyup事件,一般来说,keydown和keyup选择一个使用就可以了
当input输入框的值发生变化时,就会触发,一般用户输入内容,会变化很多次,如果不做防抖处理,oninput的事件会执行很多次
<template>
<div class="hello">
<input type="text" @input="onInput" @keydown.enter="onEnter">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
methods: {
onEnter () {
console.log('按下enter')
},
onInput () {
console.log('改变了')
}
}
}
</script>
当用户输入完成后,无论是按了一下回车键,还是点击了其它地方,或者代码控制失去焦点,都有可能触发onchange 事件。是否触发的另外一个条件就是,与上一次失去焦点的值相比,此时input框内的值是否发生变化,如果变化了,则触发onchange,没有变化则不触发
<template>
<div class="hello">
<input type="text" @change="onchange">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
methods: {
onchange () {
console.log('改变了')
}
}
}
</script>
这里涉及到开发中常用的另外一个问题,当用户敲击回车键后,onchange事件仍有可能触发。如果input框同时绑定了onchange事件,也绑定了对回车键的监听,如果在按下回车键前,input框的值发生变化,这两个事件一定都会触发。
<template>
<div class="hello">
<input type="text" @change="onchange" @keydown.enter="onEnter">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
methods: {
onEnter () {
console.log('按下enter')
},
onchange () {
console.log('改变了')
}
}
}
</script>
按下enter键虽然没有失去焦点,但也有可能会触发onchange事件
如果开发希望将这两个事件同时绑定,又从功能上要求完全分开,就需要input输入框的值是否发生变化,如果没有发生变化,只会执行回车事件,如果发生了变化,则阻止回车事件,因为onChange会执行
<template>
<div class="hello">
<input type="text" @change="onchange" @keydown.enter="onEnter">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data () {
return {
initValue: ''
}
},
methods: {
onEnter (e) {
const val = e.target.value
if (val === this.initValue) {
// 表示onChange不会执行,所以得执行
console.log('按下enter')
}
},
onchange (e) {
this.initValue = e.target.value
console.log('改变了')
}
}
}
</script>
输入后第一次按下回车,onenter虽然会触发,但我们的不想要执行的console.log并没有执行。
再次多次点击回车,不会再执行onchange,因为值没有变化
再次说明,失去焦点后,会先判断onchange是否执行,再执行onblur
<template>
<div class="hello">
<input type="text" @change="onchange" @keydown.enter="onEnter" @blur="onblur">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data () {
return {
initValue: ''
}
},
methods: {
onEnter (e) {
const val = e.target.value
if (val === this.initValue) {
// 表示onChange不会执行,所以得执行
console.log('按下enter')
}
},
onchange (e) {
this.initValue = e.target.value
console.log('改变了')
},
onblur () {
console.log('失去焦点了')
}
}
}
</script>
当用户输入完成后,无论点击了其它地方,或者代码控制失去焦点,只要有聚焦到失去焦点这一变化,就一定会触发onblur,如果原本就是失去焦点状态,再次失去焦点,onblur事件不会再触发。
<template>
<div class="hello">
<input type="text" @change="onchange" @blur="onblur" ref="input1">
<button @click="clickBtn">失去焦点</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data () {
return {
initValue: ''
}
},
methods: {
clickBtn (e) {
this.$refs.input1.blur()
this.$refs.input1.blur()
this.$refs.input1.blur()
},
onblur () {
console.log('失去焦点了')
}
}
}
</script>
<template>
<div class="hello">
<input type="text" @change="onchange" @blur="onblur" ref="input1">
<button @click="clickBtn">失去焦点</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data () {
return {
initValue: ''
}
},
methods: {
clickBtn (e) {
this.$refs.input1.blur()
this.$refs.input1.blur()
// 如果聚焦后再失去焦点,则会触发一次onblur
this.$refs.input1.focus()
this.$refs.input1.blur()
},
onblur () {
console.log('失去焦点了')
}
}
}
</script>
但是,按下回车,并不会失去焦点,onblur不会触发
<template>
<div class="hello">
<input type="text" @change="onchange" @keydown.enter="onEnter" @blur="onblur">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data () {
return {
initValue: ''
}
},
methods: {
onEnter (e) {
console.log('按下enter')
},
onblur () {
console.log('失去焦点了')
}
}
}
</script>
说明,vue的input输入框事件是从原生的input输入框封装而来的,所以对于原生html input输入框事件,与上述说明一致。