uni-app移動應(yīng)用開發(fā)(微課版)課件 項目七 一個簡單的美食搜索小程序_第1頁
uni-app移動應(yīng)用開發(fā)(微課版)課件 項目七 一個簡單的美食搜索小程序_第2頁
uni-app移動應(yīng)用開發(fā)(微課版)課件 項目七 一個簡單的美食搜索小程序_第3頁
uni-app移動應(yīng)用開發(fā)(微課版)課件 項目七 一個簡單的美食搜索小程序_第4頁
uni-app移動應(yīng)用開發(fā)(微課版)課件 項目七 一個簡單的美食搜索小程序_第5頁
已閱讀5頁,還剩64頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

項目七一個簡單的美食搜索小程序

項目七一個簡單的美食搜索小程序

項目任務(wù):任務(wù)1實現(xiàn)首頁任務(wù)2實現(xiàn)餐廳詳情頁面任務(wù)3實現(xiàn)地圖定位頁面任務(wù)4實現(xiàn)登錄頁面01任務(wù)1實現(xiàn)首頁

7.1.1首頁布局

使用HBuilderX創(chuàng)建一個名為uniappdemo7的新項目。為了在項目中方便使用擴展組件,項目創(chuàng)建時選擇創(chuàng)建uni-ui項目。創(chuàng)建完成后首先在pages目錄下新建index/index.vue文件。創(chuàng)建時勾選“在pages.json中注冊”復選框以便在pages.json文件中配置頁面路由,pages.json中pages節(jié)點路由配置如下。{ "pages":[{ "path":"pages/index/index", "style":{ "navigationBarTitleText":"美食搜索首頁", "enablePullDownRefresh":false } }]}

7.1.1首頁布局

在index.vue文件的template和style標簽中輸入如下代碼進行頁面布局和樣式設(shè)置。其中,scroll-view組件用于顯示餐廳列表信息。<template> <viewclass="app"style="{overflow:'auto'}"> <viewclass="top"> <viewclass="search"> <inputtype="text"placeholder="搜索餐廳"/> </view> <buttonclass="search-btn"type="primary"size="mini"@click="search">搜索</button> </view> <scroll-viewclass="content":scroll-y="true"@scrolltolower="scrollToLower"> <viewclass="DataItem"> <imgclass="homeImg"src="../../static/restaurant.jpg"alt="phtoto"/> <viewclass="DataItem-content"> <viewclass="DataItem-content-name">餐館1</view> <viewclass="DataItem-content-rate">¥100</view> <viewclass="DataItem-content-type">粵菜</view> <viewclass="DataItem-content-type">地址1</view> </view> </view><!--剩余代碼見下一頁-->

7.1.1首頁布局 <viewclass="DataItem"> <imgclass="homeImg"src="../../static/restaurant.jpg"alt="phtoto"/> <viewclass="DataItem-content"> <viewclass="DataItem-content-name">餐館1</view> <viewclass="DataItem-content-rate">¥100</view> <viewclass="DataItem-content-type">粵菜</view> <viewclass="DataItem-content-type">地址1</view> </view> </view> </scroll-view> </view></template><stylelang="scss"scoped> .app{ min-height:100rpx; .top{ padding:3rpx0; display:flex; align-items:center; .search{ height:50rpx; margin-left:4rpx;/*剩余代碼見下一頁*/

7.1.1首頁布局 display:flex; align-items:center; flex:1; border-radius:1rpx; } .search-btn{ margin:020rpx; } } } .searchinput{ width:100%; margin-left:4rpx; } .searchinput::-webkit-input-placeholder{ color:#999; line-height:5rpx; } .content{ height:1000rpx; } .DataItem{ background-color:#fff; display:flex; padding:04rpx;/*剩余代碼見下一頁*/

7.1.1首頁布局 align-items:center; font-size:12px; margin-bottom:3rpx; color:#999; .homeImg{ width:4.4rem; height:3.4rem; margin-right:0.266667rem; } .DataItem-content{ flex:1; .DataItem-content-name{ font-size:14px; margin-top:0.233333rem; width:4rem; overflow:hidden; word-break:keep-all; white-space:nowrap; text-overflow:ellipsis; color:#333; font-size:14px; font-weight:600 }/*剩余代碼見下一頁*/

7.1.1首頁布局 .DataItem-content-rate{ margin:0.263333rem0; } .DataItem-content-type{ padding-bottom:0.2rem; } } }</style>在微信開發(fā)者工具中布局效果。

7.1.2首頁動態(tài)加載餐廳數(shù)據(jù)

