实现实时查询并带有查询结果列表的输入框

这个功能主要是实现了一个可以实时查询结果的搜索框,并具备点击外部关闭搜索结果框体的功能,除了v-show和transition依托于vue实现以外其余功能都基于原生JS实现。
效果图:
在这里插入图片描述

该功能的实现主要是很久之前面试被问到过,当时没有做出来,现在兜兜转转又碰到了这个需求,索性一次性写完整,刚好新学到了composition系列事件,
首先解释一下composition系列事件,这个系列事件分为三种类型
conpositionstart在MDN中,对该事件的定义为:文本合成系统(输入法编辑器)开始新的输入合成时会触发,通俗来说就是在中文输入法开始输入时,该事件就会触发,例图如下
在这里插入图片描述
conpositionupdate该事件是文本合成系统更新输入时会触发,例图如下
在这里插入图片描述
conpositionend该事件在MDN中的定义是当文本段落的组成完成或取消时(敲下回车或者空格),compositionend 事件将被触发,例图如下
在这里插入图片描述
敲击回车后
在这里插入图片描述
实现思路:既然可以获取到用户输入的三种状态,那么就需要声明一个变量用来保存输入状态,最后在监听Input事件的回调中,根据输入状态来实现功能。而且在调试过程中发现,同为同步任务的情况下,compositionend事件的触发是要先于input事件的,那么就表明,在input事件触发的时候,一定可以通过compositionend来将用户的输入状态更新为最新状态。这就给开发带来了很大的便利。

使用composition系列事件不同于监听input事件+防抖的地方在于,如果是正在输入的情况,那么input事件在延时到期后就会触发而不会考虑到此时用户是否已经完成输入而需要触发,而composition事件在没有选择备用词或者没有按下空格/回车是不会触发的,从状态管理的角度来看,状态之间的转移更为清晰可控。
该功能主要针对的点还是在于调起文本合成器输入的情况,如果是普通的连续输入数字/英文/英文+数字的场景,则只用基本的防抖+监听input即可。
HTML部分

<van-field>
  <template #input>
    <label>
      <input name="projectName">
    </label>
  </template>
</van-field>
<transition name="van-fade">
  <div v-show="visible" class="projectList">
    <div class="van-ellipsis listItem" v-for="item in 8">
      项目{{item}}
    </div>
  </div>
</transition>

JS部分,Vue只需要声明一个变量则不再赘述

const inputDom = document.querySelector('input[name="projectName"]')
      let typing = false // 初始化为false,保证用户在连续输入英文/数字的情况下也可以正常进入input逻辑
      function handleEvent(event) {
        if (event.type === 'compositionstart') {
          typing = true
        }
        if (event.type === 'compositionend') {
          console.log('compositionend触发了')
          // 可以在这里给备选list赋值
          typing = false
        }
        if (event.type === 'input' && typing === false) {
          console.log(event.target.value);
          console.log('input触发了')
          // 可以在这里调用接口
          vm.projectData.name = inputDom.value
          vm.visible = !!event.target.value
        }
        if (event.type === 'click' && !!inputDom.value) {
          vm.visible = true
        }
      }
      inputDom.addEventListener("input", debounce(handleEvent, 1000));
      inputDom.addEventListener("compositionstart", handleEvent);
      inputDom.addEventListener("compositionend", handleEvent);
      inputDom.addEventListener('click', handleEvent)

      document.addEventListener('click', (e) => {
        if (!inputDom.contains(e.target)) {
          vm.visible = false
        }
      })
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值