服務器搭建完成之后,編寫了諸多api用于數據傳輸工作(略)
編寫完成之后,回到鴻蒙開發工具,開始編寫搜索頁面的代碼。
打開搜索頁面時,先會展示歷史搜索記錄(如果有的話),然后會根據熱門搜索向用戶推薦搜索內容。當用戶點擊歷史搜索或者熱門搜索的標簽或者手動輸入搜索內容并點擊搜索時,搜索提示將會消失,并展示搜索結果。
在編寫的過程中遇到了一個問題:
@State search: boolean = false;
onSearch(textInput) {this.search = true;
}
?
build() {SearchCard({ onSearch: this.onSearch })if(!this.search) {...}
}
將函數作為參數傳遞給子組件,子組件調用該函數并改變了響應式變量的值,但是卻沒有引起重繪。具體原因未知,但是可以將響應式變量使用@Link傳入子組件中,在子組件中修改變量的值,這樣就可以觸發響應重繪。
搜索頁面效果展示(數據僅為樣例):
當用戶搜索出來這些列表之后,點某個商店可以進入商店詳情頁并展示該商店所售賣的單品,而點某個單品可以進入商店并滾動到單品所在地。同時,數據庫中還包含了單品所屬類別,所以詳情頁可以按照類別來規劃單品。
設計頁面如下
遇到的問題
在父組件中定義函數,并將函數傳給子組件,子組件調用函數時報錯
錯誤原因:子組件調用函數時找不到函數中this所指的定義在父組件中的數據,所以在傳遞函數時需要用 .bind(this)
將this引用一同傳遞過去。
接下來來實現購物車界面,此界面參考美團購物車界面:
可以看到,同一家商店的商品會被歸類到一個卡片中,每個商品前都有選擇框,每個商店卡片頭部也有選擇框控制是否選擇自家的所有商品,同時,在頁腳處,有一個全局的選擇框控制是否全選商品;當點擊頭部的編輯按鈕時,頁尾的結算按鈕會變成刪除按鈕,刪除所有選中的商品。
本人實現該界面的方法是:頁首頁腳單獨編寫兩個組件Header、Footer來控制,隨后通過算法分類出每個出現的商店和商品,通過ForEach渲染出相應的卡片組件StoreCard,在卡片中再次ForEach渲染出子組件ProductCard。然而考慮到還需要實現選擇功能,所以使用@Observed
修飾相關類后通過@ObjectLink
傳遞給子組件。
中間遇到了一點小問題:
在這個卡片中,預想的效果應當是:
-
當點擊商店名旁邊的選擇框時,應當全選或全不全所有該商店的商品。
-
當未點擊商店名旁的選擇框而是手動選擇了全部商品,此時商店選擇框應當自動被勾選
-
當全選了商店的商品時,若手動取消了某個商品的選擇,應當自動取消勾選商店的全選框
最初我為商店的全選按鈕添加了 onChange
事件:
.onChange((value) => {for (let index = 0; index < this.storeItem.child.length; index++) {this.storeItem.child[index].selected = value;}})
這樣就可以實現點擊全選后選擇所有商品。但是當測試上述第三個功能時,子組件的改變引起了父組件單選框狀態的改變,此時會觸發這個 onChange
函數,取消一個商品的選擇,導致所有不相關的商品一同被取消了選擇。
解決方法是:將 onChange
改為 onClick
事件,原理很簡單,只有當用戶點擊全選按鈕時才會觸發所有商品的全選/全不選方法,所以改為onClick
可以避免程序修改selected
的值而觸發事件。
最后編寫個人主頁見面,初步實現如下: