最近做uniapp项目时,用到了IndexedList索引列表这个组件,但是需要添加一个搜索功能,于是呢我就尝试着在组件上面自己改一下。下面我就简单介绍一下:

所需组件

其实也就是两个,首先是indexedLIst索引组件,其次就是搜索框组件了,如果你不显麻烦,搜索框组件你可以自己写。这里我用的searchBar搜索栏组件。
在这里插入图片描述

步骤

1. 下载上面说到的两个组件。最主的要是在indexedList组件中的uni-indexed-list.vue页面中使用搜索框组件,使用组件前记得先引入啊。如图所示。

在这里插入图片描述

import uniSearchBar from '@/components/uni-search-bar/uni-search-bar.vue'
components: {
	uniIcons,
	uniIndexedListItem,
	uniSearchBar
},
<uni-search-bar :radius="30" cancelButton='none' clearButton='auto'
 v-model="searchKey" @input="search"></uni-search-bar>

2. 把搜索框组件添加进去,需要让点空间给他吧。在uni-indexed-list修改top给个空间。

.uni-indexed-list {
	position: absolute;
	left: 0;
	top: 102rpx;
	right: 0;
	bottom: 0;
	/* #ifndef APP-NVUE */
	display: flex;
	/* #endif */
	flex-direction: row;
}

3. 接下来就是搜索得js部分了。我在data里面新增了两个属性:

serchKey :填写的搜索文字(没啥用,保留)
select: showSelect勾选为true时,表示勾选的对象数组
oldLists:最原始的Lists(搜索的时候每次都要改变Lists,如果再次搜索就是在修改后的Lists的基础上再次搜索。明显不太友好吧,所以oldLists保留了原始的Lists)
oldLists是在mounted里面修改的,其实就一行代码。

mounted() {
	setTimeout(() => {
		this.setList()
	}, 50)
	setTimeout(() => {
		this.oldLists = this.lists
		this.loaded = true
	}, 300);
},

搜索部分的代码如下,其实可以给他加个防抖(太简单了,不加了):

search(searchKey) {
		this.lists = []
		// 没有内容时,直接让他变成原始Lists
		if (!searchKey.value) {
			this.lists = this.oldLists
			this.changeBlockOffset()
			return
		}
		let index = 0;
		this.oldLists.forEach(item => {
			let items = item.items.filter(one => one.name.includes(searchKey.value))
			if (items.length > 0) {
				this.lists.push({
					"title": item.title,
					"key": item.key,
					"items": items,
					"itemIndex": index++
				})
			}
		});
		this.changeBlockOffset()
	},

changeBlockOffset方法就是调整右边的索引列表的。setList方法里面都有,我把他写成一个方法了而已。

// 改变右边得索引得winOffsetY,winHeight,itemHeight
changeBlockOffset() {
	// #ifndef APP-NVUE
	uni.createSelectorQuery()
		.in(this)
		.select('#list')
		.boundingClientRect()
		.exec(ret => {
			this.winOffsetY = ret[0].top
			this.winHeight = ret[0].height
			this.itemHeight = this.winHeight / this.lists.length
		})
	// #endif
	// #ifdef APP-NVUE
	dom.getComponentRect(this.$refs['list'], (res) => {
		this.winOffsetY = res.size.top
		this.winHeight = res.size.height
		this.itemHeight = this.winHeight / this.lists.length
	})
	// #endif
},

如果IndexedList中你的showSelect勾选为true时,这个时候你需要修改OnClick代码。如下:

onClick({idx,index}) {
				let obj = {}
				for (let key in this.lists[idx].items[index]) {
					obj[key] = this.lists[idx].items[index][key]
				}
				if (this.showSelect) {
					obj.checked = this.lists[idx].items[index].checked = !this.lists[idx].items[index].checked
					if (obj.checked) {
					// 为真表示勾选,直接push进去
						this.select.push(obj)
					} else {
					// 为假表示取消勾选,找到他然后删掉他
						this.select.splice(this.select.findIndex(item => item.key == obj.key && item.itemIndex == obj.itemIndex), 1)
					}
				}
				this.$emit('click', {
					item: obj,
					select: this.select
				})
			}

总结(觉得上面太繁琐,直接看这里)

其实还是要看上面,只是我总结一下让你更快了解上面的东西。总的来说就是添加一个搜索框,然后再写搜索代码。添加搜索框就是1,2步,先引入,再改一下HTML,CSS。1,2步写那么多也就两行代码。直接复制粘贴上面都有。然后嘛就直接复制search方法,里面没有的oldLists属性,changeBlockOffset方法没有的该怎么加就怎么加,如果showSelect勾选为true,改onClick代码。

最后我也是初入职场的小菜鸡,上面还有很多地方可以优化的,可以建议一下。

再提一嘴

IndexedList索引列表传递的数据格式,形如

[{
    "letter": "A",
    "data": [
        "阿克苏机场",
        "阿拉山口机场",
        "阿勒泰机场",
        "阿里昆莎机场",
        "安庆天柱山机场",
        "澳门国际机场"
    ]
}, {
    "letter": "B",
    "data": [
        "保山机场",
        "包头机场",
        "北海福成机场",
        "北京南苑机场",
        "北京首都国际机场"
    ]
}]

如果你们后台未作处理,需要我们前端处理。你可以参考我的这篇文章中文汉字按拼音排序并按字母分类 uniapp indexedList索引列表数据匹配。这里面讲述了如何将一个名字数组转换为IndexedList索引列表所匹配的数据

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