首页 > 编程知识 正文

vue 输入框,vue文本输入框怎么写

时间:2023-05-05 14:53:52 阅读:282853 作者:3392

1.实现的功能

输入框输入字符后,联想词列表出现,可以按“↓”或“↑”选择列表中的内容,也可以鼠标点选,且互相不影响选择样式,即只会出现一个被选中,“Enter”键发起检索。

2.DOM结构 <template> <div class="input-m"> <div class="search"> <input type="text" :placeholder=placeholder v-model="content" @keyup="input"> </div> <ul class="associate-list" v-show="associateWords&&showList" @mouseout="selectedLi(0)"> <li class="associate-item">{{inputContent}}</li> <li class="associate-item" v-for="(item,index) of associateWords" :key="index" @mouseover="selectedLi(index+1)">{{item}}</li> </ul> </div></template>复制代码

3.变量 content: '',---双向绑定的数据,input输入框中的内容,用户选择联想词列表时同步变化 inputContent: '',---保存用户通过键盘输入的内容,不与用户选择的联想词列表同步变化 focusIndex: 0,---用户选择的联想词<li>列表的下标 associateWords: [],---联想词列表数组 showList: true---是否显示联想词列表由此变量和associateWords的长度共同控制

inputConent是用于记录用户通过键盘输入的内容,通过上下键选择或鼠标悬浮时选择的会通过双向绑定同步到content中,以百度搜索联想词列表为例,当用户一直按向下键时,超过联想词列表后,input框中的内容为用户最开始输入的内容。

focusIndex记录用户选择的<li>标签的下标,当一直按向上或向下键时,会出现focusIndex超出<li>列表长度的或小于0的清理,用focusIndex = (focusIndex+length)%length操作,可以实现fousIndex总是在0至length-1范围内。

当通过document.getElementsByClassName获取<li>数组时,数组下标从0开始,而foucusIndex初始值为0,当按下“↓”时,focusIndex+1,选中的就是<li>列表的下标为1的元素,即第2个<li>,这是不合理的。

如果将focusIndex的下标初始值设为-1,满足了上边的需求。那么当按下“↑”时,focusIndex-1,通过取余操作可以得到foucusIndex = length-2,即<li>列表的倒数第2项,也是不合理的。

故将用户输入的文字内容作为<li>列表的第一项,且隐藏,将focusIndex初始值设为0。这样就实现了按上下键选择,且超出显示的长度时,是用户通过键盘输入的内容。

用showList与associateWords一起控制列表的显示,没有相关联想词时肯定不显示,但用户点击输入框以外的位置时,联想词列表应该可以隐藏。如果采用将associateWords来隐藏的话,用户再次点击输入框时,会多向服务器发送一次搜索相关联想词的请求。

4.JavaScript部分

input (e) { //keyup事件的event e = e || window.event this.showList = true // 按“↑” 键 if (e.keyCode === 38) { this.focusIndex-- this.selectedLi() } else if (e.keyCode === 40) { // 按“↓”,数组下标从0开始,list的[0]项内容为用户输入内容,不显示,从[1]项开始显示 this.focusIndex++ this.selectedLi() } else if (e.keyCode === 13) { // 按“Enter”调用搜索函数 this.doSomething() //----向后台发送搜索请求 this.associateWords = [] } else { // 用户继续输入时,将inputContent置空----非常重要的一步 this.inputContent = '' this.focusIndex = 0 // 搜索联想内容 this.getAssociateWords() //----向后台请求相关联想词列表 this.clearSelected() } }复制代码

与样式相关的js操作

selectedLi (hoverIndex) { // 当inputContent内容为空时,记录下搜索框中用户输入的内容,作为associate-item的第一项 if (this.inputContent === '') { this.inputContent = this.content } let associateList = document.getElementsByClassName('associate-item') // 移除已添加的.selected样式 for (var i = 0; i < associateList.length; i++) { associateList[i].classList.remove('selected') } if (hoverIndex !== undefined) { this.focusIndex = hoverIndex } // 一直按向下键超出联想内容li长度时,应回到联想内容第一个 this.focusIndex = (this.focusIndex + associateList.length) % associateList.length // 为选中的li添加.selected样式 let selectedOne = associateList[this.focusIndex] this.content = selectedOne.textContent selectedOne.classList.add('selected') }clearSelected () { let associateList = document.getElementsByClassName('associate-item') // 移除已添加的.selected样式 for (var i = 1; i < associateList.length; i++) { associateList[i].classList.remove('selected') } }复制代码

为除了input框以外的页面部分添加监听事件,点击input以外的部分时,隐藏联想词列表

// 点击input输入框以外的位置时 隐藏联想词列表 document.body.addEventListener('click', e => { if (e.target.nodeName === 'INPUT') { this.showList = true } else { this.showList = false } })复制代码

向后台服务器请求联想词列表

getAssociateWords () { let self = this axios.get('XX/data.json').then(function (res) { self.associateWords = result.slice(0, 5) }) }复制代码


版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。