在 vue 项目中, 需要实现某些特定的功能时, 使用 mvvm 模式不易实现. 因此引入 jQuery 包来完成需求
jQuery 中的触发事件可以自己定义在 mounted 中, 如果需要使用 vue 中 data 的数据, 直接使用 this.msg 是无法使用的, 需要另外定义 const _this = this,
存储 this. 之后便可以在事件中使用_this.msg 数据了.
需求: 在品牌处可以输入, 并且会有模糊搜索的下拉框, 也可下拉选择, 在输入完毕后检验值是否在下拉框中存在, 聚焦时蓝色边框, change 时如果不存在则红框显示, 存在的话就绿框提示,(就是带输入建议的输入框)
问题: 使用 element-ui 中的 el-autocomplete 组件, 开始通过失焦事件来验证, 但是如果选择了下拉框某个值时 (选中后会将下拉框的值赋给上面的输入框), 失焦事件触发会在赋值之前, 因此拿失焦时输入框的值来进行判断时错误的, 在先改变输入框的值后再去选择下拉框, change 事件有同样的 bug, 没办法只能自己引入 jQuery 来完成
点击输入框后, 通过 placeholder 判断是否是品牌下的的输入框, 因为每个输入框都有这个类, 如果是的话则增加一个类名, 如果第一次点击的位置和第二次鼠标点击的位置都是品牌下的输入框, 则执行相应的逻辑判断,
在逻辑执行完后就删除其他处同样的类名 inputList
- const _this = this
- $('body').delegate('.el-input__inner', 'focus', function(e) { // 因为是动态生成的, 所以选择这种方式来监听事件
- if (e.target.placeholder === '请输入品牌') { // 当聚焦在品牌输入框时触发
- $(this).addClass('inputList') // 加上一个类名 inputList
- if ($('.inputList').length === 2) { // 判断下一次点击的位置, 当从第一个输入框改值后下一个聚焦位置还是品牌下的输入框时
- if (!$('.inputList').not(this).val()) {
- $('.inputList').not(this).CSS('border', '1px solid #67c23a')
- } else {
- let num = 0
- for (let j = 0; j < _this.goodsBrands.length; j++) {
- if ($('.inputList').not(this).val() === _this.goodsBrands[j].value) {
- num += 1
- break
- }
- }
- if (num === 0) {
- _this.$message.error('输入的品牌不在品牌列表中')
- $('.inputList').not(this).CSS('border', '1px solid #F56C6C')
- } else {
- $('.inputList').not(this).CSS('border', '1px solid #67c23a')
- }
- }
- }
- $('.el-input__inner').not(this).removeClass('inputList') // 逻辑执行完之后删除当前聚焦位置以外的 inputList 类, 这样就保持. inputList 长度最多为 2
- }
- })
此处是为了模拟出输入框的 change 事件, 因为在聚焦时会添加 inputList 这个类名. 所以这里可以判断是否是自己想要的位置, 如果是的话给一个标志位 getindex, 当点击到品牌下的输入框时, 如果第二次的点击位置不是品牌其他位置的输入框, 则进行逻辑判断
- $(document).click(function(e) { // focus 触发时也会触发这个事件, 并且触发在 focus 事件之后
- if (e.target.classList[1] === 'inputList') { // 判断是否点击在对应位置
- _this.getIndex = 1 // 用于标志在聚焦事件触发后的下一次点击是否同样会触发聚焦, 如果是则把第二次点击当成第一次重新判断, 等到下一次点击再来判断
- } else {
- if (_this.getIndex === 1) {
- if (!$('.inputList').eq(0).val()) {
- $('.inputList').eq(0).CSS('border', '1px solid #67c23a')
- } else {
- let num = 0
- for (let j = 0; j < _this.goodsBrands.length; j++) {
- if ($('.inputList').eq(0).val() === _this.goodsBrands[j].value) {
- num += 1
- break
- }
- }
- if (num === 0) {
- _this.$message.error('输入的品牌不在品牌列表中')
- $('.inputList').eq(0).CSS('border', '1px solid #F56C6C')
- } else {
- $('.inputList').eq(0).CSS('border', '1px solid #67c23a')
- }
- }
- $('.el-input__inner').removeClass('inputList')
- _this.getIndex = 0 // 每次第二次点击了其他位置时, getIndex 重新计数
- }
- }
- })
小白一枚, 如果有其他更好的方法, 欢迎各位同行指教, 多多交流
来源: https://www.cnblogs.com/cazj/p/10870624.html