小程序字母检索列表
先上效果
沒錯看著界面很像黃軼老師webapp的,其實就是想用小程序實現一個,可以根據界面滾動位置字母也實時高亮,也可以點擊字母索引跳轉到對應的位置。沒有使用scroll-view組件,因為不可能什么功能都有現成的。話不多說下面上代碼
1、處理后臺返回數據
先看下后臺返回的數據是什么樣子的,原來是這樣子的(大家看到效果圖上第一個是周董,因為這是我手動添加的,周董必須放在第一位哦)
有時候啊,后臺看心情還不一定給你返回A-Z的字母呢,說不定返回了還不給你排序(我就遇到過),所以呢我還是自己處理了一遍,這是處理后的數據
這里說一下思路吧
(tips:最好做一個判斷,如果后臺返回的數據為空或者返回錯誤的狀態碼,直接return,防止報錯)
好了,處理數據就說到這里,大家那么聰明的程序員應該都能處理好數據
2、編寫基礎頁面
wxml代碼
<!--components/SingerList/SingerList.wxml--> <view class="index-list"><view id="groupRef"><view wx:for="{{data}}" wx:key="title" class="group"><view id="{{item.title}}" class="title">{{item.title}}</view><view><view wx:for="{{item.list}}" wx:key="id" wx:for-item="t" class="item"><image class="avatar" src="{{t.pic}}" lazy-load="{{true}}" /><span class="name">{{t.name}}</span></view></view></view></view><!-- <div class="fixed" v-show="fixedTitle" :style="fixedStyle"><div class="fixed-title">{{fixedTitle}}</div></div> --><view class="shortcut"><view><viewwx:for="{{data}}"wx:key="index"data-id="{{item.title}}"data-index="{{index}}"catchtap="onScrollTo"class="shortcut-item {{curIndex === index ? 'active': ''}}">{{item.title}}</view></view></view> </view>wxss代碼
/* components/SingerList/SingerList.wxss */ .index-list {position: relative;width: 100%;height: 100%;overflow: hidden;background: #222; } .group {padding-bottom: 30rpx; } .title {height: 60rpx;line-height: 60rpx;padding-left: 20rpx;font-size: 24rpx;color: rgba(255, 255, 255, 0.5);background-color: #333; } .item {display: flex;align-items: center;padding: 40rpx 0 0 40rpx; } .avatar {width: 100rpx;height: 100rpx;border-radius: 50%; } .name {margin-left: 40rpx;color: rgba(255, 255, 255, 0.5);font-size: 28rpx; } .fixed {position: absolute;top: 0;left: 0;width: 100%; } .fixed-title {height: 60rpx;line-height: 60rpx;padding-left: 40rpx;font-size: 24rpx;color: rgba(255, 255, 255, 0.5);background: #333; } .shortcut {position: fixed;right: 18rpx;top: 50%;transform: translateY(-50%);width: 40rpx;padding: 40rpx 0;border-radius: 20rpx;text-align: center;background-color: rgba(0, 0, 0, 0.3);font-family: Helvetica; } .shortcut-item {padding: 3px;line-height: 1;color: rgba(255, 255, 255, 0.5);font-size: 24rpx; } .active {color: #ffcd32; }3、處理邏輯部分(數據請提前在data中定義好)
1、首先這個組件接👋兩個數據
scrollTop即父組件實時滾動的top值
2、剛進入頁面的時候我們需要獲取group類中的dom信息,這是為了滾動高亮顯示字母做準備
pageLifetimes: {show() {const groupRef = wx.createSelectorQuery().in(this)groupRef.selectAll('.group').boundingClientRect(rect => {const listHeights = rect.map(item => item.top)this.setData({listHeights,groupRef: rect})}).exec()}},3、先處理點擊字母跳轉到對應位置
methods: {onScrollTo({currentTarget: {dataset}}) {const {id, index} = datasetconst query = wx.createSelectorQuery().in(this)// 這里的動態id就是我們在wxml中給每個item綁定的idquery.select(`#${dataset.id}`).boundingClientRect(rect => {this.setData({curIndex: index})this.triggerEvent('scrollY', {scrollTop: rect.top,alphaId: id})}).exec()}, }然后在父組件中接受不了子組件傳來的值,并進行跳轉。為什么不在子組件中完成這個邏輯,
因為這個列表組件只是為了渲染,任何功能性的都會放在父組件中處理
4、處理滾動頁面時,字母高亮
在模板中,我們是使用index作為標志來顯示高亮的(你也可以使用title),現在我們要監聽scrollTop的值,計算每一項列表的高度區間;然后用新的scrollTop和高度區間的top、bottom進行一個判斷
observers: {data() {this.calculate() },scrollTop(newVal) {const singersVal = this.data.listHeights// 在最開始的時候push了一個0,這里就需要-1,相對應for (let i = 0; i < singersVal.length - 1; i++) {const heightTop = singersVal[i]const heightBottom = singersVal[i + 1]console.log(heightTop)if (newVal >= heightTop && newVal <= heightBottom) {this.setData({curIndex: i})}}}},methods: {// 計算每一項列表的高度區間calculate() {const {listHeights, groupRef} = this.data// 區間高度let height = 0// 每次計算前都要先清空,從0開始listHeights.length = 0listHeights.push(height)for (let i = 0; i < groupRef.length; i++) {height += groupRef[i].heightlistHeights.push(height)}this.setData({listHeights})}}完整代碼
// components/SingerList/SingerList.js Component({properties: {data: {type: Array,value: []},scrollTop: {type: Number,value: 0}},data: {defaultId: '熱',curIndex: 0,listHeights: [],groupRef: []},pageLifetimes: {show() {const groupRef = wx.createSelectorQuery().in(this)groupRef.selectAll('.group').boundingClientRect(rect => {const listHeights = rect.map(item => item.top)this.setData({listHeights,groupRef: rect})}).exec()}},observers: {data() {this.calculate() },scrollTop(newVal) {const singersVal = this.data.listHeights// 在最開始的時候push了一個0,這里就需要-1,相對應for (let i = 0; i < singersVal.length - 1; i++) {const heightTop = singersVal[i]const heightBottom = singersVal[i + 1]console.log(heightTop)if (newVal >= heightTop && newVal <= heightBottom) {this.setData({curIndex: i})}}}},methods: {onScrollTo({currentTarget: {dataset}}) {const {id, index} = datasetconst query = wx.createSelectorQuery().in(this)query.select(`#${dataset.id}`).boundingClientRect(rect => {this.setData({curIndex: index})this.triggerEvent('scrollY', {scrollTop: rect.top,alphaId: id})}).exec()},// 計算每一項列表的高度區間calculate() {const {listHeights, groupRef} = this.data// 區間高度let height = 0// 每次計算前都要先清空,從0開始listHeights.length = 0listHeights.push(height)for (let i = 0; i < groupRef.length; i++) {height += groupRef[i].heightlistHeights.push(height)}this.setData({listHeights})}} })總結
- 上一篇: 图像处理:高斯滤波算法
- 下一篇: 这样一个爱