• 技术文章 >web前端 >uni-app

    实例讲解uniapp实现多选框的全选功能

    长期闲置长期闲置2022-06-22 11:57:51转载195
    本篇文章给大家带来了关于uniapp的相关知识,其中主要整理了实现多选框的全选功能的相关问题,无法实现全选的原因是动态修改checkbox的checked字段时,界面上的状态能够实时变化,但是无法触发checkbox-group的change事件,下面一起来看一下,希望对大家有帮助。

    推荐:《uniapp教程

    uniapp内置的checkbox其实以及checkbox-group本来挺好的,但是有两个问题:

    1. 无法依赖其事件实现全选
    2. 样式固定,难以修改

    他们无法实现全选的原因是:
    我动态修改checkboxchecked字段时,界面上的状态能够实时变化,但是无法触发checkbox-groupchange事件。意味着无法依赖checkbox-group管理好已选项。

    就是说:我点了全选,界面上看着是全选了。然后此时我取消了其中一个选项,此时触发change事件,但是它反馈给我的已选列表是错的。这是不行的。

    所以我自己想了个实现全选多选框的方案。

    实现思路

    鉴于上面的问题,于是就可以放弃checkbox-group了,那么,我顺便就放弃了checkbox,因为我更喜欢radio的圆圈样式。

    首先先模拟生成一些数据,方便展示,数据的要点是要有一个字段selected,其余随心所欲:

    <script setup lang="ts">
        import { reactive } from "vue";
        // 模拟的数据对象,要是响应式的
        let data = reactive([] as { id: number; text: string; selected: boolean }[]);
        // 生成数据
        for (let i = 0; i < 10; i++) {
            data.push({
                id: i + 5,
                text: "标题" + i,
                selected: false,
            });
        }</script>

    然后我们需要有一个存储已选择数据信息的对象,采用map:

        // 存储已选内容, 因为这个列表是增删很频繁的,所以选用map而不是数组,key对应的是数据的下标。至于value存放什么,完全由自己定
        let selected = reactive(new Map<number, number>());

    在然后我们得有一个选项框点击事件,用于选择数据或者取消选择:

        // 选项框点击事件,参数是数据的下标
        function checkbox(index: number) {
            // 选中的状态下再次点击,即为取消选中
            if (data[index].selected) {
                data[index].selected = false;
                selected.delete(index); // 然后删除对应key即可
            }
            // 未选中状态下点击
            else {
                data[index].selected = true;
                selected.set(index, data[index].id);
            }
        }

    再再然后,我们还得有一个全选的点击事件:

        // 全选与反选事件
        function allSelect() {
            // 已经全选情况下,就是反选,全选就说明长度一样
            if (selected.size === data.length) {
                selected.clear(); // 全部清除
                data.forEach((element) => {
                    element.selected = false; // 全部不选,就行了
                });
            }
            // 还未全选的状态下
            else {
                data.forEach((element, index) => {
                    // 因为可能存在部分已经选择了,所以得先判断是否已存在,不存在才需要添加
                    if (!selected.has(index)) {
                        selected.set(index, element.id); // key是对应的下标index,而value是可以自定义的
                        element.selected = true; // 设为选中
                    }
                });
            }
        }

    其实上面两个点击事件都是很基本的判断和增删数据。至此功能已经全部都有了,下面看看页面怎么写:

    <template>
        <!-- 是个多选列表 -->
        <view v-for="(item, index) in data">
            <label style="margin-left: 50px">
                <radio :value="String(index)" :checked="item.selected" @click="checkbox(index)" />{{ item.text }}        </label>
        </view>
        <!-- 全选按钮 -->
        <label> <radio value="1" :checked="selected.size === data.length" @click="allSelect" />全选</label></template>

    其实就两组radio,一个是循环展示数据,一个是全选按钮。

    连起来的完整代码:

    <template>
        <!-- 是个多选列表 -->
        <view v-for="(item, index) in data">
            <label style="margin-left: 50px">
                <radio :value="String(index)" :checked="item.selected" @click="checkbox(index)" />{{ item.text }}
            </label>
        </view>
        <!-- 全选按钮 -->
        <label> <radio value="1" :checked="selected.size === data.length" @click="allSelect" />全选</label></template><script setup lang="ts">
        import { reactive } from "vue";
    
        // 模拟的数据对象,要是响应式的
        let data = reactive([] as { id: number; text: string; selected: boolean }[]);
        // 生成数据
        for (let i = 0; i < 10; i++) {
            data.push({
                id: i + 5,
                text: "标题" + i,
                selected: false,
            });
        }
    
        // 存储已选内容, 因为这个列表是增删很频繁的,所以选用map而不是数组,key对应的是数据的下标。至于value存放什么,完全由自己定
        let selected = reactive(new Map<number, number>());
    
        // 全选与反选事件
        function allSelect() {
            // 已经全选情况下,就是反选,全选就说明长度一样
            if (selected.size === data.length) {
                selected.clear(); // 全部清除
                data.forEach((element) => {
                    element.selected = false; // 全部不选,就行了
                });
            }
            // 还未全选的状态下
            else {
                data.forEach((element, index) => {
                    // 因为可能存在部分已经选择了,所以得先判断是否已存在,不存在才需要添加
                    if (!selected.has(index)) {
                        selected.set(index, element.id); // key是对应的下标index,而value是可以自定义的
                        element.selected = true; // 设为选中
                    }
                });
            }
        }
    
        // 选项框点击事件,参数是数据的下标
        function checkbox(index: number) {
            // 选中的状态下再次点击,即为取消选中
            if (data[index].selected) {
                data[index].selected = false;
                selected.delete(index); // 然后删除对应key即可
            }
            // 未选中状态下点击
            else {
                data[index].selected = true;
                selected.set(index, data[index].id);
            }
        }</script><style></style>

    看起来代码不少,其实都是很基础的逻辑判断。

    最后效果是这样的:
    全选:
    在这里插入图片描述

    多选:
    在这里插入图片描述

    反选全部:
    在这里插入图片描述

    推荐:《uniapp教程

    以上就是实例讲解uniapp实现多选框的全选功能的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:CSDN,如有侵犯,请联系admin@php.cn删除
    专题推荐:uni-app
    上一篇:uni-app入门:项目创建及原生tabbar配置 下一篇:聊聊使用Uniapp怎么实现全局消息提示及其组件
    20期PHP线上班

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• uniapp中怎么使用scrpll-view组件实现下拉刷新• uniapp中怎么实现直播旁路推流(步骤分享)• 你必须了解的UniAPP入门知识整理• 带你搞懂uniapp跨域问题(实例详解)• 聊聊iOS端下uniAPP原生插件是怎样打包的?(打包流程分享)
    1/1

    PHP中文网