Skip to content

tui-index-list 延迟1200秒,使用不便 #130

@he0xff

Description

@he0xff

`

<scroll-view class="tui-scroll__view" :style="{ height: getHeight }" scroll-y :scroll-top="scrollTop"
@scroll="scroll">





{{ item.letter }}




{{ item.letter }}




{{ item.letter }}








{{ listData[treeItemCur] && listData[treeItemCur].letter }}

<view id="tui_index__letter" class="tui-index__letter" @touchstart.stop="touchStart"
@touchmove.stop.prevent="touchMove" @touchend.stop="touchEnd" @touchcancel.stop="touchEnd">
<view class="tui-letter__item" :class="[index === treeItemCur ? 'tui-letter__cur' : '']"
v-for="(item, index) in listData" :key="index" @tap="letterClick(index,item.letter)">

{{ item.letter }}




<script> let ColorUtil = { rgbToHex(r, g, b) { let hex = ((r << 16) | (g << 8) | b).toString(16); return '#' + new Array(Math.abs(hex.length - 7)).join('0') + hex; }, hexToRgb(hex) { let rgb = []; if (hex.length === 4) { let text = hex.substring(1, 4); hex = '#' + text + text; } for (let i = 1; i < 7; i += 2) { rgb.push(parseInt('0x' + hex.slice(i, i + 2))); } return rgb; }, /** * 生成渐变过渡色数组 {startColor: 开始颜色值, endColor: 结束颜色值, step: 生成色值数组长度} */ gradient(startColor, endColor, step) { // 将hex转换为rgb let sColor = this.hexToRgb(startColor), eColor = this.hexToRgb(endColor); // 计算R\G\B每一步的差值 let rStep = (eColor[0] - sColor[0]) / step, gStep = (eColor[1] - sColor[1]) / step, bStep = (eColor[2] - sColor[2]) / step; let gradientColorArr = []; for (let i = 0; i < step; i++) { // 计算每一步的hex值 gradientColorArr.push(this.rgbToHex(parseInt(rStep * i + sColor[0]), parseInt(gStep * i + sColor[1]), parseInt(bStep * i + sColor[2]))); } return gradientColorArr; }, /** * 生成随机颜色值 */ generateColor() { let color = '#'; for (let i = 0; i < 6; i++) { color += ((Math.random() * 16) | 0).toString(16); } return color; } }; export default { name: 'tuiIndexList', emits: ['letterClick'], props: { // 数据源 listData: { type: Array, default () { return []; } }, // 顶部高度 top: { type: Number, default: 0 }, // 底部高度 bottom: { type: Number, default: 0 }, //top和bottom单位,可传rpx 或 px unit: { type: String, default: 'px' }, //sticky letter 是否显示上边线条 topLine: { type: Boolean, default: true }, //sticky letter 是否显示下边线条 bottomLine: { type: Boolean, default: true }, height: { type: String, default: '60rpx' }, color: { type: String, default: '#666' }, activeColor: { type: String, default: '' }, size: { type: String, default: '26rpx' }, background: { type: String, default: '#ededed' }, activeBackground: { type: String, default: '#FFFFFF' }, padding: { type: String, default: '0 20rpx' }, keyColor: { type: String, default: '#666' }, activeKeyColor: { type: String, default: '#FFFFFF' }, activeKeyBackground: { type: String, default: '' }, //重新初始化[可异步加载时使用,设置大于0的数] reinit: { type: Number, default: 0 } }, computed: { getHeight() { return `calc(100vh - ${this.top + this.bottom + this.unit})`; }, getChange() { return `${this.top}-${this.bottom}-${this.reinit}`; }, getActiveColor(){ return this.activeColor || (uni && uni.$tui && uni.$tui.color.primary) || '#5677fc' }, getActiveKeyBgColor(){ return this.activeKeyBackground || (uni && uni.$tui && uni.$tui.color.primary) || '#5677fc' } }, watch: { listData(val) { this.init(); }, getChange(val) { this.init(); } }, data() { return { remScale: 1, // 缩放比例 realTop: 0, // 计算后顶部高度实际值 realBottom: 0, // 计算后底部高度实际值 treeInfo: { // 索引树节点信息 treeTop: 0, treeBottom: 0, itemHeight: 0, itemMount: 0 }, indicatorTopList: [], // 指示器节点信息列表 maxScrollTop: 0, // 最大滚动高度 blocks: [], // 节点组信息 /* 渲染数据 */ treeItemCur: -1, // 索引树的聚焦项 listItemCur: -1, // 节点树的聚焦项 touching: false, // 是否在触摸索引树中 scrollTop: 0, // 节点树滚动高度 indicatorTop: -1, // 指示器顶部距离 treeKeyTran: false, background_cur: '', color_cur: '', background_next: '', color_next: '', colors: [], backgroundColors: [] }; }, methods: { scroll(e) { if (this.touching) return; let scrollTop = e.detail.scrollTop; if (scrollTop > this.maxScrollTop) return; let blocks = this.blocks, stickyTitleHeight = this.remScale * 30; let len = blocks.length - 1; this.background_cur = this.background; this.color_cur = this.color; for (let i = len; i >= 0; i--) { let block = blocks[i]; // 判断当前滚动值 scrollTop 所在区间, 以得到当前聚焦项 if (scrollTop >= block.itemTop && scrollTop < block.itemBottom) { // 判断当前滚动值 scrollTop 是否在当前聚焦项底一个 .block__title 高度范围内, 如果是则开启过度色值计算 if (scrollTop > block.itemBottom - stickyTitleHeight) { let percent = Math.floor(((scrollTop - (block.itemBottom - stickyTitleHeight)) / stickyTitleHeight) * 100); this.background_cur = this.backgroundColors[percent]; this.color_cur = this.colors[percent]; this.background_next = this.backgroundColors[100 - percent]; this.color_next = this.colors[100 - percent]; this.treeItemCur = i; this.listItemCur = i; } else if (scrollTop <= block.itemBottom - stickyTitleHeight) { this.background_cur = this.activeBackground; this.color_cur = this.getActiveColor; this.background_next = this.background; this.color_next = this.color; this.treeItemCur = i; this.listItemCur = i; } break; } } }, /** * tree 触摸开始 */ touchStart(e) { // 获取触摸点信息 let startTouch = e.changedTouches[0]; if (!startTouch) return; this.touching = true; let treeItemCur = this.getCurrentTreeItem(startTouch.pageY); this.setValue(treeItemCur); }, /** * tree 触摸移动 */ touchMove(e) { // 获取触摸点信息 let currentTouch = e.changedTouches[0]; if (!currentTouch) return; // 滑动结束后迅速开始第二次滑动时候 touching 为 false 造成不显示 indicator 问题 if (!this.touching) { this.touching = true; } let treeItemCur = this.getCurrentTreeItem(currentTouch.pageY); this.setValue(treeItemCur); }, /** * tree 触摸结束 */ touchEnd(e) { let treeItemCur = this.treeItemCur; let listItemCur = this.listItemCur; if (treeItemCur !== listItemCur) { this.treeItemCur = listItemCur; this.indicatorTop = this.indicatorTopList[treeItemCur]; } this.treeKeyTran = true; setTimeout(() => { this.touching = false; this.treeKeyTran = false; }, 300); }, letterClick(index, letter) { // #ifdef H5 this.setValue(index); this.touchEnd() // #endif this.$emit('letterClick', { index: index, letter: letter }) }, /** * 获取当前触摸的 tree-item * @param pageY: 当前触摸点pageY */ getCurrentTreeItem(pageY) { let { treeTop, treeBottom, itemHeight, itemMount } = this.treeInfo; if (pageY < treeTop) { return 0; } else if (pageY >= treeBottom) { return itemMount - 1; } else { return Math.floor((pageY - treeTop) / itemHeight); } }, /** * 触摸之后后设置对应value */ setValue(treeItemCur) { if (treeItemCur === this.treeItemCur) return; let block = this.blocks[treeItemCur]; if (!block) return; let { scrollTop, scrollIndex } = block, indicatorTop = this.indicatorTopList[treeItemCur]; this.background_cur = this.activeBackground; this.color_cur = this.getActiveColor; this.background_next = this.background; this.color_next = this.color; this.treeItemCur = treeItemCur; this.scrollTop = scrollTop; this.listItemCur = scrollIndex; this.indicatorTop = indicatorTop; }, /** * 清除参数 */ clearData() { this.treeItemCur = 0; // 索引树的聚焦项 this.listItemCur = 0; // 节点树的聚焦项 this.touching = false; // 是否在触摸索引树中 this.scrollTop = 0; // 节点树滚动高度 this.indicatorTop = -1; // 指示器顶部距离 this.treeKeyTran = false; this.background_cur = this.background; this.color_cur = this.color; this.background_next = this.background; this.color_next = this.color; }, /** * 初始化获取 dom 信息 */ initDom() { let { windowHeight, windowWidth } = uni.getSystemInfoSync(); let remScale = (windowWidth || 375) / 375, realTop = (this.top * remScale) / 2, realBottom = (this.bottom * remScale) / 2, colors = ColorUtil.gradient(this.getActiveColor, this.color, 100), backgroundColors = ColorUtil.gradient(this.activeBackground, this.background, 100); this.remScale = remScale; this.realTop = realTop; this.realBottom = realBottom; this.colors = colors; this.backgroundColors = backgroundColors; uni.createSelectorQuery() .in(this) .select('#tui_index__letter') .boundingClientRect(res => { let treeTop = res.top, treeBottom = res.top + res.height, itemHeight = res.height / this.listData.length, itemMount = this.listData.length; let indicatorTopList = this.listData.map((item, index) => { return itemHeight / 2 + index * itemHeight + treeTop - remScale * 25; }); this.treeInfo = { treeTop: treeTop, treeBottom: treeBottom, itemHeight: itemHeight, itemMount: itemMount }; this.indicatorTopList = indicatorTopList; }) .exec(); uni.createSelectorQuery() .in(this) .select('.tui-content__box') .boundingClientRect(res => { let maxScrollTop = res.height - (windowHeight - realTop - realBottom); uni.createSelectorQuery() .in(this) .selectAll('.tui-item__select') .boundingClientRect(res => { let maxScrollIndex = -1; let blocks = res.map((item, index) => { // Math.ceil 向上取整, 防止索引树切换列表时候造成真机固定头部上边线显示过粗问题 let itemTop = Math.ceil(item.top - realTop), itemBottom = Math.ceil(itemTop + item.height); if (maxScrollTop >= itemTop && maxScrollTop < itemBottom) maxScrollIndex = index; return { itemTop: itemTop, itemBottom: itemBottom, scrollTop: itemTop >= maxScrollTop ? maxScrollTop : itemTop, scrollIndex: maxScrollIndex === -1 ? index : maxScrollIndex }; }); this.maxScrollTop = maxScrollTop; this.blocks = blocks; }) .exec(); }) .exec(); }, /** * 初始化 */ init() { this.clearData(); // 避免获取不到节点信息报错问题 if (this.listData.length === 0) { return; } // 异步加载数据时候, 延迟执行 initDom 方法 setTimeout(() => this.initDom(), 1200); } }, mounted() { this.$nextTick(()=>{ this.init(); }) } }; </script> <style scoped> .tui-index-list { width: 100vw; overflow: hidden; position: relative; } .tui-scroll__view { width: 100vw; } .tui-content__box { position: relative; width: 100%; } .tui-content__title { position: sticky; top: 0; z-index: 10; font-weight: bold; } .tui-content__title .tui-title__item { width: 100%; position: relative; display: flex; align-items: center; } .tui-line__top::before { content: ' '; position: absolute; top: 0; right: 0; left: 0; border-top: 1px solid #ebedf0; -webkit-transform: scaleY(0.5) translateZ(0); transform: scaleY(0.5) translateZ(0); transform-origin: 0 0; z-index: 2; pointer-events: none; } .tui-line__bottom::after { content: ' '; position: absolute; border-bottom: 1px solid #ebedf0; -webkit-transform: scaleY(0.5) translateZ(0); transform: scaleY(0.5) translateZ(0); transform-origin: 0 100%; bottom: 0; right: 0; left: 0; } .tui-index__indicator { position: fixed; right: 100rpx; width: 100rpx; height: 100rpx; line-height: 100rpx; border-radius: 10rpx; text-align: center; color: #ffffff; font-size: 60rpx; font-weight: bold; display: none; z-index: 10; } .tui-index__indicator:after { content: ''; position: absolute; top: 0; right: 0; width: 100%; height: 100%; z-index: -1; border-radius: 100% 0% 100% 100%; background: #c9c9c9; transform: rotate(45deg); } .tui-indicator__show { display: block; z-index: 10; } .tui-indicator__tran { display: block; opacity: 0; transition: opacity 0.3s linear; } .tui-index__letter { position: fixed; right: 0; top: 50%; transform: translateY(-50%); text-align: center; z-index: 10; } .tui-letter__item { padding: 0 8rpx; font-weight: bold; } .tui-letter__key { width: 40rpx; height: 40rpx; border-radius: 50%; font-size: 26rpx; transform: scale(0.8); transform-origin: center center; display: flex; align-items: center; justify-content: center; } .tui-list__item { width: 100%; display: flex; align-items: center; } .tui-list__item .tui-avatar { width: 68rpx; height: 68rpx; border-radius: 8rpx; flex-shrink: 0; background-color: #ccc; } .tui-list__item view { width: 90%; font-size: 32rpx; padding-left: 20rpx; padding-right: 40rpx; box-sizing: border-box; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } </style>

` 源码中 setTimeout(() => this.initDom(), 1200); 这个延迟会导致页面上通讯录显示的时候有卡顿的感觉,请问这个怎么调整,为什么是1200

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions