怎么动态跟新购物车的数量以及tabbar的动态显示微标
思路:1.首先怎么动态跟踪购物车数量的变化,一般情况下我们都是计算属性加上侦听器的,
2.工作中咱们,为了不刷新就可以实时处理,可以把数据放到本地存储中,这些公共的数据以及方法可以放到共享数据库vuex中,在vuex里面保存到本地中。
3.vuex是什么? 复习下
store是Vuex.Store这个构造函数new出来的实例。在构造函数中可以传一个对象参数。这个参数中可以包含5个对象:
1.state – 存放状态
2.getters – state的计算属性
3.mutations – 更改状态的逻辑,同步操作
4.actions – 提交mutation,异步操作
5.mudules – 将store模块化
4.继续讲解,首先我们要在store对象的state存放状态 也就是data 共享数据,这里指的是商品的信息对象
// 模块的 state 数据
state: () => ({
// 购物车的数组,用来存储购物车中每个商品的信息对象
// 每个商品的信息对象,都包含如下 6 个属性:
// { goods_id, goods_name, goods_price, goods_count, goods_small_logo, goods_state }
cart: JSON.parse(uni.getStorageSync('cart') || '[]'),
}),
5.此时我们有了数据 可以通过mutations 同步操作更改里面的数据在里面封装添加商品的函数以及修改商品的函数以及删除的函数,通过封装函数,形参就是之后我们在页面要调用的函数传的格式 通过 mapMutations 辅助函数映射到页面调用改方法传递页面的实参,也就是变化之后的数据,达到页面视图数据。
实例代码:
mutations: {
// 添加商品
addToCart(state, goods) {
// 根据提交的商品的Id,查询购物车中是否存在这件商品
// 如果不存在,则 findResult 为 undefined;否则,为查找到的商品信息对象
const findResult = state.cart.find(item => item.goods_id === goods.goods_id)
if (!findResult) {
// 如果购物车没有这件商品 就push给cart
state.cart.push(goods)
} else {
// 如果购物车中有这件商品,则只更新数量即可
findResult.goods_count++
}
// 通过 commit方法 调用 saveToStorage()这个方法
this.commit('m_cart/saveToStorage')
},
// 把商品数量保存本地中
saveToStorage(state) {
uni.setStorageSync('cart', JSON.stringify(state.cart))
},
// 更新本地中cart的单选框的状态
updateGoodsState(state, goods) {
// 查询商品的信息对象
const findResult = state.cart.find(x => x.goods_id === goods.goods_id)
// 有对应的商品信息对象
if(findResult) {
// 改变其中的状态
findResult.goods_state = goods.goods_state
// 持久化处理 储存本地中
this.commit('m_cart/saveToStorage')
}
},
// 更新本地的cart 的 商品数量
updateGoodsCount(state, goods) {
// 查询商品的信息对象
const findResult = state.cart.find(x => x.goods_id === goods.goods_id)
// 有对应的商品信息对象
if(findResult) {
// 改变其中的状态
findResult.goods_count = goods.goods_count
// 持久化处理 储存本地中
this.commit('m_cart/saveToStorage')
}
},
// 通过商品id 删除对应的商品
removeByID(state, goods_id) {
// 通过filter查询商品的信息对象 排除指定删除的商品
state.cart = state.cart.filter(x => x.goods_id !== goods_id)
// 本地存储持久化处理
this.commit('m_cart/saveToStorage')
}
},
页面只需要调用就可以:
//导入 mapState mapMutations 辅助函数
import {mapState, mapMutations } from 'vuex'
computed: {
// 在 m_cart把cart数组 映射当前页面的 计算属性中
...mapState('m_cart', ['cart'])
},
--------------------------------------------------------------------------
methods: {
// 将 m_cart 中的 updateGoodsState() 方法 映射到当前页面中使用
...mapMutations('m_cart', ['updateGoodsState', 'updateGoodsCount', 'removeByID']),
// 通过子组件传过来的参数 来改变选中状态
radioChangeHandler(e) {
this.updateGoodsState(e)
},
// 通过子组件传过来的参数 来改变商品的数量值
numChangeHandler(e) {
this.updateGoodsCount(e)
},
// 点击通过vuex 封装的 方法来删除商品列表
swipeActionClickHandler(goods) {
this.removeByID(goods.goods_id)
}
}
- 基本完成了购物车数量变化的功能,现在还有一个问题就是tabbar的微标不会随state里的状态改变 需要重新刷新页面才可以显示,因此咱们必须要在他页面加载之前渲染出来就可以。我此时用的uni.app。上面又一个方法可以显示微标,此时就可以使用 getters 这个计算属性里的封装的商品总数量的方法,监听商品总数量 这样就可以动态跟新微标的变化,还有一点想要切换tabbar的时候 其他底部导航 也可以显示商品的加购数量 可以利用vue.js混入api
// 模块的 getters 属性
getters: {
// 统计购物车商品的总数量
total(state) {
// 声明一个变量用来接收 自增的数量
let c = 0
// 循环遍历商品信息对象 把每次自增的数量累加
state.cart.forEach(goods =>c += goods.goods_count)
return c
}
}
-----------------------------------------------
// 按需导入mapGetters 这个辅助方法
import { mapGetters } from 'vuex'
export default {
computed: {
// 将m_cart 中的total属性 映射到当前页面 作为计算属性使用
...mapGetters('m_cart', ['total'])
},
watch: {
total: {
handler(newVal) {
this.setBadge()
},
// 通过vue api 的一个方法 immediate 来实现进入页面就加载
immediate: true
}
},
methods: {
setBadge() {
// 调用 uni.setTabBarBadge() 方法,为购物车设置右上角的徽标
uni.setTabBarBadge({
index: 2, // 索引
text: this.total + '' // 注意:text 的值必须是字符串,不能是数字
})
}
}
}
7.补充 watch 里面可以是一个 对象 也可以是一个函数,,,computed只能是一个函数 里面可以返回这个计算的值
我刚写的表达式 是普通监听?
total : this.setBadge()
对象? handler 函数? this.setBadge()包函数?
计算属性也是的是啊吧? 或者函数 返回一个结果?