小程序字母检索列表
先上效果
沒錯(cuò)看著界面很像黃軼老師webapp的,其實(shí)就是想用小程序?qū)崿F(xiàn)一個(gè),可以根據(jù)界面滾動(dòng)位置字母也實(shí)時(shí)高亮,也可以點(diǎn)擊字母索引跳轉(zhuǎn)到對(duì)應(yīng)的位置。沒有使用scroll-view組件,因?yàn)椴豢赡苁裁垂δ芏加鞋F(xiàn)成的。話不多說下面上代碼
1、處理后臺(tái)返回?cái)?shù)據(jù)
先看下后臺(tái)返回的數(shù)據(jù)是什么樣子的,原來是這樣子的(大家看到效果圖上第一個(gè)是周董,因?yàn)檫@是我手動(dòng)添加的,周董必須放在第一位哦)
有時(shí)候啊,后臺(tái)看心情還不一定給你返回A-Z的字母呢,說不定返回了還不給你排序(我就遇到過),所以呢我還是自己處理了一遍,這是處理后的數(shù)據(jù)
這里說一下思路吧
(tips:最好做一個(gè)判斷,如果后臺(tái)返回的數(shù)據(jù)為空或者返回錯(cuò)誤的狀態(tài)碼,直接return,防止報(bào)錯(cuò))
好了,處理數(shù)據(jù)就說到這里,大家那么聰明的程序員應(yīng)該都能處理好數(shù)據(jù)
2、編寫基礎(chǔ)頁面
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、處理邏輯部分(數(shù)據(jù)請(qǐng)?zhí)崆霸赿ata中定義好)
1、首先這個(gè)組件接👋兩個(gè)數(shù)據(jù)
scrollTop即父組件實(shí)時(shí)滾動(dòng)的top值
2、剛進(jìn)入頁面的時(shí)候我們需要獲取group類中的dom信息,這是為了滾動(dòng)高亮顯示字母做準(zhǔn)備
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、先處理點(diǎn)擊字母跳轉(zhuǎn)到對(duì)應(yīng)位置
methods: {onScrollTo({currentTarget: {dataset}}) {const {id, index} = datasetconst query = wx.createSelectorQuery().in(this)// 這里的動(dòng)態(tài)id就是我們?cè)趙xml中給每個(gè)item綁定的idquery.select(`#${dataset.id}`).boundingClientRect(rect => {this.setData({curIndex: index})this.triggerEvent('scrollY', {scrollTop: rect.top,alphaId: id})}).exec()}, }然后在父組件中接受不了子組件傳來的值,并進(jìn)行跳轉(zhuǎn)。為什么不在子組件中完成這個(gè)邏輯,
因?yàn)檫@個(gè)列表組件只是為了渲染,任何功能性的都會(huì)放在父組件中處理
4、處理滾動(dòng)頁面時(shí),字母高亮
在模板中,我們是使用index作為標(biāo)志來顯示高亮的(你也可以使用title),現(xiàn)在我們要監(jiān)聽scrollTop的值,計(jì)算每一項(xiàng)列表的高度區(qū)間;然后用新的scrollTop和高度區(qū)間的top、bottom進(jìn)行一個(gè)判斷
observers: {data() {this.calculate() },scrollTop(newVal) {const singersVal = this.data.listHeights// 在最開始的時(shí)候push了一個(gè)0,這里就需要-1,相對(duì)應(yīng)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: {// 計(jì)算每一項(xiàng)列表的高度區(qū)間calculate() {const {listHeights, groupRef} = this.data// 區(qū)間高度let height = 0// 每次計(jì)算前都要先清空,從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// 在最開始的時(shí)候push了一個(gè)0,這里就需要-1,相對(duì)應(yīng)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()},// 計(jì)算每一項(xiàng)列表的高度區(qū)間calculate() {const {listHeights, groupRef} = this.data// 區(qū)間高度let height = 0// 每次計(jì)算前都要先清空,從0開始listHeights.length = 0listHeights.push(height)for (let i = 0; i < groupRef.length; i++) {height += groupRef[i].heightlistHeights.push(height)}this.setData({listHeights})}} })總結(jié)
- 上一篇: 图像处理:高斯滤波算法
- 下一篇: 这样一个爱