@PC端搜索框实现index索引列表功能–代码记录
实现效果
领导提出莫名奇妙的需求,实现效果如上图,直接上代码
父级代码
<el-popover
placement="bottom"
width="250"
v-model="visible">//这里使用的是element-ui组件
<index-list class="indexArea" @closeList='closeList'></index-list>//index索引列表
<el-form-item label="品牌" slot="reference">
<el-input :value="inpVal"></el-input>
</el-form-item>
</el-popover>
index索引列表代码
<template>
<div class="menu">
<div class="city_menu_container" @scroll="onScroll">//滚动区域,滚动事件
<div class="area" v-for="(item,index) in option" :key="index" >
<div class="itemTit" ref="item.letter" :id='item.letter'>{{item.letter}}</div>
<div class="item action" :class="{active_brand: brandIndex === newIndex && wortIndex === index}" v-for="(list,newIndex) in item.data" :key="newIndex" @click="chose(list,index,newIndex)">{{list}}</div>
</div>
</div>
<ul class="city_list_container">
<li v-for="(item,index) in wortList" :key="index" :class="{active: activeIndex === index }" @click="jump(index)">{{item}}</li>
</ul>
</div>
</template>
列表数据格式
通过scroll事件监听滚动
onScroll (e) {
let scrollItems = document.querySelectorAll('.itemTit')
for (let i = scrollItems.length - 1; i >= 0; i--) {
// 判断滚动条滚动距离是否大于当前滚动项可滚动距离
let judge = e.target.scrollTop >= scrollItems[i].offsetTop - scrollItems[0].offsetTop
if (judge) {
this.activeStep = i
break
}
}
},
根据点击侧边栏索引实现指定滚动动画效果
jump (index) {
this.activeIndex = index
let target = document.querySelector('.city_menu_container')
let scrollItems = document.querySelectorAll('.area')
// 判断滚动条是否滚动到底部
if (target.scrollHeight <= target.scrollTop + target.clientHeight) {
this.activeStep = index
}
console.log(this.activeIndex,index);
let roll = scrollItems[index].offsetTop - scrollItems[0].offsetTop // 锚点元素距离其滚动窗口顶部的距离(待滚动的距离)
let distance = document.querySelector('.city_menu_container').scrollTop // 滚动条距离滚动区域顶部的距离
// 滚动条距离滚动区域顶部的距离(滚动区域为窗口)
// 滚动动画实现, 使用setTimeout的递归实现平滑滚动,将距离细分为10小段,10ms滚动一次
// 计算每一小段的距离
let step = roll / 10
if (roll > distance) {
rollDown(target)
} else {
let newTotal = distance - roll
step = newTotal / 10
rollUp(target)
}
// node为滚动区域节点
function rollDown (node) {
if (distance < roll) {
distance += step
node.scrollTop = distance
setTimeout(rollDown.bind(this, node), 10)
} else {
node.scrollTop = roll
}
}
// node为滚动区域节点
function rollUp (node) {
if (distance > roll) {
distance -= step
node.scrollTop = distance
setTimeout(rollUp.bind(this, node), 10)
} else {
node.scrollTop = roll
}
}
}
最后通过调用父组件的方法关闭窗口,并传参
chose(e,index,newIndex) {
this.brandIndex = newIndex
this.wortIndex = index
this.$emit('closeList',e)
},
父组件方法
closeList(val) {
this.inpVal = val
this.visible = false
}
这样基本效果就基本完成了,略有不足,请多多纠正。
时隔这么久,终于对此组件优化了,这里新增了输入筛选,单选多选,数据的双向绑定,查看可访问Vue2搜索框实现indexedList索引列表-锚点跳转,附带数据动态绑定、多选、单选、搜索功能
这里非常感谢 http://www.jb51.net/article/110325.htm 这篇文章带来的启发。