案例主要分三个部分:1、选中、非选中和默认禁止选中;2、进步器使用;3、全选计算总价

完整的代码在最后!

       

1、选中、非选中和默认禁止选中

:disabled = "item.money < 0" 表示把价格小于零的选项禁止掉,如果代表商品,可以相当于该商品已经下架,无法选中

// HTML 

<van-checkbox-group v-model="result" ref="checkboxGroup">
            <div class="van-checkbox-cell-group" v-for="(item,index) in tableData" :key="index">
                <van-checkbox :name="item" @click="checkbox()" ref="checkbox" :disabled = "item.money < 0"></van-checkbox>
                <van-cell center :title="item.number" :value="item.money+'元'" is-link></van-cell>
            </div>
        </van-checkbox-group>
 data(){
            return {
                result: [], // 选中数据
                tableData:[
                    {"number":"A123456","money":"36.36"},
                    {"number":"A123456","money":"-30.54"},
                    {"number":"A123456","money":"-1.36"},
                    {"number":"B368946","money":"109.32"},
                    {"number":"C268985","money":"1550.01"},
                    {"number":"D659565","money":"196.65"},
                    {"number":"E565655","money":"209.88"}
                ],
                
            }
        },

如果需要默认勾选某个选项状态,则在wacth里面监听tableData的变化,当然如果tableData一开始就在data创建好,是监听不到他的变化的,最好是网络接口把值传过来

  tableData(val){
                // 监听tableData,把价格小于零的默认勾选,本地无法监听
                this.$nextTick(() =>{
                    for(let i = 0;i<val.length;i++) {
                        if (+val[i].money < 0) {
                            this.$refs.checkbox[i].toggle(true);
                        }
                    }
                })
            },

2、进步器使用

主要实现点击,进步器,价格的累加 / 减少

 <van-cell-group v-for="(item,index) in sumTable" :key="item.id">
            <van-cell :title="fmoney(item.sum*sumValue[index],2)" >
                <van-row>
                    <van-col span="12">
                        <van-stepper v-model="sumValue[index]" theme="round" button-size="22" disable-input @change="onStepper"/>
                    </van-col>
                </van-row>
            </van-cell>
        </van-cell-group>
 data(){
            return {
               // 进步器绑定
               sumValue:[],
               // 数据
               tableData:[
                    {"number":"A123456","money":"36.36"},
                    {"number":"A123456","money":"-30.54"},
                    {"number":"A123456","money":"-1.36"},
                    {"number":"B368946","money":"109.32"},
                    {"number":"C268985","money":"1550.01"},
                    {"number":"D659565","money":"196.65"},
                    {"number":"E565655","money":"209.88"}
                ]   
            }
        },

3、全选计算总价

这里的:price="totals*100",是因为SubmitBar 提交订单栏的价格本身四舍五入了,因此要*100,才能正常显示原本正常的价格

<van-submit-bar :price="totals*100" button-text="提交订单">
            <div class="" @click="checkAll">
                <van-checkbox v-model="checked">全选</van-checkbox>
            </div>
        </van-submit-bar>
data(){
            return {
                result: [], // 选中数据
                resultAll:[], // 保存全选数据,忽略禁止选择的数据
                checked:false, // 全选
                totals:0, // 总计
                tableData:[
                    {"number":"A123456","money":"36.36"},
                    {"number":"A123456","money":"-30.54"},
                    {"number":"A123456","money":"-1.36"},
                    {"number":"B368946","money":"109.32"},
                    {"number":"C268985","money":"1550.01"},
                    {"number":"D659565","money":"196.65"},
                    {"number":"E565655","money":"209.88"}
                ]
            }
        },

 全选的实现需要配合各个选项计算出来的价格 

totalsNum(){
 // 计算总计
    this.totals = 0;
    this.result.forEach(item =>{
        this.totals += parseFloat(item.money)
       })
    },
// 选中的时候计算价格
checkbox(){
     this.totalsNum()
   },

// 选中的时候计算价格
 checkAll(){
   // 点击可切换模式
    this.checked = !this.checked;
    // 全选,并且跳过默认禁止点击的选框
     this.$refs.checkboxGroup.toggleAll({
          checked:this.checked,
           skipDisabled:true
      });
      this.totalsNum()
 },

 由于存在禁止选中的数据,那么禁止的数据是不可以进入到全选当中的,因此,要把禁止选择的选项内容去掉

 watch:{
            // 监听选中单元,判断全选控件
            'result'(val) {
                // 如果有禁止选中的,则忽略它
                let count = 0;
                for(let i = 0; i<this.tableData.length; i++){
                    if (this.$refs.checkbox[i].disabled === true && this.$refs.checkbox[i].checked === false){
                        count ++;
                    }
                }
                if (val.length !== this.tableData.length - count) {
                    this.checked = false
                } else {
                    this.checked = true
                }
            },
        },

