1.地理定位
使用方法

javascript
"requiredPrivateInfos":["getLocation","chooseLocation"],
"permission":{
"scope.userLocation":{
"desc":"获取地理位置信息用于填写收货地址"
}
}
获取位置
javascript
async onLocation() {
const { latitude, longitude } = await wx.getLocation()
console.log(location)
}
打开地图选择位置
javascript
async onLocation() {
const { latitude, longitude } = await wx.chooseLocation()
console.log(res)
}
2.拒绝授权和授权完整流程

javascript
async onLocation() {
const { authSetting } = await wx.getSetting()
console.log(authSetting)
if (authSetting['scope.userLocation'] === false) {
const modalRes = await wx.modal({
title: '授权提示',
content: '需要需要您的地理位置信息,请确认授权'
})
if (!modalRes) return wx.toast({ title: '您拒绝了授权' })
const { authSetting } = await wx.openSetting()
if (!authSetting['scope.userLocation'])
return wx.toast({ title: '授权失败!' })
try {
const locationRes = await wx.getLocation()
console.log(locationRes)
} catch (err) {
console.log(err)
}
} else {
try {
const locationRes = await wx.getLocation()
console.log(locationRes)
} catch (error) {
wx.toast({ title: '您拒绝授权获取地址位置' })
}
}
}
3.腾讯位置服务
引入SDK核心类
javascript
import QQMapWX from '../../../../libs/qqmap-wx-jssdk'
实例化API核心类
javascript
Page({
onLoad: function () {
this.qqmapsdk = new QQMapWX({
key: '申请的key'
})
}
}
逆地址解析
javascript
async onLocation() {
let { longitude, latitude, name } = await wx.chooseLocation()
this.qqmapsdk.reverseGeocoder({
location: { longitude, latitude},
success: (res) => {
const {
province,
city,
district,
adcode,
} = res.result.ad_info
const { street, street_number } = res.result.address_component
const { standard_address } = res.result.formatted_addresses
this.setData({
provinceCode: adcode.replace(adcode.substring(2, 6), '0000'),
provinceName: province,
cityCode: adcode.replace(adcode.substring(4, 6), '00'),
cityName: city,
districtCode: district && adcode,
districtName: district,
address: street + street_number + name,
fullAddress: standard_address + name
})
}
})
}
4表单验证-async-validator基本使用
使用 npm i async-validator 安装 async-validator,之后点击工具中的构建npm
从 async-validator中引入构造函数
javascript
import Schema from 'async-validator'
javascript
Page({
data: {
name: '你好'
},
onValidate() {
const rules = {
name: [
{ required: true, message: 'name 不能为空' },
//type 验证数据类型
{ type: 'string', message: 'name 不是字符串' },
//min最少位数,max最大位数
{ min: 2, max: 5, message: '名字最少 2 个字,最多 5 个字' }
// 正则表达式
{ pattern: '', message: '' }
// 自定义验证规则
/{ validator: () => {} }
]
}
const validator = new Schema(rules)
validator.validate(this.data, (errors, fields) => {
console.log(errors)
console.log(fields)
if (errors) {
console.log('验证没有通过')
console.log(errors)
return
}
console.log('验证通过')
})
}
})
5.新增收货地址
javascript
async saveAddrssForm(event) {
const {
provinceName,
cityName,
districtName,
address,
isDefault
} = this.data
const params = {
...this.data,
fullAddress: provinceName + cityName + districtName + address,
isDefault: isDefault ? 1 : 0
}
if (!valid) return
const res = await reqAddAddress(params)
if (res.code === 200) {
wx.toast({ title: '新增收货地址成功' })
wx.navigateBack()
}
}
6.收货地址列表渲染
在pages/address/list/index.js中
javascript
import { reqAddressList } from '../../../../../api/address'
Page({
data: {
addressList: []
},
async getAddressList() {
const { data: addressList } = await reqAddressList()
this.setData({
addressList
})
},
toEdit() {
wx.navigateTo({
url: '/modules/settingModule/pages/address/add/index'
})
},
onLoad() {
this.getAddressList()
}
})
在HTML中
html
<view class="list-warpper">
<view wx:for="{{ addressList }}" wx:key="id" class="list-item">
<view class="info">
<view class="user-info">
<text class="text">{{ item.name }}</text>
<text class="text">{{ item.phone }}</text>
<text class="text tag">{{ item.tagName }}</text>
<text class="text default-tag" wx:if="{{ item.isDefault === 1 }}">默认</text>
</view>
<view class="address-info">{{ item.fullAddress }}</view>
</view>
<van-icon bindtap="toEdit" name="edit" size="22px" color="#999" />
<van-icon name="delete" size="22px" color="#999" />
</view>
7.更新收货地址
javascript
toEdit(e) {
const { id } = e.target.dataset
wx.navigateTo({
url: `/pages/address/add/index?id=${id}`,
})
}
8.删除收货地址
javascript
async delAddress(e) {
const { id } = e.currentTarget.dataset
await reqDelAddress(id)
this.getAddressList()
}
9.封装商品模块接口API
javascript
{
"subPackages": [
{
"root": "modules/settingModule",
"name": "settingModule",
"pages": [
"pages/address/add/index",
"pages/address/list/index",
"pages/profile/profile"
]
},
{
"root": "modules/goodModule",
"name": "goodModule",
"pages": ["pages/goods/list/list", "pages/goods/detail/detail"]
}
],
"preloadRule": {
"pages/settings/settings": {
"network": "all",
"packages": ["settingModule"]
},
"pages/category/category": {
"network": "all",
"packages": ["goodModule"]
}
}
}
10.准备列表请求参数
javascript
Page({
data: {
goodsList: [],
isFinish: false,
requestData: {
page: 1,
limit: 10,
category1Id: '',
category2Id: ''
}
},
onLoad(options) {
Object.assign(this.data.requestData, options)
}
})
11.获取商品列表数数据并渲染
javascript
import { reqGoodsList } from '../../../../../api/good'
Page({
data: {
goodsList: [],
total: 0,
isFinish: false,
requestData: {
page: 1,
limit: 10,
category1Id: '',
category2Id: ''
}
},
async getGoodsList() {
const { data } = await reqGoodsList(this.data.requestData)
this.setData({
goodsList: data.records,
total: data.total
})
},
onLoad(options) {
Object.assign(this.data.requestData, options)
this.getGoodsList()
}
})
html
<view class="container">
<view class="goods-list" wx:if="{{ goodsList.length }}">
<block wx:for="{{ goodsList }}" wx:key="id">
<goods-card goodItem="{{ item }}"></goods-card>
</block>
<view class="finish" hidden="{{ !isFinish }}">数据加载完毕~~~</view>
</view>
<van-empty wx:else description="该分类下暂无商品,去看看其他商品吧~">
<van-button round type="danger" class="bottom-button" bindtap="gotoBack">
查看其他商品
</van-button>
</van-empty>
</view
12.上拉加载更多功能
javascript
import { reqGoodsList } from '../../../api/goods'
Page({
async getGoodsList() {
const { data } = await reqGoodsList(this.data.params)
this.setData({
goodsList: [...this.data.goodsList, ...data.records],
total: data.total
})
},
onReachBottom() {
let { page } = this.data.requestData
this.setData({
requestData: { ...this.data.requestData, page: (page += 1) }
})
this.getGoodsList()
}
})
13.判断数据加载是否完毕
javascript
import { reqGoodsList } from '../../../api/goods'
Page({
onReachBottom() {
const { total, goodsList, requestData } = this.data
let { page } = requestData
if (total === goodsList.length) {
this.setData({
isFinish: true
})
return
}
this.setData({
requestData: { ...this.data.requestData, page: (page += 1) }
})
this.getGoodsList()
}
})
14.节流阀进行列表节
javascript
import { reqGoodsList } from '../../../../../api/good'
Page({
data: {
goodsList: [],
isFinish: false,
isLoading: false,
total: 0,
requestData: {
page: 1,
limit: 10,
category1Id: '',
category2Id: ''
}
},
async getGoodsList() {
this.data.isLoading = true
const { data } = await reqGoodsList(this.data.requestData)
this.data.isLoading = false
this.setData({
goodsList: [...this.data.goodsList, ...data.records],
total: data.total
})
},
onReachBottom() {
const { total, goodsList, requestData, isLoading } = this.data
let { page } = requestData
if (isLoading) return
.
}
})
15.下拉刷新
javascript
{
"usingComponents": {
"goods-card": "/components/goods-card/goods-card"
},
"navigationBarTitleText": "商品列表",
"enablePullDownRefresh": true,
"backgroundColor": "#f7f4f8",
"backgroundTextStyle": "dark"
}
javascript
onPullDownRefresh() {
this.setData({
goodsList: [],
total: 0,
isFinish: false,
requestData: { ...this.data.requestData, page: 1 }
})
this.getGoodsList()
}
16.封装购物车接口API
javascript
import http from '../utils/http'
/**
* @description
* @returns Promise
*/
export const reqCartList = () => {
return http.get('/mall-api/cart/getCartList')
}
/**
* @description
* @param {*} data
* @returns Promise
*/
export const reqAddCart = ({ goodsId, count, ...data }) => {
return http.get(`/cart/addToCart/${goodsId}/${count}`, data)
}
/**
* @description
* @param {*} goodsId
* @param {*} isChecked
* @returns Promise
*/
export const reqUpdateChecked = (goodsId, isChecked) => {
return http.get(`/cart/checkCart/${goodsId}/${isChecked}`)
}
/**
* @description
* @param {*} isChecked
* @returns Promise
*/
export const reqCheckAllCart = (isChecked) => {
return http.get(`/cart/checkAllCart/${isChecked}`)
}
/**
* @description
* @param {*} goodsId
* @returns Promise
*/
export const reqDelCart = (goodsId) => {
return http.get(`/cart/delete/${goodsId}`)
}
17.模块分析和渲染
javascript
<van-goods-action>
<van-goods-action-button text="加入购物车" type="warning" bindtap="handleAddcart" />
<van-goods-action-button text="立即购买" bindtap="handeGotoBuy" />
</van-goods-action>
<van-action-sheet show="{{ show }}" bind:close="onClose">
<view class="sheet-wrapper">
<view class="buy-btn" wx:if="{{ buyNow === 0 }}">
<van-stepper value="{{ count }}" bind:change="onChangeGoodsCount" />
</view>
</view>
</van-action-sheet>
javascript
Page({
data: {
goodsInfo: {},
show: false,
count: 1,
blessing: '',
buyNow: ''
},
handleAddcart() {
this.setData({
show: true,
buyNow: 0
})
},
handeGotoBuy() {
this.setData({
show: true,
buyNow: 1
})
},
}
18.关联store对象
javascript
import { BehaviorWithStore } from 'mobx-miniprogram-bindings'
import { userStore } from '@/stores/userstore'
export const userBehavior = BehaviorWithStore({
storeBindings: {
store: userStore,
fields: ['token']
}
}
19.立即购买和加入购物车
javascript
<van-stepper
value="{{ count }}"
integer
min="1"
max="200"
bind:change="onChangeGoodsCount"
/>
javascript
async handleSubmit() {
const { token, count, blessing, buyNow } = this.data
const goodsId = this.goodsId
if (!this.data.token) {
wx.navigateTo({
url: '/pages/login/login'
})
return
}
if (buyNow === 0) {
const res = await reqAddGood({ goodsId, count, blessing })
if (res.code === 200) {
wx.showToast({
title: '加入购物车成功'
})
this.setData({
show: false
})
}
} else {
wx.navigateTo({
url: `/pages/order/detail/index?goodsId=${goodsId}&blessing=${blessing}`
})
}
}
20.展示购物车购买数量
javascript
Page({
data: {
allCount: ''
},
async handleSubmit() {
if (!this.data.token) {
wx.navigateTo({
url: '/pages/login/login'
})
return
}
const { count, blessing, allCount } = this.data
const goodsId = this.goodsId
if (this.data.buyNow === 0) {
const res = await reqAddCart({ goodsId, count, blessing })
if (res.code === 200) {
wx.toast({
title: '加入购物车成功',
icon: 'success',
mask: false
})
this.getCartCount()
this.setData({
show: false
})
}
} else {
wx.navigateTo({
url: `/pages/order/detail/detail?goodsId=${goodsId}&blessing=${blessing}`
})
}
},
async getCartCount() {
if (!this.data.token) return
const res = await reqCartList()
if (res.data.length !== 0) {
let allCount = 0
res.data.forEach((item) => {
allCount += item.count
})
this.setData({
allCount: (allCount > 99 ? '99+' : allCount) + ''
})
}
},
onLoad(options) {
this.goodsId = options.goodsId
this.getGoodsInfo()
this.getCartCount()
}
})