> 文章列表 > 【uniapp索引列表】移动端uniapp使用uni-indexed-list索引列表方法,增加图片头像方法,覆盖全屏解决办法

【uniapp索引列表】移动端uniapp使用uni-indexed-list索引列表方法,增加图片头像方法,覆盖全屏解决办法

【uniapp索引列表】移动端uniapp使用uni-indexed-list索引列表方法,增加图片头像方法,覆盖全屏解决办法

前言

最近做到了一个移动端联系人列表功能
但是不让使用移动端的ui库,只能使用uniapp的组件
所以就发现了这个索引列表组件
但是使用过后发现有一点问题,比如我需要头像,但是他没有自带图片功能。
比如我使用过后,我自定义了导航栏但是被覆盖住了,把导航栏顶没了。
这里我都一一的解决了,所以这里记录一下。

效果图

数据还是用自带的数据模拟了一下,然后图片我随便换了几个试试效果。
【uniapp索引列表】移动端uniapp使用uni-indexed-list索引列表方法,增加图片头像方法,覆盖全屏解决办法

使用方法:按步骤来

1,打开插件市场把这个组件下载安装到自己的项目。这个就不细说了。应该都会吧
【uniapp索引列表】移动端uniapp使用uni-indexed-list索引列表方法,增加图片头像方法,覆盖全屏解决办法
2,进入项目代码,找到这个文件uni-indexed-list.vue
然后更改里面的这个部分。改成我这样。
当然我会把完整代码放下面,直接复制一下也行
【uniapp索引列表】移动端uniapp使用uni-indexed-list索引列表方法,增加图片头像方法,覆盖全屏解决办法