首頁布局完成后,下一步將動態(tài)加載餐廳列表數(shù)據(jù)。這里數(shù)據(jù)采用靜態(tài)JS模擬實現(xiàn),真實開發(fā)中可采用uni.requestAPI向服務(wù)端發(fā)送請求獲取數(shù)據(jù)。在pages/index目錄下創(chuàng)建data.js文件,文件內(nèi)添加16條靜態(tài)模擬數(shù)據(jù),單條靜態(tài)數(shù)據(jù)格式如下。exportdefault[{ "cid":"1", "restaurant":"餐廳1",

"type":"粵菜", "rate":"4.8", "avgPrice":"80", "pic":"../../static/restaurant.jpg", "address":"廣東省廣州市番禺區(qū)迎賓路557-567號", "product":[ {"id":"1","name":"菜品1","num":0,"price":55,image:"../../static/caipin.jpg"}, {"id":"2","name":"菜品2","num":0,"price":65,image:"../../static/caipin.jpg"}, {"id":"3","name":"菜品3","num":0,"price":75,image:"../../static/caipin.jpg"}, {"id":"4","name":"菜品4","num":0,"price":85,image:"../../static/caipin.jpg"}, {"id":"5","name":"菜品5","num":0,"price":80,image:"../../static/caipin.jpg"}, ]}]

7.1.2首頁動態(tài)加載餐廳數(shù)據(jù)

下面在index.vue文件的script標簽中添加如下代碼加載餐廳數(shù)據(jù)。import{onLoad,onPullDownRefresh}from'@dcloudio/uni-app'import{reactive,ref}from'vue';importdatafrom'/pages/index/data/data.js'//模擬數(shù)據(jù)源letpageCurrent=ref(1)//分頁查詢頁數(shù)letrestArr=reactive([])//餐館列表數(shù)據(jù)letpageSize=10/**scroll-view監(jiān)聽滾動條到底部*/functionscrollToLower(){ //滾動條到底部加載下一頁數(shù)據(jù) pageCurrent.value=pageCurrent.value+1 getRestaurantData(pageCurrent.value,false)}onLoad((option)=>{ //獲取餐館數(shù)據(jù)列表 getRestaurantData(pageCurrent.value,true)})functiongetRestaurantData(pageCurrent,flag){ //flag為真,代表下拉操作或初始化加載數(shù)據(jù)清空homeArr, //否則為滾動條到底部加載下一頁數(shù)據(jù) if(flag){ homeArr.length=0 }//剩余代碼見下一頁

7.1.2首頁動態(tài)加載餐廳數(shù)據(jù) //分頁查詢獲取符合條件的數(shù)據(jù)id letpageData=data.filter((item,index)=>{ constidx=index-(pageCurrent-1)*pageSize returnidx<pageSize&&idx>=0 }) if(pageData.length==0){ //pageData長度0,則數(shù)據(jù)全部加載完成,否則繼續(xù)加載下一頁數(shù)據(jù) if(!flag){ uni.showToast({ title:"數(shù)據(jù)已加載到底" }) } }else{ for(letitemofpageData){ restArr.push({ pic:item.pic, restaurant:item.restaurant, rate:item.rate, avgPrice:item.avgPrice, type:item.type, cid:item.cid, address:item.address, product:duct

}) } }}

7.1.2首頁動態(tài)加載餐廳數(shù)據(jù)

上述代碼使用onLoad函數(shù),在頁面加載時調(diào)用getRestaurantData方法從data.js中加載數(shù)據(jù)。餐廳數(shù)據(jù)使用分頁加載模式,每一頁加載10條數(shù)據(jù)。同時使用scroll-view組件的scrolltolower事件監(jiān)聽滾動條是否到達底部,如果滾動條到達底部則加載下一頁數(shù)據(jù)。餐廳數(shù)據(jù)使用restArr響應(yīng)式數(shù)據(jù)存儲。

下面對restArr中的數(shù)據(jù)進行頁面展現(xiàn)。由于每一條餐廳數(shù)據(jù)內(nèi)容格式相同,這里使用自定義組件child.vue來封裝展現(xiàn)每一條餐廳數(shù)據(jù),涉及父子組件之間的傳值問題。

在uniappdemo7項目下新建components目錄,在components目錄下新建child/child.vue文件,在其中輸入如下代碼。child.vue中使用defineProps來接收index.vue傳遞的參數(shù),參數(shù)名稱為obj,參數(shù)類型為Object。樣式.DataItem-content為index.vue中的原有代碼,直接復制過來并刪除index.vue中的原有代碼。

7.1.2首頁動態(tài)加載餐廳數(shù)據(jù)<template> <viewclass="DataItem"> <imgclass="homeImg":src="obj.pic"alt="phtoto"/> <viewclass="DataItem-content"> <viewclass="DataItem-content-name">{{obj.restaurant}}</view> <viewclass="DataItem-content-rate">¥{{obj.avgPrice}}</view> <viewclass="DataItem-content-type">{{obj.type}}</view> <viewclass="DataItem-content-type">{{obj.address}}</view> </view> </view></template><scriptsetup> constprops=defineProps({ obj:{ type:Object, required:false } })</script><stylelang="scss"scoped> .DataItem{ background-color:#fff; display:flex; padding:04rpx; align-items:center; font-size:12px;/*剩余代碼見下一頁*/

7.1.2首頁動態(tài)加載餐廳數(shù)據(jù) margin-bottom:3rpx; color:#999; .homeImg{ width:4.4rem; height:3.4rem; margin-right:0.266667rem; } .DataItem-content{ flex:1; .DataItem-content-name{ font-size:14px; margin-top:0.233333rem; width:4rem; overflow:hidden; word-break:keep-all; white-space:nowrap; text-overflow:ellipsis; color:#333; font-size:14px; font-weight:600 }/*剩余代碼見下一頁*/

7.1.2首頁動態(tài)加載餐廳數(shù)據(jù) .DataItem-content-rate{ margin:0.263333rem0; } .DataItem-content-type{ padding-bottom:0.2rem; } } }</style>

