日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

小程序字母检索列表

發布時間:2024/3/13 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小程序字母检索列表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

先上效果

沒錯看著界面很像黃軼老師webapp的,其實就是想用小程序實現一個,可以根據界面滾動位置字母也實時高亮,也可以點擊字母索引跳轉到對應的位置。沒有使用scroll-view組件,因為不可能什么功能都有現成的。話不多說下面上代碼


1、處理后臺返回數據


先看下后臺返回的數據是什么樣子的,原來是這樣子的(大家看到效果圖上第一個是周董,因為這是我手動添加的,周董必須放在第一位哦)


有時候啊,后臺看心情還不一定給你返回A-Z的字母呢,說不定返回了還不給你排序(我就遇到過),所以呢我還是自己處理了一遍,這是處理后的數據

這里說一下思路吧

  • 后端返回的數據中前10條我們認定為是熱門歌手,定義一個Map歌手對象,例如
  • singerMap[] = {hot: {title: 'hot',list: [...]} }
  • 將歌手名字轉為拼音,可以借助pinyin這個npm包,獲取歌手名拼音的首字母,例如
    (tips:最好做一個判斷,如果后臺返回的數據為空或者返回錯誤的狀態碼,直接return,防止報錯)
  • // key即是這個歌手屬于那個字母下面const key = pinyin.getCamelChars(item.name).substr(0,1)if (key) {if (!singerMap[key]) {singerMap[key] = {title: key,list: []}}// 每個字母下面會有多名歌手,獲取歌手名拼音的首字母singerMap[key].list.push(map([item])[0])}// 這里我們用到了一個自己封裝的map方法,主要是做一個映射,構造單個歌手的數據結構function map(arr) {if (!Array.isArray(arr)) returnreturn arr.map(item => ({id: item.id,name: item.name,pic: item.picUrl,alias: item.alias,picId_str: item.picId_str,img1v1Url: item.img1v1Url}))}
  • 定義兩個數組用來存儲熱門、字母的歌手;循環遍歷處理后的singerMap
  • for (const key in singerMap) {const item = singerMap[key]if (item.title.match(/[a-zA-Z]/)) {letter.push(item)} else if (item.title === HOT) {hot.push(item)}}
  • 最后將字母按順序排序,將最終處理后的result返回出去
  • // 按字母順序排序letter.sort((a, b) => a.title.charCodeAt(0) - b.title.charCodeAt(0))result = {singers: hot.concat(letter)}return result

    好了,處理數據就說到這里,大家那么聰明的程序員應該都能處理好數據


    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值

    onPageScroll(e) {this.setData({scrollTop: e.scrollTop})}

    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()}, }

    然后在父組件中接受不了子組件傳來的值,并進行跳轉。為什么不在子組件中完成這個邏輯,
    因為這個列表組件只是為了渲染,任何功能性的都會放在父組件中處理

    // 接受組件傳來的滾動值,并滾動到指定位置onScrollTo(e) {console.log(e)const {scrollTop} = e.detailwx.pageScrollTo({scrollTop})},

    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})}} })

    總結

    以上是生活随笔為你收集整理的小程序字母检索列表的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。