思路:
前端:
-
将后端返回的数组 通过循环,将数组的每个对象 都添加一个属性 checked 默认为 true
-
前端渲染的时候,就可以直接把 第一步添加的 checked属性 动态绑定到 对应的选项标签上
-
在vuex中 分别写:全选 全不选 单选 逻辑
3.1 首先准备2个数组,第一个是 后端返回的数据 list ,第二个数组 自己定义一个空数组
state: { list: [], // 购物车数据 selectList: [] // 被选中的数据 id },
3.2 mutations中 初始化的时候,将通过map 将被选中的数据 id 拷贝一份进入到定义的空数组里
mutations: { [CART_DATA](state, data) { state.list = data // 初始化的时候,将id 通过map复制到 新的组数中,解决这个问题:如果用forEach(),会有每次进到购物车页面,都循环push id进去 导致全选按钮没有默认选中的问题,就是getters中的两个数组长度不一样了。所以换成了 map state.selectList = data.map(v => { return v.id }) console.log(state.list, state.selectList); }, }
3.3 开始做全选功能:也是循环遍历后端返回的数组,将遍历的项的 v.checked = true; 最后赋值给 自定定义的数组,
// 全选 [CHECK_ALL](state) { state.selectList = state.list.map(v => { v.checked = true; return v.id }) },
3.4 全不选功能:也是循环遍历后端返回的数组,将遍历的项的 v.checked = false; 将自定义的数组 赋值为 空数组 state.selectList = []
// 全不选 [UNCHECK_ALL](state) { state.list.map(v => { v.checked = false; return v.id }) state.selectList = [] },
3.5 单选 根据 后端返回数组的下标id ,去 第二个数组中查找对应的内容,如果找到就删除,找不到 就添加 这个方法的index 是通过绑定在vue组件单选按钮上传递过来的 index值,其实有点绕 有点难,对新手来说
[CHECK_ITEM](state, index) { // console.log(state.list[index].id, state.selectList); let indexId = state.list[index].id let i = state.selectList.indexOf(indexId) // console.log(i, "77"); if (i > -1) { // 可以找到 把当前这个删掉 return state.selectList.splice(i, 1) } // 如果之前没有选中 ,就将当前的id push进去 state.selectList.push(indexId) console.log(state.list.length, state.selectList.length); },
3.5 判断2个数组的length是否相等 如果相等 就在actions 提交commit mutations中的全选 或 全不选
getters: { // 判断2个数组的length是否相等 isCheckedAll(state) { return state.list.length == state.selectList.length } },
3.6 在actions 提交commit mutations中的全选 或 全不选
actions: { checkAllFn({commit, getters }) { getters.isCheckedAll ? commit("unCheckAll") : commit("checkAll") } }
-
在getters中计算单价和 总数 ,注意判断 当都是选中状态的时候 才计算
// 计算数量 total(state) { let total = { num: 0, price: 0 } state.list.forEach(v => { console.log(v); if (v.checked) { total.num += parseInt(v.num) total.price += v.shop_price * v.num } }) return total }
问题:
vue组件 这里绑定数据用的数 v-module 双向数据流,但是 vuex的数据 是单向数据流,
视图错误
在vue组件中引入vuex的内容:
在vue组件中v-module 使用:
解决办法参考:segmentfault.com/a/119000001…
解决方法一(失败了,后面有机会回头再看吧,先用方法二):将 ...mapGetters(["isCheckedAll"]), 替换成下面的方式, 然后也可以使用v-model来绑定数据
// ...mapGetters(["isCheckedAll"]),
isCheckedAll: {
get() {
return this.$store.getters.isCheckedAll;
},
set(val) {
return (this.$store.getters.isCheckedAll = val);
},
},
解决办法二:将v-model 改成 :value 还是使用: ...mapGetters(["isCheckedAll"])
<van-checkbox @click="checkAllFn" :value="isCheckedAll">
功能如图: