vue项目input标签checkbox,change和click绑定事件的区别

前言

我们经常在vue开发项目的过程中,遇到需要对input框使用v-modal的这种情况,在有的时候,不光需要双向数据绑定,还需要在改变数据之后绑定其它的操作,那么问题来了,你是使用@change绑定事件还是使用@click绑定事件

开发中遇到的问题

建议不要通过click绑定事件,对待input标签,最好通过change来触发,本人血的教训。

<input @change="inputchecked" class="goods-checked" 
v-model="shopcargoods[index].checked" type="checkbox" />

click执行的时间要早于change执行的时间,因为v-modal的时间是一个异步的。
当点击之后,v-modal可能还没有来得及将绑定在data里面的数据改变,click绑定的事件就执行了,这会导致click绑定事件里面拿到的data数据不是最新的。

总结

change绑定的事件是一定要等到input框的value值改变之后才会被触发。

关于这一系列的顺序我是这样理解

点击input框
click事件生效
v-modal改变绑定的data数据
渲染到页面上改变input的value值
change事件生效

扩展

input标签 从聚焦到失去焦点,以下事件会根据情况,先后判断是否会执行。

onfocus -> 键盘输入 -> onkeydown -> onkeypress -> onkeyup -> oninput -> 失去焦点 -> onchange -> onblur

onfocus 聚焦事件

无论是用户主动的聚焦行为还是代码的强制聚焦,只要是由失去焦点的状态变为聚焦的状态都会触发这一事件。

<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才会执行。

onkeydown 键盘按键按下事件

每一个键的触发都有三个步骤 按下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也会一直执行

效果
在这里插入图片描述

onkeypress 键盘按键按住事件

每一个键的触发都有三个步骤 按下keydown,按住press,抬起keyup,如果有按键输入,keydown触发后,只要不松开按键,onkeypress 会和onkeydown一起一直触发
在这里插入图片描述

onkeyup 键盘按键松开事件

每一个键的触发都有三个步骤 按下keydown,按住press,抬起keyup,如果有按键输入,松开按键的一瞬间会触发一次onkeyup事件,一般来说,keydown和keyup选择一个使用就可以了

oninput 输入值变化事件

当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>

在这里插入图片描述
按下回车键这个行为不会触发oninput事件
在这里插入图片描述

onchange 失去焦点后的输入值变化事件

当用户输入完成后,无论是按了一下回车键,还是点击了其它地方,或者代码控制失去焦点,都有可能触发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,如果原本就是失去焦点状态,再次失去焦点,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输入框事件,与上述说明一致。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可缺不可滥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值