uni-app:购物车页面--收货地址区域
创始人
2025-05-29 22:12:54

收货地址区域 

创建收货地址组件

在 components 目录上鼠标右键,选择 新建组件,并填写组件相关的信息:

渲染收货地址组件的基本结构:

收货人:escook电话:138XXXX5555收货地址:河北省邯郸市肥乡区xxx 河北省邯郸市肥乡区xxx 河北省邯郸市肥乡区xxx 河北省邯郸市肥乡区xxx 

 美化收货地址组件的样式:

// 底部边框线的样式
.address-border {display: block;width: 100%;height: 5px;
}// 选择收货地址的盒子
.address-choose-box {height: 90px;display: flex;align-items: center;justify-content: center;
}// 渲染收货信息的盒子
.address-info-box {font-size: 12px;height: 90px;display: flex;flex-direction: column;justify-content: center;padding: 0 5px;// 第一行.row1 {display: flex;justify-content: space-between;.row1-right {display: flex;align-items: center;.phone {margin-right: 5px;}}}// 第二行.row2 {display: flex;align-items: center;margin-top: 10px;.row2-left {white-space: nowrap;}}
}

 

 

实现收货地址区域的按需展示

在 data 中定义收货地址的信息对象:

export default {data() {return {// 收货地址address: {},}},
}

使用 v-if 和 v-else 实现按需展示:





  

 

 实现选择收货地址的功能

为 请选择收货地址+ 的 button 按钮绑定点击事件处理函数:



定义 chooseAddress 事件处理函数,调用小程序提供的 chooseAddress() API 实现选择收货地址的功能:

methods: {// 选择收货地址async chooseAddress() {// 1. 调用小程序提供的 chooseAddress() 方法,即可使用选择收货地址的功能//    返回值是一个数组:第 1 项为错误对象;第 2 项为成功之后的收货地址对象const [err, succ] = await uni.chooseAddress().catch(err => err)// 2. 用户成功的选择了收货地址if (err === null && succ.errMsg === 'chooseAddress:ok') {// 为 data 里面的收货地址对象赋值this.address = succ}}
}

chooseAddress() 方法 解决方案uni-app项目 在项目根目录中找到 manifest.json 文件,在左侧导航栏选择源码视图,找到mp-weixin 节点,在节点后面加上:(一定要注意在setting节点同级)
"requiredPrivateInfos": [
"getLocation",
"onLocationChange",
"startLocationUpdateBackground",
"chooseAddress"]

地理位置接口新增与相关流程调整 | 微信开放社区 (qq.com)

 

 

 定义收货详细地址的计算属性:

computed: {// 收货详细地址的计算属性addstr() {if (!this.address.provinceName) return ''// 拼接 省,市,区,详细地址 的字符串并返回给用户return this.address.provinceName + this.address.cityName + this.address.countyName + this.address.detailInfo}
}

 渲染收货地址区域的数据:


收货人:{{address.userName}}电话:{{address.telNumber}}收货地址:{{addstr}}

 

将 address 信息存储到 vuex 中 

在 store 目录中,创建用户相关的 vuex 模块,命名为 user.js

export default {// 开启命名空间namespaced: true,// state 数据state: () => ({// 收货地址address: {},}),// 方法mutations: {// 更新收货地址updateAddress(state, address) {state.address = address},},// 数据包装器getters: {},
}

 

 

在 store/store.js 模块中,导入并挂载 user.js 模块:

// 1. 导入 Vue 和 Vuex
import Vue from 'vue'
import Vuex from 'vuex'
// 导入购物车的 vuex 模块
import moduleCart from './cart.js'
// 导入用户的 vuex 模块
import moduleUser from './user.js'// 2. 将 Vuex 安装为 Vue 的插件
Vue.use(Vuex)// 3. 创建 Store 的实例对象
const store = new Vuex.Store({// TODO:挂载 store 模块modules: {// 挂载购物车的 vuex 模块,模块内成员的访问路径被调整为 m_cart,例如:// 购物车模块中 cart 数组的访问路径是 m_cart/cartm_cart: moduleCart,// 挂载用户的 vuex 模块,访问路径为 m_userm_user: moduleUser,},
})// 4. 向外共享 Store 的实例对象
export default store

 

 

改造 address.vue 组件中的代码,使用 vuex 提供的 address 计算属性 替代 data 中定义的本地 address 对象

// 1. 按需导入 mapState 和 mapMutations 这两个辅助函数
import { mapState, mapMutations } from 'vuex'export default {data() {return {// 2.1 注释掉下面的 address 对象,使用 2.2 中的代码替代之// address: {}}},methods: {// 3.1 把 m_user 模块中的 updateAddress 函数映射到当前组件...mapMutations('m_user', ['updateAddress']),// 选择收货地址async chooseAddress() {const [err, succ] = await uni.chooseAddress().catch((err) => err)// 用户成功的选择了收货地址if (err === null && succ.errMsg === 'chooseAddress:ok') {// 3.2 把下面这行代码注释掉,使用 3.3 中的代码替代之// this.address = succ// 3.3 调用 Store 中提供的 updateAddress 方法,将 address 保存到 Store 里面this.updateAddress(succ)}},},computed: {// 2.2 把 m_user 模块中的 address 对象映射当前组件中使用,代替 data 中 address 对象...mapState('m_user', ['address']),// 收货详细地址的计算属性addstr() {if (!this.address.provinceName) return ''// 拼接 省,市,区,详细地址 的字符串并返回给用户return this.address.provinceName + this.address.cityName + this.address.countyName + this.address.detailInfo},},
}

 

 

 将 Store 中的 address 持久化存储到本地

修改 store/user.js 模块中的代码如下:

export default {// 开启命名空间namespaced: true,// state 数据state: () => ({// 3. 读取本地的收货地址数据,初始化 address 对象address: JSON.parse(uni.getStorageSync('address') || '{}'),}),// 方法mutations: {// 更新收货地址updateAddress(state, address) {state.address = address// 2. 通过 this.commit() 方法,调用 m_user 模块下的 saveAddressToStorage 方法将 address 对象持久化存储到本地this.commit('m_user/saveAddressToStorage')},// 1. 定义将 address 持久化存储到本地 mutations 方法saveAddressToStorage(state) {uni.setStorageSync('address', JSON.stringify(state.address))},},// 数据包装器getters: {},
}

  将 addstr 抽离为 getters

目的:为了提高代码的复用性,可以把收货的详细地址抽离为 getters,方便在多个页面和组件之间实现复用。

剪切 my-address.vue 组件中的 addstr 计算属性的代码,粘贴到 user.js 模块中,作为一个 getters 节点:

// 数据包装器
getters: {// 收货详细地址的计算属性addstr(state) {if (!state.address.provinceName) return ''// 拼接 省,市,区,详细地址 的字符串并返回给用户return state.address.provinceName + state.address.cityName + state.address.countyName + state.address.detailInfo}
}

改造 my-address.vue 组件中的代码,通过 mapGetters 辅助函数,将 m_user 模块中的 addstr 映射到当前组件中使用:

// 按需导入 mapGetters 辅助函数
import { mapState, mapMutations, mapGetters } from 'vuex'export default {// 省略其它代码computed: {...mapState('m_user', ['address']),// 将 m_user 模块中的 addstr 映射到当前组件中使用...mapGetters('m_user', ['addstr']),},
}

 

 

 重新选择收货地址

为 class 类名为 address-info-box 的盒子绑定 click 事件处理函数如下:



 

解决收货地址授权失败的问题 

地址改了 现在自动授权的 

如果在选择收货地址的时候,用户点击了取消授权,则需要进行特殊的处理,否则用户将无法再次选择收货地址

改造 chooseAddress 方法如下:

// 选择收货地址
async chooseAddress() {// 1. 调用小程序提供的 chooseAddress() 方法,即可使用选择收货地址的功能//    返回值是一个数组:第1项为错误对象;第2项为成功之后的收货地址对象const [err, succ] = await uni.chooseAddress().catch(err => err)// 2. 用户成功的选择了收货地址if (succ && succ.errMsg === 'chooseAddress:ok') {// 更新 vuex 中的收货地址this.updateAddress(succ)}// 3. 用户没有授权if (err && err.errMsg === 'chooseAddress:fail auth deny') {this.reAuth() // 调用 this.reAuth() 方法,向用户重新发起授权申请}
}

在 methods 节点中声明 reAuth 方法如下:

// 调用此方法,重新发起收货地址的授权
async reAuth() {// 3.1 提示用户对地址进行授权const [err2, confirmResult] = await uni.showModal({content: '检测到您没打开地址权限,是否去设置打开?',confirmText: "确认",cancelText: "取消",})// 3.2 如果弹框异常,则直接退出if (err2) return// 3.3 如果用户点击了 “取消” 按钮,则提示用户 “您取消了地址授权!”if (confirmResult.cancel) return uni.$showMsg('您取消了地址授权!')// 3.4 如果用户点击了 “确认” 按钮,则调用 uni.openSetting() 方法进入授权页面,让用户重新进行授权if (confirmResult.confirm) return uni.openSetting({// 3.4.1 授权结束,需要对授权的结果做进一步判断success: (settingResult) => {// 3.4.2 地址授权的值等于 true,提示用户 “授权成功”if (settingResult.authSetting['scope.address']) return uni.$showMsg('授权成功!请选择地址')// 3.4.3 地址授权的值等于 false,提示用户 “您取消了地址授权”if (!settingResult.authSetting['scope.address']) return uni.$showMsg('您取消了地址授权!')}})
}

思想可以学习 

 解决 iPhone 真机上无法重新授权的问题

问题说明:在 iPhone 设备上,当用户取消授权之后,再次点击选择收货地址按钮的时候,无法弹出授权的提示框!

  1. 导致问题的原因 - 用户取消授权后,再次点击 “选择收货地址” 按钮的时候:

    • 模拟器安卓真机上,错误消息 err.errMsg 的值为 chooseAddress:fail auth deny

    • 在 iPhone 真机上,错误消息 err.errMsg 的值为 chooseAddress:fail authorize no response

  2. 解决问题的方案 - 修改 chooseAddress 方法中的代码,进一步完善用户没有授权时的 if 判断条件即可:

    async chooseAddress() {// 1. 调用小程序提供的 chooseAddress() 方法,即可使用选择收货地址的功能//    返回值是一个数组:第1项为错误对象;第2项为成功之后的收货地址对象const [err, succ] = await uni.chooseAddress().catch(err => err)// 2. 用户成功的选择了收货地址if (succ && succ.errMsg === 'chooseAddress:ok') {this.updateAddress(succ)}// 3. 用户没有授权if (err && (err.errMsg === 'chooseAddress:fail auth deny' || err.errMsg === 'chooseAddress:fail authorize no response')) {this.reAuth()}
    }

​​​​​​​

 

相关内容

热门资讯

2所211高校,迎来新任副校长 近日,哈尔滨工程大学、合肥工业大学2所211高校,分别迎来新任副校长。其中,尹航任哈尔滨工程大学党委...
香港警方通报10亿日元劫案最新... 【#香港警方通报10亿日元劫案最新进展#】#香港10亿日元劫匪部分有黑社会背景#据南方日报消息,12...
商务部国际贸易谈判代表兼副部长... 12月19日,商务部国际贸易谈判代表兼副部长李成钢会见美国苹果公司首席运营官萨比赫·汗。双方就苹果公...
继CPU、GPU后,又来了个M... (来源:上观新闻)今年的国产芯片是真火。近期摩尔线程和沐曦登陆资本市场,首日暴涨印证了市场对国产GP...
李成钢会见苹果公司首席运营官:... 12月19日,商务部国际贸易谈判代表兼副部长李成钢会见美国苹果公司首席运营官萨比赫·汗。双方就苹果公...