<template><view class="uni-indexed-list" ref="list" id="list"><!-- #ifdef APP-NVUE --><list class="uni-indexed-list__scroll" scrollable="true" show-scrollbar="false"><cell v-for="(list, idx) in lists" :key="idx" :ref="'uni-indexed-list-' + idx"><!-- #endif --><!-- #ifndef APP-NVUE --><scroll-view :scroll-into-view="scrollViewId" class="uni-indexed-list__scroll" scroll-y><view v-for="(list, idx) in lists" :key="idx" :id="'uni-indexed-list-' + idx"><!-- #endif --><indexed-list-item :list="list" :loaded="loaded" :idx="idx" :showSelect="showSelect"@itemClick="onClick"></indexed-list-item><!-- #ifndef APP-NVUE --></view></scroll-view><!-- #endif --><!-- #ifdef APP-NVUE --></cell></list><!-- #endif --><view class="uni-indexed-list__menu" @touchstart="touchStart" @touchmove.stop.prevent="touchMove"@touchend="touchEnd" @mousedown.stop="mousedown" @mousemove.stop.prevent="mousemove"@mouseleave.stop="mouseleave"><view v-for="(list, key) in lists" :key="key" class="uni-indexed-list__menu-item":class="touchmoveIndex == key ? 'uni-indexed-list__menu--active' : ''"><text class="uni-indexed-list__menu-text":class="touchmoveIndex == key ? 'uni-indexed-list__menu-text--active' : ''">{{ list.key }}</text></view></view><view v-if="touchmove" class="uni-indexed-list__alert-wrapper"><text class="uni-indexed-list__alert">{{ lists[touchmoveIndex].key }}</text></view></view>
</template>
<script>import indexedListItem from './uni-indexed-list-item.vue'// #ifdef APP-NVUEconst dom = weex.requireModule('dom');// #endif// #ifdef APP-PLUSfunction throttle(func, delay) {var prev = Date.now();return function() {var context = this;var args = arguments;var now = Date.now();if (now - prev >= delay) {func.apply(context, args);prev = Date.now();}}}function touchMove(e) {let pageY = e.touches[0].pageYlet index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)if (this.touchmoveIndex === index) {return false}let item = this.lists[index]if (item) {// #ifndef APP-NVUEthis.scrollViewId = 'uni-indexed-list-' + indexthis.touchmoveIndex = index// #endif// #ifdef APP-NVUEdom.scrollToElement(this.$refs['uni-indexed-list-' + index][0], {animated: false})this.touchmoveIndex = index// #endif}}const throttleTouchMove = throttle(touchMove, 40)// #endif/* IndexedList 索引列表* @description 用于展示索引列表* @tutorial https://ext.dcloud.net.cn/plugin?id=375* @property {Boolean} showSelect = [true|false] 展示模式* 	@value true 展示模式* 	@value false 选择模式* @property {Object} options 索引列表需要的数据对象* @event {Function} click 点击列表事件 ,返回当前选择项的事件对象* @example <uni-indexed-list options="" showSelect="false" @click=""></uni-indexed-list>*/export default {name: 'UniIndexedList',components: {indexedListItem},emits: ['click'],props: {options: {type: Array,default () {return []}},showSelect: {type: Boolean,default: false}},data() {return {lists: [],winHeight: 0,itemHeight: 0,winOffsetY: 0,touchmove: false,touchmoveIndex: -1,scrollViewId: '',touchmovable: true,loaded: false,isPC: false}},watch: {options: {handler: function() {this.setList()},deep: true}},mounted() {// #ifdef H5this.isPC = this.IsPC()// #endifsetTimeout(() => {this.setList()}, 50)setTimeout(() => {this.loaded = true}, 300);},methods: {setList() {let index = 0;this.lists = []this.options.forEach((value, index) => {if (value.data.length === 0) {return}let indexBefore = indexlet items = value.data.map(item => {let obj = {}obj['key'] = value.letterobj['name'] = item.nameobj['pic'] = item.picobj['itemIndex'] = indexindex++obj.checked = item.checked ? item.checked : falsereturn obj})this.lists.push({title: value.letter,key: value.letter,items: items,itemIndex: indexBefore})})// #ifndef APP-NVUEuni.createSelectorQuery().in(this).select('#list').boundingClientRect().exec(ret => {this.winOffsetY = ret[0].topthis.winHeight = ret[0].heightthis.itemHeight = this.winHeight / this.lists.length})// #endif// #ifdef APP-NVUEdom.getComponentRect(this.$refs['list'], (res) => {this.winOffsetY = res.size.topthis.winHeight = res.size.heightthis.itemHeight = this.winHeight / this.lists.length})// #endif},touchStart(e) {this.touchmove = truelet pageY = this.isPC ? e.pageY : e.touches[0].pageYlet index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)let item = this.lists[index]if (item) {this.scrollViewId = 'uni-indexed-list-' + indexthis.touchmoveIndex = index// #ifdef APP-NVUEdom.scrollToElement(this.$refs['uni-indexed-list-' + index][0], {animated: false})// #endif}},touchMove(e) {// #ifndef APP-PLUSlet pageY = this.isPC ? e.pageY : e.touches[0].pageYlet index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)if (this.touchmoveIndex === index) {return false}let item = this.lists[index]if (item) {this.scrollViewId = 'uni-indexed-list-' + indexthis.touchmoveIndex = index}// #endif// #ifdef APP-PLUSthrottleTouchMove.call(this, e)// #endif},touchEnd() {this.touchmove = false// this.touchmoveIndex = -1},/* 兼容 PC @tian*/mousedown(e) {if (!this.isPC) returnthis.touchStart(e)},mousemove(e) {if (!this.isPC) returnthis.touchMove(e)},mouseleave(e) {if (!this.isPC) returnthis.touchEnd(e)},// #ifdef H5IsPC() {var userAgentInfo = navigator.userAgent;var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];var flag = true;for (let v = 0; v < Agents.length - 1; v++) {if (userAgentInfo.indexOf(Agents[v]) > 0) {flag = false;break;}}return flag;},// #endifonClick(e) {let {idx,index} = elet obj = {}for (let key in this.lists[idx].items[index]) {obj[key] = this.lists[idx].items[index][key]}let select = []if (this.showSelect) {this.lists[idx].items[index].checked = !this.lists[idx].items[index].checkedthis.lists.forEach((value, idx) => {value.items.forEach((item, index) => {if (item.checked) {let obj = {}for (let key in this.lists[idx].items[index]) {obj[key] = this.lists[idx].items[index][key]}select.push(obj)}})})}this.$emit('click', {item: obj,select: select})}}}
</script>
<style lang="scss" scoped>.uni-indexed-list {position: absolute;left: 0;top: 0;right: 0;bottom: 0;/* #ifndef APP-NVUE */display: flex;/* #endif */flex-direction: row;}.uni-indexed-list__scroll {flex: 1;}.uni-indexed-list__menu {width: 24px;/* #ifndef APP-NVUE */display: flex;/* #endif */flex-direction: column;}.uni-indexed-list__menu-item {/* #ifndef APP-NVUE */display: flex;/* #endif */flex: 1;align-items: center;justify-content: center;/* #ifdef H5 */cursor: pointer;/* #endif */}.uni-indexed-list__menu-text {font-size: 12px;text-align: center;color: #aaa;}.uni-indexed-list__menu--active {// background-color: rgb(200, 200, 200);}.uni-indexed-list__menu--active {}.uni-indexed-list__menu-text--active {border-radius: 16px;width: 16px;height: 16px;line-height: 16px;background-color: #007aff;color: #fff;}.uni-indexed-list__alert-wrapper {position: absolute;left: 0;top: 0;right: 0;bottom: 0;/* #ifndef APP-NVUE */display: flex;/* #endif */flex-direction: row;align-items: center;justify-content: center;}.uni-indexed-list__alert {width: 80px;height: 80px;border-radius: 80px;text-align: center;line-height: 80px;font-size: 35px;color: #fff;background-color: rgba(0, 0, 0, 0.5);}
</style>

3,再找到下面的这个文件。uni-indexed-list-item.vue
然后更改这一部分,也就是把图片加进去。
【uniapp索引列表】移动端uniapp使用uni-indexed-list索引列表方法,增加图片头像方法,覆盖全屏解决办法
然后我这里更改了中间ABC的样式,所以大家可以酌情要不要改,反正我觉得原版的有点不好看,就调整了一下
【uniapp索引列表】移动端uniapp使用uni-indexed-list索引列表方法,增加图片头像方法,覆盖全屏解决办法
然后是完整代码也放出来。需要的直接复制。

<template><view><view v-if="loaded || list.itemIndex < 15" class="uni-indexed-list__title-wrapper"><text v-if="list.items && list.items.length > 0" class="uni-indexed-list__title">{{ list.key }}</text></view><view v-if="(loaded || list.itemIndex < 15) && list.items && list.items.length > 0" class="uni-indexed-list__list"><view v-for="(item, index) in list.items" :key="index" class="uni-indexed-list__item" hover-class="uni-indexed-list__item--hover"><view class="uni-indexed-list__item-container" @click="onClick(idx, index)"><view class="uni-indexed-list__item-border" :class="{'uni-indexed-list__item-border--last':index===list.items.length-1}"><view v-if="showSelect" style="margin-right: 20rpx;"><uni-icons :type="item.checked ? 'checkbox-filled' : 'circle'" :color="item.checked ? '#007aff' : '#C0C0C0'" size="24" /></view><view  style="margin-right: 20rpx;"><image :src="item.pic" mode="" style="width:30px;height:30px;"></image></view><text class="uni-indexed-list__item-content">{{ item.name }}</text></view></view></view></view></view>
</template><script>export default {name: 'UniIndexedList',emits:['itemClick'],props: {loaded: {type: Boolean,default: false},idx: {type: Number,default: 0},list: {type: Object,default () {return {}}},showSelect: {type: Boolean,default: false}},methods: {onClick(idx, index) {this.$emit("itemClick", {idx,index})}}}
</script><style lang="scss" scoped>.uni-indexed-list__list {background-color: $uni-bg-color;/* #ifndef APP-NVUE */display: flex;/* #endif */flex-direction: column;border-top-style: solid;border-top-width: 1px;border-top-color: #DEDEDE;}.uni-indexed-list__item {font-size: 14px;/* #ifndef APP-NVUE */display: flex;/* #endif */flex: 1;flex-direction: row;justify-content: space-between;align-items: center;}.uni-indexed-list__item-container {padding-left: 15px;flex: 1;position: relative;/* #ifndef APP-NVUE */display: flex;box-sizing: border-box;/* #endif */flex-direction: row;justify-content: space-between;align-items: center;/* #ifdef H5 */cursor: pointer;/* #endif */}.uni-indexed-list__item-border {flex: 1;position: relative;/* #ifndef APP-NVUE */display: flex;box-sizing: border-box;/* #endif */flex-direction: row;justify-content: space-between;align-items: center;height: 50px;padding: 25px;padding-left: 0;border-bottom-style: solid;border-bottom-width: 1px;border-bottom-color:  #DEDEDE;}.uni-indexed-list__item-border--last {border-bottom-width: 0px;}.uni-indexed-list__item-content {flex: 1;font-size: 14px;color: #191919;}.uni-indexed-list {/* #ifndef APP-NVUE */display: flex;/* #endif */flex-direction: row;}.uni-indexed-list__title-wrapper {/* #ifndef APP-NVUE */display: flex;width: 100%;/* #endif */background-color: #F2F2F2;}.uni-indexed-list__title {padding: 6px 12px;line-height: 16px;font-size: 16px;font-weight: 500;color:#5B5B5B;}
</style>

然后就可以直接使用了

4,传数据的格式
【uniapp索引列表】移动端uniapp使用uni-indexed-list索引列表方法,增加图片头像方法,覆盖全屏解决办法

组件使用方法,出现覆盖其他组件的情况如何解决,比如上面的搜索栏或者自定义导航栏被盖住

完整代码直接发出来看吧
问题点是:
这个组件给自己的最外层盒子加了个定位,在这里
【uniapp索引列表】移动端uniapp使用uni-indexed-list索引列表方法,增加图片头像方法,覆盖全屏解决办法
所以就造成了他是脱离文档流的,然后会导致比如你再上写了其他的组件比如搜索栏,
自定义导航栏之类的东西都不显示了,因为被这个组件顶上去盖住了。
所以我们的解决办法很简单,就是直接在外面套一层view盒子
然后给一个position: relative;就可以限制住这个组件不要乱覆盖别的盒子了。
然后组件的高度我们用uni的方法来计算出动态的高度,最终实现我们需要的效果。

<template><view><!-- 自定义导航栏 --><view class="title_bar"><uni-nav-bar title="通讯录" :statusBar="true" left-icon="bars" @clickLeft="menus"></uni-nav-bar></view><view class="indexlist" :style="{height:height+'px'}"><uni-indexed-list :options="list" :showSelect="false" @click="bindClick"></uni-indexed-list></view></view>
</template><script>export default {data() {return {height:0,list: [{'letter': 'A','data': [{name: '阿里呀',pic: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202003%2F22%2F20200322091214_tuesm.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683339658&t=4a36d3c94d2be9f7f6d29c3ddd350d3c'},{name: '爱',pic: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F4a677e9f-6326-4f5a-b581-c3f2dd2dbb36%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683339701&t=9534d88b7d352b3dad1b4ba7b80ea216'},{name: '阿云',pic: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202005%2F02%2F20200502005351_MfnWJ.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683339726&t=d5fb3b34fb2a91fa65e4d46c3f186cd4'},{name: '阿司',pic: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202101%2F31%2F20210131131407_f4f93.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1683339765&t=3193c93a9dc5d62aa00e7475f34e336f'},{name: '安徽',pic: 'https://img1.baidu.com/it/u=422323813,1539412709&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=485'}]}, {'letter': 'B','data': [{name: '保山机场',pic: '/static/logo.png'},{name: '包头机场',pic: '/static/logo.png'},{name: '北海福成机场',pic: '/static/logo.png'},{name: '北京南苑机场',pic: '/static/logo.png'},{name: '北京首都国际机场',pic: '/static/logo.png'}]}, {'letter': 'C','data': [{name: '长白山机场',pic: '/static/logo.png'},{name: '长春龙嘉国际机场',pic: '/static/logo.png'},{name: '常德桃花源机场',pic: '/static/logo.png'},{name: '昌都邦达机场',pic: '/static/logo.png'},{name: '长沙黄花国际机场',pic: '/static/logo.png'}]}, {'letter': 'D','data': [{name: '大理机场',pic: '/static/logo.png'},{name: '大连周水子国际机场',pic: '/static/logo.png'},{name: '大庆萨尔图机场',pic: '/static/logo.png'},{name: '达州河市机场',pic: '/static/logo.png'},{name: '丹东浪头机场',pic: '/static/logo.png'}]}, {'letter': 'E','data': [{name: '鄂尔多斯机场',pic: '/static/logo.png'},{name: '恩施许家坪机场',pic: '/static/logo.png'},{name: '二连浩特赛乌苏国际机场',pic: '/static/logo.png'}]}, {'letter': 'F','data': [{name: '阜阳西关机场',pic: '/static/logo.png'},{name: '福州长乐国际机场',pic: '/static/logo.png'}]}, {'letter': 'G','data': [{name: '赣州黄金机场',pic: '/static/logo.png'},{name: '格尔木机场',pic: '/static/logo.png'},{name: '固原六盘山机场',pic: '/static/logo.png'},{name: '广元盘龙机场',pic: '/static/logo.png'},{name: '广州白云国际机场',pic: '/static/logo.png'},{name: '桂林两江国际机场',pic: '/static/logo.png'}]}, {'letter': 'H','data': [{name: '哈尔滨太平国际机场',pic: '/static/logo.png'},{name: '哈密机场',pic: '/static/logo.png'},{name: '海口美兰国际机场',pic: '/static/logo.png'},{name: '海拉尔东山国际机场',pic: '/static/logo.png'},{name: '邯郸机场',pic: '/static/logo.png'},{name: '汉中机场',pic: '/static/logo.png'}]}, {'letter': 'I','data': []}, {'letter': 'J','data': [{name: '济南遥墙国际机场',pic: '/static/logo.png'},{name: '济宁曲阜机场',pic: '/static/logo.png'},{name: '鸡西兴凯湖机场',pic: '/static/logo.png'},{name: '佳木斯东郊机场',pic: '/static/logo.png'},{name: '嘉峪关机场',pic: '/static/logo.png'},{name: '景德镇机场',pic: '/static/logo.png'}]}, {'letter': 'K','data': [{name: '喀什机场',pic: '/static/logo.png'},{name: '克拉玛依机场',pic: '/static/logo.png'},{name: '库车龟兹机场',pic: '/static/logo.png'},{name: '库尔勒机场',pic: '/static/logo.png'},{name: '昆明巫家坝国际机场',pic: '/static/logo.png'}]}, {'letter': 'L','data': [{name: '拉萨贡嘎机场',pic: '/static/logo.png'},{name: '兰州中川机场',pic: '/static/logo.png'},{name: '丽江三义机场',pic: '/static/logo.png'},{name: '黎平机场',pic: '/static/logo.png'},{name: '连云港白塔埠机场',pic: '/static/logo.png'}]}, {'letter': 'M','data': [{name: '满洲里西郊机场',pic: '/static/logo.png'},{name: '绵阳南郊机场',pic: '/static/logo.png'},{name: '漠河古莲机场',pic: '/static/logo.png'},{name: '牡丹江海浪机场',pic: '/static/logo.png'}]}, {'letter': 'N','data': [{name: '南昌昌北国际机场',pic: '/static/logo.png'},{name: '南充高坪机场',pic: '/static/logo.png'},{name: '南京禄口国际机场',pic: '/static/logo.png'},{name: '南宁吴圩机场',pic: '/static/logo.png'}]}, {'letter': 'O','data': []}, {'letter': 'P','data': [{name: '普洱思茅机场',pic: '/static/logo.png'}]}, {'letter': 'Q','data': [{name: '齐齐哈尔三家子机场',pic: '/static/logo.png'},{name: '秦皇岛山海关机场',pic: '/static/logo.png'},{name: '青岛流亭国际机场',pic: '/static/logo.png'},{name: '衢州机场',pic: '/static/logo.png'}]}, {'letter': 'R','data': [{name: '日喀则和平机场',pic: '/static/logo.png'}]}, {'letter': 'S','data': [{name: '三亚凤凰国际机场',pic: '/static/logo.png'},{name: '汕头外砂机场',pic: '/static/logo.png'},{name: '上海虹桥国际机场',pic: '/static/logo.png'},{name: '上海浦东国际机场',pic: '/static/logo.png'}]}, {'letter': 'T','data': [{name: '塔城机场',pic: '/static/logo.png'},{name: '太原武宿国际机场',pic: '/static/logo.png'},{name: '台州路桥机场 (黄岩机场)',pic: '/static/logo.png'},{name: '唐山三女河机场',pic: '/static/logo.png'}, {name: '腾冲驼峰机场',pic: '/static/logo.png'},{name: '天津滨海国际机场',pic: '/static/logo.png'},{name: '通辽机场',pic: '/static/logo.png'}]}, {'letter': 'U','data': []}, {'letter': 'V','data': []}, {'letter': 'W','data': [{name: '万州五桥机场',pic: '/static/logo.png'},{name: '潍坊机场',pic: '/static/logo.png'},{name: '威海大水泊机场',pic: '/static/logo.png'},{name: '文山普者黑机场',pic: '/static/logo.png'}, {name: '温州永强国际机场',pic: '/static/logo.png'},{name: '乌海机场',pic: '/static/logo.png'},{name: '武汉天河国际机场',pic: '/static/logo.png'}]}, {'letter': 'X','data': [{name: '西安咸阳国际机场',pic: '/static/logo.png'},{name: '西昌青山机场',pic: '/static/logo.png'},{name: '锡林浩特机场',pic: '/static/logo.png'},{name: '西宁曹家堡机场',pic: '/static/logo.png'}, {name: '西双版纳嘎洒机场',pic: '/static/logo.png'},{name: '厦门高崎国际机场',pic: '/static/logo.png'},{name: '香港国际机场',pic: '/static/logo.png'}]}, {'letter': 'Y','data': [{name: '延安二十里堡机场',pic: '/static/logo.png'},{name: '盐城机场',pic: '/static/logo.png'},{name: '延吉朝阳川机场',pic: '/static/logo.png'},{name: '烟台莱山国际机场',pic: '/static/logo.png'}, {name: '宜宾菜坝机场',pic: '/static/logo.png'},{name: '宜昌三峡机场',pic: '/static/logo.png'},{name: '伊春林都机场',pic: '/static/logo.png'}]}, {'letter': 'Z','data': [{name: '湛江机场',pic: '/static/logo.png'},{name: '昭通机场',pic: '/static/logo.png'},{name: '郑州新郑国际机场',pic: '/static/logo.png'},{name: '芷江机场',pic: '/static/logo.png'}, {name: '重庆江北国际机场',pic: '/static/logo.png'},{name: '中卫香山机场',pic: '/static/logo.png'},{name: '舟山朱家尖机场',pic: '/static/logo.png'}]}]}},mounted() {this.getHeight()},methods: {bindClick(e) {console.log(e);},// 更多菜单menus() {},getHeight() {let that=thisuni.getSystemInfo({success: function(res) {let obj = uni.createSelectorQuery().select('.title_bar')obj.boundingClientRect(function(data) { // data - 各种参数that.height=res.windowHeight-data.height}).exec()}});}}}
</script><style>.indexlist {position: relative;}
</style>