微信小程序?qū)崿F(xiàn)點餐小程序左側(cè)滑動菜單
前言
最近在幫親戚做一款微信的點餐小程序,以前從沒有接觸過小程序的我只能現(xiàn)做現(xiàn)賣。一邊看文檔一邊實踐嘗試,在進行到點菜模塊左側(cè)滑動菜單時遇到了小小的阻礙。索性在查找一些資料和教程后主要功能實現(xiàn)了出來。特此記錄下,也希望能幫助到需要做同樣功能的同學(xué)。
效果圖:
一、初識scroll-view
想要實現(xiàn)上述功能我們必須要借助微信為我們提供的scroll-view組件,沒有了解過的同學(xué)需要先去簡單閱讀下API。從圖中我們可以看出整個布局主要是由左右兩個滾動界面構(gòu)成。但是它們彼此之間又有聯(lián)系,在點擊左側(cè)菜單類型跟滑動右側(cè)菜品的時候另外一個滾動窗口必須做出響應(yīng)。滾動條實現(xiàn)原理其實就是我們HTML中的錨點,右側(cè)整個菜單是一個完整界面它會將其按唯一id標(biāo)識拆分成不同模塊。比如我們整個界面的高度是2000rpx,其中人氣top10占400rpx。那么height:0-400就對應(yīng)人氣top10。而無肉不歡對應(yīng)模塊高度為300rpx那么,400-700區(qū)域就是無肉不歡。以此類推,下面代碼中我們使用id="{{ ‘right’ + item.id}}" 為每個分類模塊做了唯一標(biāo)識。
<view> ? <view class="menuMain"> ? ? <scroll-view scroll-y="true" class="menuLeft"> ? ? ? <view wx:for="{{menuArr}}" wx:key="*this" bindtap="leftMenuClick" data-current_index="{{index}}" class="{{leftView == index ? 'active' : ''}}">{{item.name}} ? ? ? </view> ? ? </scroll-view> ? ? <scroll-view scroll-y="true" scroll-with-animation="true" bindscroll="rightScroll" scroll-into-view="{{rightId}}" ? ? ?class="menuRight"> ? ? ? <view ?wx:for="{{menuArr}}" wx:key="*this" id="{{ 'right' + item.id}}" class="goods"> ? ? ? ? <view class="goodsType"> ? ? ? ? ?--- ?{{item.name}} --- ? ? ? ? </view> ? ? ? ? <view wx:for="{{item.subArr}}" wx:key="*this" wx:for-item="goods" class="goodsContent"> ? ? ? ? ? <view class="orderDishes"> ? ? ? ? ? ? <image src="{{goods.imageUrl}}" ></image> ? ? ? ? ? ? <view class="goodsInfo"> ? ? ? ? ? ? ? <view class="goodsInfo">{{goods.goodsName}}</view> ? ? ? ? ? ? ? <view class="goodsInfo">規(guī)格:{{goods.unit}}</view> ? ? ? ? ? ? ? <view class="goodsInfo goodsInfoPrice">¥{{goods.price}}</view> ? ? ? ? ? ? ? <view class="add"> ? ? ? ? ? ? ? ? + ? ? ? ? ? ? ? </view> ? ? ? ? ? ? </view> ? ? ? ? ? </view> ? ? ? ? </view> ? ? ? </view> ? ? </scroll-view> ? </view> </view>
二、左側(cè)導(dǎo)航
在小程序初始化生命周期函數(shù)onReady中我們需要提前獲取不同模塊的高度并存入數(shù)組中,來為我們后續(xù)跳轉(zhuǎn)提供高度信息。我們分段將所有的view對應(yīng)高度都放入到heightArr 數(shù)組中。首先實現(xiàn)左側(cè)點擊導(dǎo)航右側(cè)滑動到對應(yīng)高度需求,這里使用bindtap微信我們提供的綁定事件函數(shù)來控制右側(cè)的位置。這里我們?yōu)閒or循環(huán)參數(shù)index進行了重命名,通過自定義屬性data-傳遞給函數(shù)調(diào)用者。這里需要注意一個屬性scroll-into-view。值應(yīng)為某子元素id(id不能以數(shù)字開頭)。設(shè)置哪個方向可滾動,則在哪個方向滾動到該元素 其對應(yīng)的view標(biāo)識id就是當(dāng)前右側(cè)滑動窗口要顯示的內(nèi)容,所以我們需要將左側(cè)屬性與右側(cè)視圖id對應(yīng)起來。在data中我們定義兩個字段leftView代表左側(cè)人氣top10,無肉不歡等分類導(dǎo)航。rightId對應(yīng)scroll-view標(biāo)簽下各個view的唯一id值。這里注意我們的id并不是直接對應(yīng),前面有right字段使用是需要進行組合。點擊左側(cè)控制右側(cè)滑動的功能并不需要用到高度數(shù)組,只需要使其與view中的id對應(yīng)起來即可。詳細(xì)請看leftMenuClick函數(shù)。為了使動畫看起來比較流暢請加上scroll-with-animation屬性
let heightArr = [0] ?// 存放高度累加數(shù)組 data: { ? ? rightId: 'right0', ? ? leftView: 0 ? }, /** ? ?* 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成 ? ?*/ ? onReady: function () { ? ? const query = wx.createSelectorQuery() ? ? query.selectAll('.goods').boundingClientRect() ? ? query.selectViewport().scrollOffset() ? ? query.exec(function (res) { ? ? ? res[0].top // #the-id節(jié)點的上邊界坐標(biāo) ? ? ? res[1].scrollTop // 顯示區(qū)域的豎直滾動位置 ? ? ? res[0].map( val => { ? ? ? ? let result = val.height ?+ heightArr[heightArr.length - 1] ? ? ? ? console.log(result) ? ? ? ? // 拿后一個view盒子的高度加上前面的高度 ? ? ? ? heightArr.push(result)? ? ? ? }) ? ? ? console.log(heightArr) ? ? }) ?? ? }, /** ? ?* 左側(cè)菜單點擊事件,事件對象e傳輸index ? ?*/ ? leftMenuClick(e){ ? ? console.log(e.currentTarget.dataset.current_index) ? ? this.setData({ ? ? ? leftView: e.currentTarget.dataset.current_index, ? ? ? rightId: 'right' + e.currentTarget.dataset.current_index ? ? }) ? }, ? /** ? ?* 右側(cè)滾動事件 ? ?*/ ? rightScroll(e) { ? ? let st = e.detail.scrollTop ? ? console.log('st' + e.detail.scrollTop) ? ? for(let i = 0; i < heightArr.length; i++){ ? ? ? if(st >= heightArr[i] && st <= heightArr[i+1] - 5){ ? ? ? ? this.setData({ ? ? ? ? ? leftView: i, ? ? ? ? }) ? ? ? ? console.log(this.data.leftView) ? ? ? ? return ? ? ? } ? ? } ? }
三、右側(cè)滑動
右側(cè)滑動控制左側(cè)菜單自動選擇就需要用到我們前面說到的滑動高度了,上面我們獲取到了每個view對應(yīng)的高度分別存儲到了heightArr 數(shù)組中。數(shù)組中存放的每個數(shù)值對應(yīng)的是我們view所在高度。e.detail.scrollTop獲取到的是頂部界面所屬高度,假設(shè)當(dāng)前頂部高度為500我們知道400-700是屬于無肉不歡對應(yīng)的界面。此時只需要判斷后將leftView修改為所對應(yīng)的2即可。具體實現(xiàn)看rightScroll函數(shù),我們遍歷循環(huán)heightArr中的高度數(shù)值判斷當(dāng)前st屬于哪個階層,找到后將左側(cè)標(biāo)識字段設(shè)置為對應(yīng)值即可。其中我們 -5是為了使用戶體驗更友好避免出現(xiàn)分類標(biāo)題已經(jīng)劃過去了,左側(cè)導(dǎo)航還沒變更的情況。大體邏輯就是這樣,樣式根據(jù)自己需求來就可以。下面給出我實現(xiàn)界面對應(yīng)的代碼,其中很多樣式都是偽代碼大家到時自信更改。
/* pages/order/order.wxss */ .link { ? height: 30px; } .mainMenu { ? width: 180rpx; } .menuMain { ? height: 100vh; ? display: flex; ? flex-direction: row; ? justify-content: space-around; } /* 左側(cè)菜單導(dǎo)航欄 */ .menuLeft { ? width: 20%; } .menuLeft view { ? font-size: 26rpx; ? text-align: center; ? height: 100rpx; ? line-height: 100rpx; ? background-color: rgb(238, 241, 241); ? position: relative; } .menuLeft view.active{ ? background-color: rgb(255, 255, 255); } .menuLeft view::before { ? content: ''; ? width: 6rpx; ? height: 100%; ? position: absolute; ? left: 0; ? top: 0; ? background-color:transparent; ? border-left: none; } .menuLeft view.active::before { ? background-color: rgb(245, 229, 6); } .menuRight { ? height: 100vh; ? width: 75%; } .menuRight .goods{ ? padding: 10rpx; } .menuRight .goodsType{ ? text-align: center; ? height: 60rpx; ? line-height: 60rpx; ? font-weight: 600; ? color: rgb(0, 0, 0); } .menuRight .goods .goodsContent .orderDishes image{ ? width: 320rpx; ? height: 260rpx; } .menuRight .goods .goodsContent text{ ? overflow: hidden; ? text-overflow: ellipsis; ? white-space: nowrap; } .orderDishes{ ? padding-top: 20rpx; ? display: flex; ? flex-direction: row; } .add{ ? margin-left: 40rpx; ? margin-top: 10rpx; ? width: 120rpx; ? font-size: 40rpx; ? font-weight: 600; ? height: 40rpx; ? line-height: 40rpx; ? text-align: center; ? background-color: rgb(219, 80, 55); ? border-radius: 20rpx; ? color: rgb(255, 255, 255); } .goodsInfo{ ? margin-left: 16rpx; ? height: 65rpx; ? font-size: 28rpx; ? font-weight: 800; ? color: rgb(0, 0, 0); } .goodsInfoPrice{ ? color: rgb(247, 36, 36); }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
javascript 具名函數(shù)的四種調(diào)用方式 推薦
看四種方式執(zhí)行結(jié)果沒有區(qū)別。但如果函數(shù)有返回值的話,用new方式調(diào)用時可能會讓你有些失望。2009-07-07Javascript筆記一 js以及json基礎(chǔ)使用說明
JavaScript中的數(shù)據(jù)很簡潔的。簡單數(shù)據(jù)只有 undefined, null, boolean, number和string這五種,而復(fù)雜數(shù)據(jù)只有一種,即object。2010-05-05javascript制作網(wǎng)頁圖片上實現(xiàn)下雨效果
這里給大家分享的是一則使用javascript實現(xiàn)在網(wǎng)頁圖片上下雨的特效,效果非常炫酷,推薦給小伙伴們。2015-02-02基于JS實現(xiàn)PHP的sprintf函數(shù)實例
這篇文章主要介紹了基于JS實現(xiàn)PHP的sprintf函數(shù)的方法,可實現(xiàn)JavaScript模擬PHPsprintf函數(shù)的輸出功能,涉及JavaScript字符串操作的相關(guān)技巧,需要的朋友可以參考下2015-11-11