有时候可能会用到保留两位小数,为了更加方便多个数据都需要保留两位小数,自定义一个函数,用于需要的数据 ,在用正则表达式的时候,eslint在检查代码的时候,把一些正则表达式当作特殊字符串处理,这时候就会报错,因此,要在package.json中,配置一下eslint规则

 twoPlaces(str, n) {
                if (str == null) {
                    str = '0.00'
                } else if (+str === 0) {
                    str = '0.00'
                } else if (str === '') {
                    str = '0.00'
                } else {
                    n = n > 0 && n <= 20 ? n : 2
                    // eslint检测,这里可能会报错
                    str = parseFloat((str + '').replace(/[^\d\.-]/g, '')).toFixed(n) + ''
                }
                return str
            },

 配置eslint规则

 "rules": {
      "no-invalid-regexp": "off",
      "no-useless-escape": 0
    }

 完整案例代码

<template>
    <div>
        <van-checkbox-group v-model="result" ref="checkboxGroup">
            <div class="van-checkbox-cell-group" v-for="(item,index) in tableData" :key="index">
                <van-checkbox :name="item" @click="checkbox()" ref="checkbox" :disabled = "item.money < 0"></van-checkbox>
                <van-cell center :title="item.number" :value="item.money+'元'" is-link></van-cell>
            </div>
        </van-checkbox-group>

        <van-cell-group v-for="(item,index) in sumTable" :key="item.id">
            <van-cell :title="fmoney(item.sum*sumValue[index],2)" >
                <van-row>
                    <van-col span="12">
                        <van-stepper v-model="sumValue[index]" theme="round" button-size="22" disable-input @change="onStepper"/>
                    </van-col>
                </van-row>
            </van-cell>
        </van-cell-group>

        <van-submit-bar :price="totals*100" button-text="提交订单">
            <div class="" @click="checkAll">
                <van-checkbox v-model="checked">全选</van-checkbox>
            </div>
        </van-submit-bar>
    </div>
</template>

<script>
    export default {
        name: "extract",
        data(){
            return {
                sumValue:[],
                result: [], // 选中数据
                resultAll:[], // 保存全选数据,忽略禁止选择的数据
                checked:false, // 全选
                totals:0, // 总计
                sumTable:[
                    {"sum":"36.25","id":"001"},
                    {"sum":"45.96","id":"002"},
                    {"sum":"81.54","id":"003"}
                ],
                tableData:[
                    {"number":"A123456","money":"36.36"},
                    {"number":"A123456","money":"-30.54"},
                    {"number":"A123456","money":"-1.36"},
                    {"number":"B368946","money":"109.32"},
                    {"number":"C268985","money":"1550.01"},
                    {"number":"D659565","money":"196.65"},
                    {"number":"E565655","money":"209.88"}
                ]
            }
        },
        created() {
            this.sumSteTotals();
        },
        watch:{
            // 监听选中单元,判断全选控件
            'result'(val) {
                // 如果有禁止选中的,则忽略它
                let count = 0;
                for(let i = 0; i<this.tableData.length; i++){
                    if (this.$refs.checkbox[i].disabled === true && this.$refs.checkbox[i].checked === false){
                        count ++;
                    }
                }
                if (val.length !== this.tableData.length - count) {
                    this.checked = false
                } else {
                    this.checked = true
                }
            },
        },
        methods:{
            checkAll(){
                // 点击可切换模式
                this.checked = !this.checked;
                // 全选,并且跳过默认禁止点击的选框
                this.$refs.checkboxGroup.toggleAll({
                    checked:this.checked,
                    skipDisabled:true
                });
                this.totalsNum()
            },
            checkbox(){
                this.totalsNum()
            },
            totalsNum(){
                // 计算总计
                this.totals = 0;
                this.result.forEach(item =>{
                    this.totals += parseFloat(item.money)
                })
            },
            sumSteTotals(){
                // 计算进步器总计
                this.sumTableData = [];
                this.sumTable.forEach(item =>{
                    this.sumTableData.push(parseFloat(item.sum))
                })
            },
            // 进步器变化
            onStepper(value){
            },
            // 保留两位小数
            fmoney(str, n) {
                if (str == null) {
                    str = '0.00'
                } else if (+str === 0) {
                    str = '0.00'
                } else if (str === '') {
                    str = '0.00'
                } else {
                    n = n > 0 && n <= 20 ? n : 2
                    str = parseFloat((str + '').replace(/[^\d\.-]/g, '')).toFixed(n) + ''
                }
                return str
            },
        }
    }
</script>

<style lang="less" scoped>
    @import "../../vant-variables";
    .van-checkbox-group{
        padding-bottom: 48px;
        .van-checkbox-cell-group{
            width: 100%;
            height: 100%;
            display: flex;
            margin-bottom: 8px;
            .van-checkbox{
                width: 60px;
                background: #fff;
            }
        }
        /deep/.van-checkbox__label{
            margin-left: 20px;
            width: 100%;
        }
        /deep/.van-checkbox__icon{
            margin-left: 16px;
        }
        /deep/.van-tag{
            margin-left: 8px;
        }
    }
</style>

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