1.0 創(chuàng)建 goodslist 分支
1.1 定義請求參數(shù)對象
為了方便發(fā)起請求獲取商品列表的數(shù)據(jù),我們要根據(jù)接口的要求,事先定義一個請求參數(shù)對象:
data ( ) { return { queryObj
: { query
: '' , cid
: '' , pagenum
: 1 , pagesize
: 10 } }
}
將頁面跳轉(zhuǎn)時攜帶的參數(shù),轉(zhuǎn)存到 queryObj 對象中:
onLoad ( options ) { this . queryObj
. query
= options
. query
|| '' this . queryObj
. cid
= options
. cid
|| ''
}
為了方便開發(fā)商品分類頁面,建議大家通過微信開發(fā)者工具,新建商品列表頁面的編譯模式:
1.2 獲取商品列表數(shù)據(jù)
在 data 中新增如下的數(shù)據(jù)節(jié)點: 在 onLoad 生命周期函數(shù)中,調(diào)用 getGoodsList 方法獲取商品列表數(shù)據(jù): 在 methods 節(jié)點中,聲明 getGoodsList 方法如下:
data ( ) { return { goodsList
: [ ] , total
: 0 }
} onLoad ( options ) { this . getGoodsList ( )
} methods
: { async getGoodsList ( ) { const { data
: res
} = await uni
. $http
. get ( '/api/public/v1/goods/search' , this . queryObj
) if ( res
. meta
. status
!== 200 ) return uni
. $showMsg ( ) this . goodsList
= res
. message
. goods
this . total
= res
. message
. total
}
}
1.3 渲染商品列表結(jié)構(gòu)
在頁面中,通過 v-for 指令,循環(huán)渲染出商品的 UI 結(jié)構(gòu):(用到了 block 空白符) 為了防止某些商品的圖片不存在,需要在 data 中定義一個默認的圖片、并在頁面渲染時按需使用: 美化商品列表的 UI 結(jié)構(gòu):
< template
> < view
> < view
class = "goods-list" > < block v
- for = "(goods, i) in goodsList" : key
= "i" > < view
class = "goods-item" > < ! -- 商品左側(cè)圖片區(qū)域
-- > < view
class = "goods-item-left" > < image
: src
= "goods.goods_small_logo || defaultPic" class = "goods-pic" > < / image
> < / view
> < ! -- 商品右側(cè)信息區(qū)域
-- > < view
class = "goods-item-right" > < ! -- 商品標(biāo)題
-- > < view
class = "goods-name" > { { goods
. goods_name
} } < / view
> < view
class = "goods-info-box" > < ! -- 商品價格
-- > < view
class = "goods-price" > ¥
{ { goods
. goods_price
} } < / view
> < / view
> < / view
> < / view
> < / block
> < / view
> < / view
>
< / template
> data ( ) { return { defaultPic
: 'https://img3.doubanio.com/f/movie/8dd0c794499fe925ae2ae89ee30cd225750457b4/pics/movie/celebrity-default-medium.png' }
} . goods
- item
{ display
: flex
; padding
: 10 px
5 px
; border
- bottom
: 1 px solid #f0f0f0
; . goods
- item
- left
{ margin
- right
: 5 px
; . goods
- pic
{ width
: 100 px
; height
: 100 px
; display
: block
; } } . goods
- item
- right
{ display
: flex
; flex
- direction
: column
; justify
- content
: space
- between
; . goods
- name
{ font
- size
: 13 px
; } . goods
- price
{ font
- size
: 16 px
; color
: #c00000
; } }
}
1.4 把商品 item 項封裝為自定義組件
在 components 目錄上鼠標(biāo)右鍵,選擇 新建組件 my-goods: (沒有 components 文件夾就新建一個) 將 goods_list 頁面中,關(guān)于商品 item 項相關(guān)的 UI 結(jié)構(gòu)、樣式、data 數(shù)據(jù),封裝到 my-goods 組件中:
< template
> < view
class = "goods-item" > < ! -- 商品左側(cè)圖片區(qū)域
-- > < view
class = "goods-item-left" > < image
: src
= "goods.goods_small_logo || defaultPic" class = "goods-pic" > < / image
> < / view
> < ! -- 商品右側(cè)信息區(qū)域
-- > < view
class = "goods-item-right" > < ! -- 商品標(biāo)題
-- > < view
class = "goods-name" > { { goods
. goods_name
} } < / view
> < view
class = "goods-info-box" > < ! -- 商品價格
-- > < view
class = "goods-price" > ¥
{ { goods
. goods_price
} } < / view
> < / view
> < / view
> < / view
>
< / template
> < script
> export default { props
: { goods
: { type
: Object
, defaul
: { } , } , } , data ( ) { return { defaultPic
: 'https://img3.doubanio.com/f/movie/8dd0c794499fe925ae2ae89ee30cd225750457b4/pics/movie/celebrity-default-medium.png' , } } , }
< / script
> < style lang
= "scss" > . goods
- item
{ display
: flex
; padding
: 10 px
5 px
; border
- bottom
: 1 px solid #f0f0f0
; . goods
- item
- left
{ margin
- right
: 5 px
; . goods
- pic
{ width
: 100 px
; height
: 100 px
; display
: block
; } } . goods
- item
- right
{ display
: flex
; flex
- direction
: column
; justify
- content
: space
- between
; . goods
- name
{ font
- size
: 13 px
; } . goods
- price
{ font
- size
: 16 px
; color
: #c00000
; } } }
< / style
>
在 goods_list 組件中,循環(huán)渲染 my-goods 組件即可:
< view
class = "goods-list" > < block v
- for = "(item, i) in goodsList" : key
= "i" > < ! -- 為 my
- goods 組件動態(tài)綁定 goods 屬性的值
-- > < my
- goods
: goods
= "item" > < / my
- goods
> < / block
>
< / view
>
1.5 使用過濾器處理價格
在 my-goods 組件中,和 data 節(jié)點平級,聲明 filters 過濾器節(jié)點如下:
filters
: { tofixed ( num ) { return Number ( num
) . toFixed ( 2 ) }
}
在渲染商品價格的時候,通過管道符 | 調(diào)用過濾器:
< ! -- 商品價格
-- >
< view
class = "goods-price" > ¥
{ { goods
. goods_price
| tofixed
} } < / view
>
1.6 上拉加載更多
打開項目根目錄中的 pages.json 配置文件,為 subPackages 分包中的 goods_list 頁面配置上拉觸底的距離:
"subPackages" : [ { "root" : "subpkg" , "pages" : [ { "path" : "goods_detail/goods_detail" , "style" : { } } , { "path" : "goods_list/goods_list" , "style" : { "onReachBottomDistance" : 150 } } , { "path" : "search/search" , "style" : { } } ] } ]
在 goods_list 頁面中,和 methods 節(jié)點平級,聲明 onReachBottom 事件處理函數(shù),用來監(jiān)聽頁面的上拉觸底行為:
onReachBottom ( ) { this . queryObj
. pagenum
+= 1 this . getGoodsList ( )
}
改造 methods 中的 getGoodsList 函數(shù),當(dāng)列表數(shù)據(jù)請求成功之后,進行新舊數(shù)據(jù)的拼接處理:
async getGoodsList ( ) { const { data
: res
} = await uni
. $http
. get ( '/api/public/v1/goods/search' , this . queryObj
) if ( res
. meta
. status
!== 200 ) return uni
. $showMsg ( ) this . goodsList
= [ ... this . goodsList
, ... res
. message
. goods
] this . total
= res
. message
. total
}
1.7 通過節(jié)流閥防止發(fā)起額外的請求
在 data 中定義 isloading 節(jié)流閥如下:
data ( ) { return { isloading
: false }
}
修改 getGoodsList 方法,在請求數(shù)據(jù)前后,分別打開和關(guān)閉節(jié)流閥:
async getGoodsList ( ) { this . isloading
= true const { data
: res
} = await uni
. $http
. get ( '/api/public/v1/goods/search' , this . queryObj
) this . isloading
= false
}
在 onReachBottom 觸底事件處理函數(shù)中,根據(jù)節(jié)流閥的狀態(tài),來決定是否發(fā)起請求:
onReachBottom ( ) { if ( this . isloading
) return this . queryObj
. pagenum
+= 1 this . getGoodsList ( )
}
1.8 判斷數(shù)據(jù)是否加載完畢
如果下面的公式成立,則證明沒有下一頁數(shù)據(jù)了:
當(dāng)前的頁碼值
* 每頁顯示多少條數(shù)據(jù)
>= 總數(shù)條數(shù)
pagenum
* pagesize
>= total
修改 onReachBottom 事件處理函數(shù)如下:
onReachBottom ( ) { if ( this . queryObj
. pagenum
* this . queryObj
. pagesize
>= this . total
) return uni
. $showMsg ( '數(shù)據(jù)加載完畢!' ) if ( this . isloading
) return this . queryObj
. pagenum
+= 1 this . getGoodsList ( )
}
1.9 下拉刷新
在 pages.json 配置文件中,為當(dāng)前的 goods_list 頁面單獨開啟下拉刷新效果:
"subPackages" : [ { "root" : "subpkg" , "pages" : [ { "path" : "goods_detail/goods_detail" , "style" : { } } , { "path" : "goods_list/goods_list" , "style" : { "onReachBottomDistance" : 150 , "enablePullDownRefresh" : true , "backgroundColor" : "#F8F8F8" } } , { "path" : "search/search" , "style" : { } } ]
} ]
監(jiān)聽頁面的 onPullDownRefresh 事件處理函數(shù):
onPullDownRefresh ( ) { this . queryObj
. pagenum
= 1 this . total
= 0 this . isloading
= false this . goodsList
= [ ] this . getGoodsList ( ( ) => uni
. stopPullDownRefresh ( ) )
}
修改 getGoodsList 函數(shù),接收 cb 回調(diào)函數(shù)并按需進行調(diào)用:
async getGoodsList ( cb ) { this . isloading
= true const { data
: res
} = await uni
. $http
. get ( '/api/public/v1/goods/search' , this . queryObj
) this . isloading
= false cb
&& cb ( ) if ( res
. meta
. status
!== 200 ) return uni
. $showMsg ( ) this . goodsList
= [ ... this . goodsList
, ... res
. message
. goods
] this . total
= res
. message
. total
}
1.20 點擊商品 item 項跳轉(zhuǎn)到詳情頁面
將循環(huán)時的 block 組件修改為 view 組件 ,并綁定 click 點擊事件處理函數(shù):
< view
class = "goods-list" > < view v
- for = "(item, i) in goodsList" : key
= "i" @click
= "gotoDetail(item)" > < ! -- 為 my
- goods 組件動態(tài)綁定 goods 屬性的值
-- > < my
- goods
: goods
= "item" > < / my
- goods
> < / view
>
< / view
>
在 methods 節(jié)點中,定義 gotoDetail 事件處理函數(shù):
gotoDetail ( item ) { uni
. navigateTo ( { url
: '/subpkg/goods_detail/goods_detail?goods_id=' + item
. goods_id
} )
}
2.0 商品詳情
2.1 添加商品詳情頁的編譯模式
在微信開發(fā)者工具中,點擊工具欄上的編譯模式下拉菜單,選擇 添加編譯模式 選項: 勾選 啟動頁面 的路徑,并填寫了 啟動參數(shù) 之后,點擊 確定 按鈕,添加詳情頁面的編譯模式:
2.2 獲取商品詳情數(shù)據(jù)
在 data 中定義商品詳情的數(shù)據(jù)節(jié)點:
data ( ) { return { goods_info
: { } }
}
在 onLoad 中獲取商品的 Id,并調(diào)用請求商品詳情的方法:
onLoad ( options ) { const goods_id
= options
. goods_id
this . getGoodsDetail ( goods_id
)
}
在 methods 中聲明 getGoodsDetail 方法:
methods
: { async getGoodsDetail ( goods_id ) { const { data
: res
} = await uni
. $http
. get ( '/api/public/v1/goods/detail' , { goods_id
} ) if ( res
. meta
. status
!== 200 ) return uni
. $showMsg ( ) this . goods_info
= res
. message
}
}
2.3 渲染商品詳情頁的 UI 結(jié)構(gòu)
2.31 渲染輪播圖區(qū)域
使用 v-for 指令,循環(huán)渲染如下的輪播圖 UI 結(jié)構(gòu):
< ! -- 輪播圖區(qū)域
-- >
< swiper
: indicator
- dots
= "true" : autoplay
= "true" : interval
= "3000" : duration
= "1000" : circular
= "true" > < swiper
- item v
- for = "(item, i) in goods_info.pics" : key
= "i" > < image
: src
= "item.pics_big" > < / image
> < / swiper
- item
>
< / swiper
>
美化輪播圖的樣式:
swiper
{ height
: 750 rpx
; image
{ width
: 100 % ; height
: 100 % ; }
}
2.32 實現(xiàn)輪播圖預(yù)覽效果
為輪播圖中的 image 圖片綁定 click 事件處理函數(shù):
< swiper
- item v
- for = "(item, i) in goods_info.pics" : key
= "i" > < ! -- 把當(dāng)前點擊的圖片的索引,傳遞到
preview ( ) 處理函數(shù)中
-- > < image
: src
= "item.pics_big" @click
= "preview(i)" > < / image
>
< / swiper
- item
>
在 methods 中定義 preview 事件處理函數(shù):
preview ( i ) { uni
. previewImage ( { current
: i
, urls
: this . goods_info
. pics
. map ( x => x
. pics_big
) } )
}
2.33 渲染商品信息區(qū)域
定義商品信息區(qū)域的 UI 結(jié)構(gòu)如下:
< ! -- 商品信息區(qū)域
-- >
< view
class = "goods-info-box" > < ! -- 商品價格
-- > < view
class = "price" > ¥
{ { goods_info
. goods_price
} } < / view
> < ! -- 信息主體區(qū)域
-- > < view
class = "goods-info-body" > < ! -- 商品名稱
-- > < view
class = "goods-name" > { { goods_info
. goods_name
} } < / view
> < ! -- 收藏
-- > < view
class = "favi" > < uni
- icons type
= "star" size
= "18" color
= "gray" > < / uni
- icons
> < text
> 收藏
< / text
> < / view
> < / view
> < ! -- 運費
-- > < view
class = "yf" > 快遞:免運費
< / view
>
< / view
>
美化商品信息區(qū)域的樣式:
. goods
- info
- box
{ padding
: 10 px
; padding
- right
: 0 ; . price
{ color
: #c00000
; font
- size
: 18 px
; margin
: 10 px
0 ; } . goods
- info
- body
{ display
: flex
; justify
- content
: space
- between
; . goods
- name
{ font
- size
: 13 px
; padding
- right
: 10 px
; } . favi
{ width
: 120 px
; font
- size
: 12 px
; display
: flex
; flex
- direction
: column
; justify
- content
: center
; align
- items
: center
; border
- left
: 1 px solid #efefef
; color
: gray
; } } . yf
{ margin
: 10 px
0 ; font
- size
: 12 px
; color
: gray
; }
}
2.34 渲染商品詳情信息
在頁面結(jié)構(gòu)中,使用 rich-text 組件,將帶有 HTML 標(biāo)簽的內(nèi)容,渲染為小程序的頁面結(jié)構(gòu):
< ! -- 商品詳情信息
-- >
< rich
- text
: nodes
= "goods_info.goods_introduce" > < / rich
- text
>
修改 getGoodsDetail 方法,從而解決圖片底部 空白間隙 的問題:
async getGoodsDetail ( goods_id ) { const { data
: res
} = await uni
. $http
. get ( '/api/public/v1/goods/detail' , { goods_id
} ) if ( res
. meta
. status
!== 200 ) return uni
. $showMsg ( ) res
. message
. goods_introduce
= res
. message
. goods_introduce
. replace ( / <img / g , '<img style="display:block;" ' ) this . goods_info
= res
. message
}
解決 .webp 格式圖片在 ios 設(shè)備上無法正常顯示的問題:
async getGoodsDetail ( goods_id ) { const { data
: res
} = await uni
. $http
. get ( '/api/public/v1/goods/detail' , { goods_id
} ) if ( res
. meta
. status
!== 200 ) return uni
. $showMsg ( ) res
. message
. goods_introduce
= res
. message
. goods_introduce
. replace ( / <img / g , '<img style="display:block;" ' ) . replace ( / webp / g , 'jpg' ) this . goods_info
= res
. message
}
3.35 解決商品價格閃爍的問題
導(dǎo)致問題的原因:在商品詳情數(shù)據(jù)請求回來之前,data 中 goods_info 的值為 { },因此初次渲染頁面時,會導(dǎo)致 商品價格、商品名稱 等閃爍的問題。
解決方案:判斷 goods_info.goods_name 屬性的值是否存在,從而使用 v-if 指令控制頁面的顯示與隱藏:
< template
> < view v
- if = "goods_info.goods_name" > < ! -- 省略其它代碼
-- > < / view
>
< / template
>
3.4 渲染詳情頁底部的商品導(dǎo)航區(qū)域
3.41 渲染商品導(dǎo)航區(qū)域的 UI 結(jié)構(gòu)
基于 uni-ui 提供的 GoodsNav 組件來實現(xiàn)商品導(dǎo)航區(qū)域的效果
在 data 中,通過 options 和 buttonGroup 兩個數(shù)組,來聲明商品導(dǎo)航組件的按鈕配置對象:
data ( ) { return { goods_info
: { } , options
: [ { icon
: 'shop' , text
: '店鋪' } , { icon
: 'cart' , text
: '購物車' , info
: 2 } ] , buttonGroup
: [ { text
: '加入購物車' , backgroundColor
: '#ff0000' , color
: '#fff' } , { text
: '立即購買' , backgroundColor
: '#ffa200' , color
: '#fff' } ] }
}
在頁面中使用 uni-goods-nav 商品導(dǎo)航組件:
< ! -- 商品導(dǎo)航組件
-- >
< view
class = "goods_nav" > < ! -- fill 控制右側(cè)按鈕的樣式
-- > < ! -- options 左側(cè)按鈕的配置項
-- > < ! -- buttonGroup 右側(cè)按鈕的配置項
-- > < ! -- click 左側(cè)按鈕的點擊事件處理函數(shù)
-- > < ! -- buttonClick 右側(cè)按鈕的點擊事件處理函數(shù)
-- > < uni
- goods
- nav
: fill
= "true" : options
= "options" : buttonGroup
= "buttonGroup" @click
= "onClick" @buttonClick
= "buttonClick" / >
< / view
>
美化商品導(dǎo)航組件,使之固定在頁面最底部:
. goods
- detail
- container
{ padding
- bottom
: 50 px
;
} . goods_nav
{ position
: fixed
; bottom
: 0 ; left
: 0 ; width
: 100 % ;
}
3.4.2 點擊跳轉(zhuǎn)到購物車頁面
點擊商品導(dǎo)航組件左側(cè)的按鈕,會觸發(fā) uni-goods-nav 的 @click 事件處理函數(shù),事件對象 e 中會包含當(dāng)前點擊的按鈕相關(guān)的信息:
onClick ( e ) { console
. log ( e
)
}
根據(jù) e.content.text 的值,來決定進一步的操作:
onClick ( e ) { if ( e
. content
. text
=== '購物車' ) { uni
. switchTab ( { url
: '/pages/cart/cart' } ) }
}
4.0 加入購物車
4.1 配置 vuex
在項目根目錄中創(chuàng)建 store 文件夾,專門用來存放 vuex 相關(guān)的模塊 在 store 目錄上鼠標(biāo)右鍵,選擇 新建 -> js文件,新建 store.js 文件: 在 store.js 中按照如下 4 個步驟初始化 Store 的實例對象:
import Vue
from 'vue'
import Vuex
from 'vuex'
Vue
. use ( Vuex
)
const store
= new Vuex. Store ( { modules
: { } ,
} )
export default store
在 main.js 中導(dǎo)入 store 實例對象并掛載到 Vue 的實例上:
import store
from './store/store.js' const app
= new Vue ( { ... App
, store
,
} )
app
. $mount ( )
4.2 創(chuàng)建購物車的 store 模塊
在 store 目錄上鼠標(biāo)右鍵,選擇 新建 -> js文件,創(chuàng)建購物車的 store 模塊,命名為 cart.js: 在 cart.js 中,初始化如下的 vuex 模塊:
export default { namespaced
: true , state : ( ) => ( { cart
: [ ] , } ) , mutations
: { } , getters
: { } ,
}
在 store/store.js 模塊中,導(dǎo)入并掛載購物車的 vuex 模塊,示例代碼如下:
import Vue
from 'vue'
import Vuex
from 'vuex'
import moduleCart
from './cart.js' Vue
. use ( Vuex
) const store
= new Vuex. Store ( { modules
: { m_cart
: moduleCart
, } ,
} ) export default store
4.3 在商品詳情頁中使用 Store 中的數(shù)據(jù)
在 goods_detail.vue 頁面中,修改 標(biāo)簽中的代碼如下:
import { mapState
} from 'vuex' export default { computed
: { ... mapState ( 'm_cart' , [ 'cart' ] ) , } ,
}
注意:今后無論映射 mutations 方法,還是 getters 屬性,還是 state 中的數(shù)據(jù),都需要指定模塊的名稱,才能進行映射。
在頁面渲染時,可以直接使用映射過來的數(shù)據(jù),例如:
< ! -- 運費
-- >
< view
class = "yf" > 快遞:免運費
-- { { cart
. length
} } < / view
>
8.4 實現(xiàn)加入購物車的功能
在 store 目錄下的 cart.js 模塊中,封裝一個將商品信息加入購物車的 mutations 方法,命名為 addToCart。示例代碼如下:
export default { namespaced
: true , state : ( ) => ( { cart
: [ ] , } ) , mutations
: { addToCart ( state, goods ) { const findResult
= state
. cart
. find ( ( x ) => x
. goods_id
=== goods
. goods_id
) if ( ! findResult
) { state
. cart
. push ( goods
) } else { findResult
. goods_count
++ } } , } , getters
: { } ,
}
在商品詳情頁面中,通過 mapMutations 這個輔助方法,把 vuex 中 m_cart 模塊下的 addToCart 方法映射到當(dāng)前頁面:
import { mapMutations
} from 'vuex' export default { methods
: { ... mapMutations ( 'm_cart' , [ 'addToCart' ] ) , } ,
}
為商品導(dǎo)航組件 uni-goods-nav 綁定 @buttonClick=“buttonClick” 事件處理函數(shù):
buttonClick ( e ) { if ( e
. content
. text
=== '加入購物車' ) { const goods
= { goods_id
: this . goods_info
. goods_id
, goods_name
: this . goods_info
. goods_name
, goods_price
: this . goods_info
. goods_price
, goods_count
: 1 , goods_small_logo
: this . goods_info
. goods_small_logo
, goods_state
: true } this . addToCart ( goods
) }
}
8.5 動態(tài)統(tǒng)計購物車中商品的總數(shù)量
在 cart.js 模塊中,在 getters 節(jié)點下定義一個 total 方法,用來統(tǒng)計購物車中商品的總數(shù)量:
getters
: { total ( state ) { let c
= 0 state
. cart
. forEach ( goods => c
+= goods
. goods_count
) return c
}
}
在商品詳情頁面的 script 標(biāo)簽中,按需導(dǎo)入 mapGetters 方法并進行使用:
import { mapGetters
} from 'vuex' export default { computed
: { ... mapGetters ( 'm_cart' , [ 'total' ] ) , } ,
}
通過 watch 偵聽器,監(jiān)聽計算屬性 total 值的變化,從而動態(tài)為購物車按鈕的徽標(biāo)賦值:
export default { watch
: { total ( newVal ) { const findResult
= this . options
. find ( ( x ) => x
. text
=== '購物車' ) if ( findResult
) { findResult
. info
= newVal
} } , } ,
}
8.6 持久化存儲購物車中的商品
在 cart.js 模塊中,聲明一個叫做 saveToStorage 的 mutations 方法,此方法負責(zé)將購物車中的數(shù)據(jù)持久化存儲到本地:
saveToStorage ( state ) { uni
. setStorageSync ( 'cart' , JSON . stringify ( state
. cart
) )
}
修改 mutations 節(jié)點中的 addToCart 方法,在處理完商品信息后,調(diào)用步驟 1 中定義的 saveToStorage 方法:
addToCart ( state, goods ) { const findResult
= state
. cart
. find ( x => x
. goods_id
=== goods
. goods_id
) if ( ! findResult
) { state
. cart
. push ( goods
) } else { findResult
. goods_count
++ } this . commit ( 'm_cart/saveToStorage' )
}
修改 cart.js 模塊中的 state 函數(shù),讀取本地存儲的購物車數(shù)據(jù),對 cart 數(shù)組進行初始化:
state : ( ) => ( { cart
: JSON . parse ( uni
. getStorageSync ( 'cart' ) || '[]' )
} ) ,
8.7 優(yōu)化商品詳情頁的 total 偵聽器
使用普通函數(shù)的形式定義的 watch 偵聽器,在頁面首次加載后不會被調(diào)用。因此導(dǎo)致了商品詳情頁在首次加載完畢之后,不會將商品的總數(shù)量顯示到商品導(dǎo)航區(qū)域:
watch
: { total ( newVal ) { const findResult
= this . options
. find ( x => x
. text
=== '購物車' ) if ( findResult
) { findResult
. info
= newVal
} }
}
為了防止這個上述問題,可以使用對象的形式來定義 watch 偵聽器(詳細文檔請參考 Vue 官方的 watch 偵聽器教程),示例代碼如下:
watch
: { total
: { handler ( newVal ) { const findResult
= this . options
. find ( x => x
. text
=== '購物車' ) if ( findResult
) { findResult
. info
= newVal
} } , immediate
: true }
}
8.8 動態(tài)為 tabBar 頁面設(shè)置數(shù)字徽標(biāo)
需求描述:從商品詳情頁面導(dǎo)航到購物車頁面之后,需要為 tabBar 中的購物車動態(tài)設(shè)置數(shù)字徽標(biāo)。
把 Store 中的 total 映射到 cart.vue 中使用:
import { mapGetters
} from 'vuex' export default { data ( ) { return { } } , computed
: { ... mapGetters ( 'm_cart' , [ 'total' ] ) , } ,
}
在頁面剛顯示出來的時候,立即調(diào)用 setBadge 方法,為 tabBar 設(shè)置數(shù)字徽標(biāo):
onShow ( ) { this . setBadge ( )
}
在 methods 節(jié)點中,聲明 setBadge 方法如下,通過 uni.setTabBarBadge() 為 tabBar 設(shè)置數(shù)字徽標(biāo):
methods
: { setBadge ( ) { uni
. setTabBarBadge ( { index
: 2 , text
: this . total
+ '' } ) }
}
8.9 將設(shè)置 tabBar 徽標(biāo)的代碼抽離為 mixins
注意:除了要在 cart.vue 頁面中設(shè)置購物車的數(shù)字徽標(biāo),還需要在其它 3 個 tabBar 頁面中,為購物車設(shè)置數(shù)字徽標(biāo)。
此時可以使用 Vue 提供的 mixins 特性,提高代碼的可維護性。
在項目根目錄中新建 mixins 文件夾,并在 mixins 文件夾之下新建 tabbar-badge.js 文件,用來把設(shè)置 tabBar 徽標(biāo)的代碼封裝為一個 mixin 文件:
import { mapGetters
} from 'vuex'
export default { computed
: { ... mapGetters ( 'm_cart' , [ 'total' ] ) , } , onShow ( ) { this . setBadge ( ) } , methods
: { setBadge ( ) { uni
. setTabBarBadge ( { index
: 2 , text
: this . total
+ '' , } ) } , } ,
}
修改 home.vue,cate.vue,cart.vue,my.vue 這 4 個 tabBar 頁面的源代碼,分別導(dǎo)入 @/mixins/tabbar-badge.js 模塊并進行使用:
import badgeMix
from '@/mixins/tabbar-badge.js' export default { mixins
: [ badgeMix
] ,
}
總結(jié)
以上是生活随笔 為你收集整理的uni-app 小程序项目三 1. 商品列表、过滤器、封装商品item组件、上拉加载、节流阀、下拉刷新、2. 商品详情、轮播图、商品价格闪烁问题 3.加入购物车、vuex、持久化存储、mixiins 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。