注意:新建child.vue文件時,在新建頁面窗口不要勾選“在pages.json中注冊”復選框。否則在后續(xù)調(diào)試過程中可能會出現(xiàn)“Error:module‘pages/child/child.js‘isnotdefined,requireargsis‘pages/child/child.js”的錯誤。

7.1.2首頁動態(tài)加載餐廳數(shù)據(jù)

然后修改index.vue中代碼,將scroll-view組件中代碼替換成如下黑體代碼,通過參數(shù)obj向child.vue組件傳值。傳值時child標簽中的參數(shù)名稱必須和child.vue中defineProps內(nèi)部的參數(shù)名稱保持一致,否則數(shù)據(jù)不能正常接收。<scroll-viewclass="content":scroll-y="true"@scrolltolower="scrollToLower"> <viewv-if="restArr.length"> <viewv-for="(item,index)inrestArr":key="index"> <child:obj="item"></child> </view> </view></scroll-view>

7.1.2首頁動態(tài)加載餐廳數(shù)據(jù)

在微信開發(fā)者工具中效果。

7.1.3首頁餐廳搜索功能

下面對index.vue中代碼進一步修改,實現(xiàn)餐廳搜索功能。用戶可以在列表上部輸入框輸入餐廳名稱,單擊“搜索”按鈕,即可過濾查看具體某個餐廳信息。

在index.vue文件內(nèi)部script標簽中添加如下代碼,定義restaurant響應(yīng)式數(shù)據(jù),并實現(xiàn)search方法內(nèi)部邏輯。當用戶單擊“搜索”按鈕時,對原始數(shù)據(jù)data進行過濾,然后從第一頁開始加載過濾后的數(shù)據(jù)。letrestaurant=ref("")//餐館名稱functionsearch(){ pageCurrent.value=1 homeArr.length=0 getMerchantData(pageCurrent.value,restaurant.value,true)}

修改index.vue文件內(nèi)部template標簽內(nèi)innput輸入框代碼,在input組件上使用v-model綁定restaurant響應(yīng)式數(shù)據(jù)。<viewclass="search"> <inputtype="text"v-model="restaurant"

placeholder="搜索餐廳"/></view>

7.1.3首頁餐廳搜索功能

此時,在index.vue頁面上部input輸入框中輸入“餐廳1”單擊“搜索”按鈕。搜索效果如下。

7.1.4跳轉(zhuǎn)餐廳詳情頁面

當用戶單擊餐廳列表中某個餐廳時,頁面能夠跳轉(zhuǎn)到該餐廳的詳情頁面,并將該餐廳對應(yīng)的數(shù)據(jù)傳遞過去。實現(xiàn)此功能需使用uni.navigateToAPI進行頁面跳轉(zhuǎn)和傳值。傳值時可直接在url路徑后使用?拼接傳遞的數(shù)據(jù)。

修改index.vue文件內(nèi)部的template標簽中scroll-view內(nèi)部代碼,在其中給每個餐廳的view組件上添加click函數(shù),如下黑體代碼。<scroll-viewclass="content":scroll-y="true"@scrolltolower="scrollToLower"> <viewv-if="homeArr.length"> <view@click="goToRestaurant(item)"

v-for="(item,index)inhomeArr" :key="index"> <child:obj="item"></child> </view> </view></scroll-view>

7.1.4跳轉(zhuǎn)餐廳詳情頁面

餐廳詳情頁面路徑為/pages/restaurant/restaurant。在index.vue文件內(nèi)部的script標簽中添加goToRestaurant函數(shù),代碼如下。其中餐廳數(shù)據(jù)采用JSON字符串形式傳遞,并使用了encodeURIComponent函數(shù)對JSON字符串進行封裝。functiongoToRestaurant(obj){ uni.navigateTo({ url:'/pages/restaurant/restaurant?obj=' +encodeURIComponent(JSON.stringify(obj)) })}02任務(wù)2實現(xiàn)餐廳詳情頁面

7.2.1餐廳詳情頁面布局

在pages目錄下新建restaurant/restaurant.vue文件。創(chuàng)建時勾選“在pages.json中注冊”復選框以便在pages.json文件中配置頁面路由,pages.json中pages節(jié)點路由配置如黑體代碼所示。"pages":[{ "path":"pages/index/index", "style":{ "navigationBarTitleText":"美食搜索首頁", "enablePullDownRefresh":false }},{ "path":"pages/restaurant/restaurant", "style": { "navigationBarTitleText":"餐廳詳情", "enablePullDownRefresh":false }}]

7.2.1餐廳詳情頁面布局

在restaurant.vue文件的template和style標簽中輸入如下代碼進行頁面布局和樣式設(shè)置。其中,<viewclass="header">組件用于顯示餐廳圖片、名稱、評分、地址等詳細信息,scroll-view組件內(nèi)部用于顯示餐廳菜品信息。<template> <viewclass="restaurant"> <view

class="header"> <imgclass="header-img"src="../../static/restaurant.jpg"alt="餐廳圖片"/> <viewclass="restaurant-content"> <view>餐廳1</view> <uni-rateclass="restaurant-content-data":readonly="true"/>4.8分

<viewstyle="display:flex;flex:0;"> <view>地址:廣東省廣州市番禺區(qū)迎賓路557-567號</view> <imagesrc="../../static/marker.png" style="height:35rpx;width:35rpx"></image> </view> </view> </view> <view> <scroll-viewstyle="height:870rpx":scroll-y="true"> <viewclass="goods-detail"> <viewclass="detail-left"><!--剩余代碼見下一頁-->

7.2.1餐廳詳情頁面布局 <viewclass="goods-left"> <imagesrc="../../static/caipin.jpg" style="width:150rpx;height:140rpx;"></image> </view> <viewclass="goods-name"> <textstyle="font-size:25rpx;">菜品1</text> <textclass="goods-price">55元/件</text> </view> </view> <viewclass="detail-right"> <textclass="reduce">-</text> <textclass="num">0</text> <text

class="add">+</text> </view> </view> <viewclass="goods-detail"> <viewclass="detail-left"> <viewclass="goods-left"> <imagesrc="../../static/caipin.jpg" style="width:150rpx;height:140rpx;"></image> </view> <viewclass="goods-name"> <textstyle="font-size:25rpx;">菜品1</text> <textclass="goods-price">55元/件</text> </view> </view><!--剩余代碼見下一頁-->

7.2.1餐廳詳情頁面布局 <viewclass="detail-right"> <textclass="reduce">-</text> <textclass="num">0</text> <text

class="add">+</text> </view> </view> </scroll-view> <viewclass="end"> <viewclass="end-left"> <view>

總計:<textstyle="color:orangered;font-weight:bold;">

0元</text> </view> </view> <viewclass="end-right">

去結(jié)算(0) </view> </view> </view> </view></template><stylelang="scss"scoped> .restaurant{ min-height:100vh; background-color:#f2f2f2; font-size:24rpx;/*剩余代碼見下一頁*/

7.2.1餐廳詳情頁面布局 .header{ background-color:#333; display:flex; align-items:center; padding:0.266667rem0.4rem; .header-img{ width:2.4rem; height:1.6rem; margin-right:0.266667rem; border-radius:0.133333rem; } .restaurant-content{ flex:1; color:#fff; .restaurant-content-data{ margin-top:0.266667rem } } } } .goods-detail{ line-height:70rpx; display:flex; padding:20rpx15rpx20rpx20rpx; justify-content:space-between; align-items:center;/*剩余代碼見下一頁*/

7.2.1餐廳詳情頁面布局 .detail-left{ display:flex; .goods-left{ display:flex; align-items:center; } .goods-name{ display:flex; justify-content:space-around; flex-direction:column; margin-left:25rpx; .goods-price{ font-size:25rpx; color:red; } } } .detail-right{ text{ width:55rpx; line-height:55rpx; text-align:center; display:inline-block; margin-right:10rpx; }/*剩余代碼見下一頁*/

7.2.1餐廳詳情頁面布局 .add{ color:red; margin-right:20rpx; } } } .end{ width:100%; height:100rpx; position:fixed; bottom:80rpx; left:0; display:flex; align-items:center; .end-left{ width:75%; display:flex; justify-content:space-between; padding:025rpx; .end-flex{ display:flex; align-items:center; } }/*剩余代碼見下一頁*/

7.2.1餐廳詳情頁面布局 .end-right{ width:25%; line-height:90rpx; background-color:red; text-align:center; color:white; } }</style>在微信開發(fā)者工具中布局效果。

7.2.2動態(tài)加載餐廳詳細信息

餐廳詳情頁面布局完成后,下一步將動態(tài)加載餐廳詳細信息。在restaurant.vue中<viewclass="header">組件內(nèi)部代碼替換成如下黑體代碼,動態(tài)加載餐廳詳細信息。<viewclass="header"> <imgclass="header-img":src="obj.pic"alt="餐廳圖片"/> <viewclass="restaurant-content"> <view>{{obj.restaurant}}</view> <uni-rateclass="restaurant-content-data"v-model="obj.rate" :readonly="true"/>{{obj.rate}}分

<viewstyle="display:flex;flex:0;"> <view>地址:{{obj.address}}

</view> <imagesrc="../../static/marker.png" style="height:35rpx;width:35rpx"></image> </view> </view></view>

7.2.2動態(tài)加載餐廳詳細信息

在restaurant.vue中的script標簽中添加代碼動態(tài)接收index.vue傳過來的參數(shù)。import{onLoad}from'@dcloudio/uni-app'import{reactive,computed}from'vue';letobj=reactive({ pic:"", restaurant:"", rate:"", avgPrice:"", type:"", cid:"", address:""})onLoad((option)=>{ //接收傳過來的數(shù)據(jù)賦值給obj letrecData=JSON.parse(decodeURIComponent(option.obj)) obj.pic=recData.pic obj.restaurant=recData.restaurant obj.rate=recData.rate obj.avgPrice=recData.avgPrice obj.type=recData.type obj.cid=recData.cid obj.address=recData.address})

7.2.3動態(tài)加載餐廳菜品

餐廳菜品存在于index.vue傳參的product屬性中,product屬性數(shù)據(jù)如下。"product":[

{"id":"1","name":"菜品1","num":0,"price":55,image:"../../static/caipin.jpg"},

{"id":"2","name":"菜品2","num":0,"price":65,image:"../../static/caipin.jpg"},

{"id":"3","name":"菜品3","num":0,"price":75,image:"../../static/caipin.jpg"},

{"id":"4","name":"菜品4","num":0,"price":85,image:"../../static/caipin.jpg"},

{"id":"5","name":"菜品5","num":0,"price":80,image:"../../static/caipin.jpg"},]

在顯示時還需考慮之前用戶是否已選擇某些菜品,如用戶已選擇某些菜品,菜品的num屬性并不一定為0。這里將用戶選擇的菜品保存在本地緩存中,如果用戶初次使用,未選擇任何菜品,則餐廳菜品使用product屬性的默認值,所有菜品的num屬性都為0。如果用戶不是初次使用,已選擇一些菜品,那么需要根據(jù)本地緩存中的數(shù)據(jù)實時更新對應(yīng)菜品的num屬性值。本地緩存中數(shù)據(jù)格式同data.js,也是一個數(shù)組,只不過每個菜品的num值不同。

7.2.3動態(tài)加載餐廳菜品

將restaurant.vue中的scroll-view標簽內(nèi)部原有代碼替換成如下黑體代碼。<scroll-viewstyle="height:870rpx":scroll-y="true">

<viewclass="goods-detail"v-for="(item,index)induct"

:key="index">

<viewclass="detail-left">

<viewclass="goods-left">

<image:src="item.image"

style="width:150rpx;height:140rpx;"></image>

</view>

<viewclass="goods-name">

<textstyle="font-size:25rpx;">{{}}</text>

<textclass="goods-price">{{item.price}}元/件</text>

</view>

</view>

<viewclass="detail-right">

<textclass="reduce"@click="reduce(item)">-</text>

<textclass="num">{{item.num}}</text>

<text@click="add(item)"class="add">+</text>

</view>

</view></scroll-view>

7.2.3動態(tài)加載餐廳菜品

在restaurant.vue中的script標簽中添加如下黑體代碼,動態(tài)加載菜品信息。import{onLoad}from'@dcloudio/uni-app'import{reactive,computed}from'vue';letobj=reactive({ pic:"", restaurant:"", rate:"", avgPrice:"", type:"", cid:"", address:"", product:[]})onLoad((option)=>{ //接收傳過來的數(shù)據(jù)賦值給obj letrecData=JSON.parse(decodeURIComponent(option.obj)) obj.pic=recData.pic obj.restaurant=recData.restaurant obj.rate=recData.rate obj.avgPrice=recData.avgPrice obj.type=recData.type obj.cid=recData.cid obj.address=recData.address//剩余代碼見下一頁

7.2.3動態(tài)加載餐廳菜品 //頁面加載獲取緩存的數(shù)據(jù)

uni.getStorage({ key:"store", success:(res)=>{//如果緩存存在,更新本餐廳已選擇的菜品數(shù)量

if(res.data){ letgetFlag=false for(letitemofres.data){ if(item.cid==recData.cid){

//有本餐廳選擇的菜品

duct=duct getFlag=true } } if(getFlag==false){

//沒有本餐廳選擇的菜品

duct=recDduct } }else{ duct=recDduct } }, fail:(res)=>{//如果緩不存存在,使用recData數(shù)據(jù)

duct=recDduct } })})

7.2.4對菜品操作按鈕添加業(yè)務(wù)邏輯

菜品列表中每道菜品右側(cè)都對應(yīng)了“+”和“-”兩個操作按鈕供用戶新增和刪除菜品。這里對“+”和“-”兩個操作按鈕添加相應(yīng)的業(yè)務(wù)邏輯代碼。

1.“+”按鈕的業(yè)務(wù)邏輯“+”按鈕的業(yè)務(wù)邏輯如下:當用戶單擊“+”按鈕時,應(yīng)首先讀取本地緩存,檢查緩存中是否有菜品選擇數(shù)據(jù),如果有進一步確定是否是本餐廳的菜品選擇數(shù)據(jù),如果是就直接更新對應(yīng)菜品的num值,存入本地緩存。如果不是則在緩存中新增一個數(shù)組元素用于保存本餐廳選擇的菜品,存入本地緩存。如果緩存中沒有任何數(shù)據(jù),則也在緩存中新增一個數(shù)組元素用于保存本餐廳選擇的菜品,存入本地緩存?!?”按鈕對應(yīng)的add函數(shù)實現(xiàn)代碼如下。

7.2.4對菜品操作按鈕添加業(yè)務(wù)邏輯functionadd(item){ letnum=item.num item.num=num+1 //獲取緩存的數(shù)據(jù)

uni.getStorage({ key:"store", success:(res)=>{ letresData=res.data if(resData){ letgetFlag=false for(letresDataItemofresData){ //如果緩存中有該餐廳點菜數(shù)據(jù),則更新num if(resDataItem.cid==obj.cid){ getFlag=true for(letitem1ofresDataIduct){ if(item1.id==item.id){ item1.num=item.num } } } }//剩余代碼見下一頁

7.2.4對菜品操作按鈕添加業(yè)務(wù)邏輯 //如果緩存中沒有該餐廳點菜數(shù)據(jù),則resData數(shù)組中新增該餐廳obj if(getFlag==false){ resData.push(obj) } } //console.log(resData) //將新的數(shù)據(jù)存入緩存

uni.setStorage({ key:"store", data:resData, }) }, fail:()=>{//緩存中沒有數(shù)據(jù),直接存入該餐廳obj letarray=[] array.push(obj) uni.setStorage({ key:"store", data:array, }) } })}

7.2.4對菜品操作按鈕添加業(yè)務(wù)邏輯

2.“-”按鈕的業(yè)務(wù)邏輯“-”按鈕的業(yè)務(wù)邏輯如下:當用戶單擊“-”按鈕時,應(yīng)首先讀取本地緩存,如果本地緩存沒有數(shù)據(jù)或沒有本餐廳選擇的菜品數(shù)據(jù),則本餐廳所有菜品num值為0,單擊“-”按鈕則提示“不能減少數(shù)量”。如果本地緩存中有本餐廳選擇的菜品數(shù)據(jù),則對應(yīng)的菜品num值減一,然后還需確認菜品num值減一后本餐廳是否還選擇了其他菜品,如果沒有則清空緩存中的本餐廳數(shù)據(jù),否則將num值減一后的數(shù)據(jù)存入本地緩存中?!?”按鈕對應(yīng)的reduce函數(shù)實現(xiàn)代碼如下。

7.2.4對菜品操作按鈕添加業(yè)務(wù)邏輯functionreduce(item){ letnum=item.num //如果商品數(shù)量大于等于1,則減一

if(num>=1){ num-=1 }else{ //如果商品數(shù)量等于0,則提示不能減少數(shù)量了

uni.showToast({ title:"不能減少數(shù)量" }) } //更新商品數(shù)量

item.num=num //獲取緩存的購物車數(shù)據(jù)

uni.getStorage({ key:"store", success:(res)=>{//緩存中有數(shù)據(jù)

letresData=res.data if(resData){ //更新resData中菜品數(shù)量num for(letresDataItemofresData){ if(resDataItem.cid==obj.cid){//剩余代碼見下一頁

7.2.4對菜品操作按鈕添加業(yè)務(wù)邏輯 for(letitem1ofresDataIduct){ if(item1.id==item.id){ item1.num=num } } } } //當該餐廳沒有點菜時,清除該餐廳緩存數(shù)據(jù)

letremoveFlag=true for(letresDataItemofresData){ if(resDataItem.cid==obj.cid){ for(letresDataItemEleofresDataIduct){ if(resDataItemEle.num!=0){ removeFlag=false break } } } }//剩余代碼見下一頁

7.2.4對菜品操作按鈕添加業(yè)務(wù)邏輯 if(removeFlag==true){ for(letindexinresData){ if(resData[index].cid==obj.cid){ resData.splice(resData[index],1) } } } } //console.log(resData) //將新的數(shù)據(jù)存入緩存 uni.setStorage({ key:"store", data:resData, }) } })}

7.2.5動態(tài)計算選擇菜品的數(shù)量和總計金額

當用戶單擊“+”和“-”兩個操作按鈕時,如果操作成功則頁面下方“去結(jié)算”按鈕括號中的選擇菜品的數(shù)量和總計金額也應(yīng)該同步更新,注意這里選擇菜品的數(shù)量和總計金額并不只針對當前餐廳來說,應(yīng)該顯示用戶在所有餐廳中選擇的菜品數(shù)量和總計金額,類似于購物車功能。

以動態(tài)計算選擇菜品的數(shù)量為例,實現(xiàn)思路如下:可將選擇菜品的數(shù)量分為兩部分,一部分是當前餐廳的選擇菜品的數(shù)量,一部分是其他所有餐廳的選擇菜品的數(shù)量,用戶操作只會對當前餐廳的選擇菜品的數(shù)量產(chǎn)生影響,其他所有餐廳的選擇菜品的數(shù)量是不會改變的。因此可以在頁面加載時就從本地緩存獲取緩存數(shù)據(jù),計算當前餐廳的選擇菜品的數(shù)量和其他所有餐廳的選擇菜品的數(shù)量這兩部分數(shù)值,然后利用Vue中計算屬性實時監(jiān)控單擊“+”和“-”兩個操作按鈕更新當前餐廳的選擇菜品的數(shù)量。該思路也適用于動態(tài)計算總計金額。

7.2.5動態(tài)計算選擇菜品的數(shù)量和總計金額<viewclass="end">

<viewclass="end-left">

<view>

總計:<textstyle="color:orangered;font-weight:bold;">

{{totalPrice}}元</text>

</view>

</view>

<viewclass="end-right"@click="payMoney">

去結(jié)算({{totalNum}})

</view></view>

此功能具體實現(xiàn)代碼如下,首先將restaurant.vue中的<viewclass="end">標簽內(nèi)部原有代碼替換成如下黑體代碼。

7.2.5動態(tài)計算選擇菜品的數(shù)量和總計金額

然后在restaurant.vue中的script標簽中添加如下黑體代碼。import{ref,reactive,computed}from'vue';lettotalPriceOther=ref(0)//除當前餐廳外其他所有餐廳的訂餐金額lettotalNumOther=ref(0)//除當前餐廳外其他所有餐廳的訂餐數(shù)量onLoad((option)=>{ //接收傳過來的數(shù)據(jù)賦值給obj letrecData=JSON.parse(decodeURIComponent(option.obj)) obj.pic=recData.pic obj.restaurant=recData.restaurant obj.rate=recData.rate obj.avgPrice=recData.avgPrice obj.type=recData.type obj.cid=recData.cid obj.address=recData.address //頁面加載獲取緩存的數(shù)據(jù)

uni.getStorage({ key:"store", success:(res)=>{//如果緩存存在,更新本店已選擇的菜品數(shù)量

console.log(res.data) if(res.data){ letgetFlag=false for(letitemofres.data){//剩余代碼見下一頁

7.2.5動態(tài)計算選擇菜品的數(shù)量和總計金額 if(item.cid==recData.cid){//有本店選擇的菜品

duct=duct getFlag=true } } if(getFlag==false){//沒有本店選擇的菜品

duct=recDduct } //計算除當前餐廳外其他所有餐廳的訂餐金額和訂餐數(shù)量

lettotalPriceOthertemp=0 lettotalNumOthertemp=0 for(letitemofres.data){ if(item.cid!=recData.cid){ for(letproductItemofduct){ totalPriceOthertemp=totalPriceOthertemp+ productItem.num*productItem.price totalNumOthertemp=totalNumOthertemp +productItem.num } } } totalPriceOther.value=totalPriceOthertemp totalNumOther.value=totalNumOthertemp }else{ duct=recDduct } },//剩余代碼見下一頁

7.2.5動態(tài)計算選擇菜品的數(shù)量和總計金額 fail:(res)=>{//如果緩不存存在,使用recData數(shù)據(jù)

duct=recDduct } })})lettotalNum=computed(()=>{ //設(shè)置totalNum為計算屬性,實時計算購買商品總數(shù)量

lettotalNumSelf=0//本店購買商品總數(shù)量

duct.map(item=>{ totalNumSelf+=item.num }) returntotalNumOther.value+totalNumSelf})lettotalPrice=computed(()=>{ //設(shè)置totalPrice為計算屬性,實時計算購買商品總金額

lettotalPriceSelf=0//本店購買商品總金額

duct.map(item=>{ totalPriceSelf+=item.num*item.price }) returntotalPriceOther.value+totalPriceSelf})functionpayMoney(){ uni.showToast({ title:"付款總計"+totalPrice.value+"元" })}

7.2.5動態(tài)計算選擇菜品的數(shù)量和總計金額

在微信開發(fā)者工具中執(zhí)行效果。03任務(wù)3實現(xiàn)地圖定位頁面

任務(wù)3實現(xiàn)地圖定位頁面

地圖定位頁面主要功能為在騰訊地圖上顯示餐廳地理位置。在餐廳詳情頁面的餐廳地址右側(cè)有一個綠色氣泡圖標。單擊該圖標,頁面將跳轉(zhuǎn)到地圖定位頁面,在地圖上可視化顯示當前餐廳的地理位置。

在pages目錄下新建map/map.vue文件。創(chuàng)建時勾選“在pages.json中注冊”復選框以便在pages.json文件中配置頁面路由,pages.json中pages節(jié)點路由配置如黑體代碼所示。"pages":[{ "path":"pages/index/index", "style":{ "navigationBarTitleText":"美食搜索首頁", "enablePullDownRefresh":false }},{ "path":"pages/restaurant/restaurant", "style": { "navigationBarTitleText":"餐廳詳情", "enablePullDownRefresh":false }}{ "path":"pages/map/map", "style": { "navigationBarTitleText":"餐廳位置", "enablePullDownRefresh":false }}]

任務(wù)3實現(xiàn)地圖定位頁面

在restaurant.vue中<viewclass="header">組件內(nèi)部添加如下黑體代碼,定義click事件跳轉(zhuǎn)map.vue頁面。<viewclass="header"> <imgclass="header-img":src="obj.pic"alt="餐廳圖片"/> <viewclass="restaurant-content"> <view>{{obj.restaurant}}</view> <uni-rateclass="restaurant-content-data"v-model="obj.rate" :readonly="true"/>{{obj.rate}}分

<viewstyle="display:flex;flex:0;"> <view>地址:{{obj.address}}

</view> <imagesrc="../../static/marker.png" @click="toMap(obj.address)" style="height:35rpx;width:35rpx"></image> </view> </view></view>toMap方法內(nèi)部代碼如下,跳轉(zhuǎn)頁面同時將餐廳地址作為參數(shù)傳遞給map.vue。unctiontoMap(address){ uni.navigateTo({ url:"/pages/map/map?address="+address })}

任務(wù)3實現(xiàn)地圖定位頁面

map.vue頁面接收到餐廳地址后,需將該地址作為參數(shù)調(diào)用騰訊地圖的getSuggestionAPI接口獲取該餐廳的經(jīng)緯度坐標,才能在騰訊地圖上顯示。

在uniappdemo7項目中將騰訊地圖SDK文件qqmap-wx-jssdk.js放入項目的\static\js\utils\qqmap-wx-jssdk目錄中,以便后續(xù)使用。

在map.vue頁面中輸入以下代碼創(chuàng)建騰訊地圖對象qqMapWx,并調(diào)用其getSuggestion方法獲取當前餐廳的經(jīng)緯度坐標,然后將位置顯示在地圖上。<template> <view> <mapclass="map":markers="markers":latitude="latitude" :longitude="longitude"></map> </view></template><scriptsetup> import{onLoad}from'@dcloudio/uni-app' import{ref,reactive}from'vue'; letQQMapWX=require('../../static/js/utils/qqmap-wx-jssdk/qqmap-wx-jssdk.js'); letqqMapWx="" letlatitude=ref(0)//地圖中心點緯度

letlongitude=ref(0)//地圖中心點經(jīng)度//剩余代碼見下一頁

任務(wù)3實現(xiàn)地圖定位頁面 letmarkers=reactive([ { id:0, latitude:0,//標記點緯度

longitude:0,//標記點經(jīng)度

iconPath:"../../static/marker.png",//標記點圖標

width:"30",//標記點圖標寬度

height:"30"http://標記點圖標高度

}, ]) onLoad((option)=>{ qqMapWx=newQQMapWX({ key:"替換成自己的騰訊地圖Key" }) letaddress=option.address qqMapWx.getSuggestion({ //獲取輸入框值并設(shè)置keyword參數(shù)

keyword:address, success:function(res){ latitude.value=res.data[0].location.lat longitude.value=res.data[0].location.lng markers[0].latitude=res.data[0].location.lat markers[0].longitude=res.data[0].location.lng console.log(latitude.value) console.log(longitude.value) },//剩余代碼見下一頁

任務(wù)3實現(xiàn)地圖定位頁面 fail:function(error){ console.log(error); } }) })</script><stylescoped> .map{width:750rpx;height:750rpx}</style>在微信開發(fā)者工具中地圖顯示。04任務(wù)4實現(xiàn)登錄頁面

7.4.1用戶名密碼登錄

用戶名密碼登錄的流程和Web系統(tǒng)登錄差不多,需要自己處理登錄流程?;静襟E如下。(1)前端提供頁面提供輸入框給用戶輸入用戶名和密碼。?(2)用戶輸入用戶名和密碼后將數(shù)據(jù)發(fā)送到后臺服務(wù)器進行驗證。?(3)后端服務(wù)器驗證用戶名和密碼,如果驗證通過,?則生成登錄憑證Token?返回給前端頁面。(4)前端頁面接收到登錄憑證后,?可以將其保存在本地緩存,?例如使用uni.setStorageSync方法存儲Token,?這樣用戶在下一次打開小程序時只要在本地緩存中讀取到Token,就無需再次登錄,?直到token過期失效。

這里省略后臺服務(wù)器對上述流程進行簡化,直接在前端頁面驗證用戶名和密碼,模擬生成Token。

7.4.1用戶名密碼登錄

在pages目錄下新建login/login.vue文件。創(chuàng)建時勾選“在pages.json中注冊”復選框以便在pages.json文件中配置頁面路由,pages.json中pages節(jié)點路由配置如下。{ "path":"pages/login/login", "style": { "navigationBarTitleText":"登錄頁面", "enablePullDownRefresh":false }}

在login.vue文件的template標簽中添加如下代碼,定義用戶名和密碼兩個輸入框和“登錄”按鈕。<viewclass="login-content">用戶名密碼 <inputclass="login-item"type="text"placeholder="請輸入賬號" v-model="userName"> <inputclass="login-item"type="safe-password"placeholder="請輸入密碼" v-model="password"> <viewclass="view-button"><button@click="login">登錄</button></view></view>

7.4.1用戶名密碼登錄

相應(yīng)的樣式代碼如下。.login-content{ .login-item{ padding:10rpx; height:60rpx; width:80%; } .view-button{ button{ background-color:#10c52f; width:90%; height:85rpx; text-align:center; line-height:85rpx; color:#fff; } }}

7.4.1用戶名密碼登錄

在login.vue文件的script標簽中添加如下代碼。當用戶名和密碼都為admin,則通過驗證模擬生成一個Token。然后調(diào)用setStorageAPI接口將Token存入本地緩存并跳轉(zhuǎn)到index.vue頁面。import{ref}from'vue';letuserName=ref("")letpassword=ref("")functionlogin(){ //可通過uni.request向后端發(fā)送請求驗證用戶名密碼是否正確,如果正確返回Token if(userName.value=="admin"&&password.value=="admin"){ lettoken=userName.value+pas

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論