我的编程空间,编程开发者的网络收藏夹
学习永远不晚

uniapp下单选框的实现方法详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

uniapp下单选框的实现方法详解

uniapp官方虽然提供了uni-data-checkbox,含括了单选和多选框功能。但是它功能实在不能满足需求:

  • 单选框不支持再次点击取消
  • 无法与父组件的数据源进行联动,无法实现如多规格选择的那种联动
  • 源码每次点击都是对数据源进行拷贝,然后再进行json解析等操作,看着就很不靠谱,数据量大必然有性能问题。

其实我放弃uni-data-checkbox,选择自己实现也是因为商品规格展示是比较复杂的,不自己实现的话无法达到目的:

看图中,三组规格选项是要相互联动的,选择了其中一个后,就得判断其余的是否可选。然后我认为也可以将已选中的取消。所以得自己实现,好根据业务定制。

代码如下:

<template>
    <!-- uniapp内置的单选组件,见https://uniapp.dcloud.io/component/radio.html -->
    <radio-group class="checklist-group" @change="change">
        <label
            class="checklist-box is--tag"
            v-for="item in radioData.option"
            :class="[radioData.selected === item.id ? 'is-checked' : '', item.disable ? 'is-disable' : '']">
            <radio
                class="hidden"
                :disabled="item.disable"
                :value="String(item.id)"
                :checked="radioData.selected === item.id" />
            <view class="checklist-content">
                <text class="checklist-text">{{ item.text }}</text>
            </view>
        </label>
    </radio-group>
</template>
<script setup lang="ts">
    const props = defineProps({
        // 该id设计的目的是为了应对数组,记录数组的下标,这样父类就不需要遍历查找了。当然也可以根据业务用于其他方面,不需要就不用即可。
        id: {
            type: [Number, String],
        },
        
        radioData: {
            type: Object,
            required: true,
        },
    });
    // 点击后回调父类的change方法
    const emit = defineEmits(["change"]);

    // 点击后触发
    function change(e: any) {
        // 参数:tag的id;props.id
        emit("change", e.detail.value, props.id);
    }
</script>
<style lang="scss">
    $checked-color: #2979ff;
    $border-color: #dcdfe6;
    $disable: 0.4;
    @mixin flex {
        
        display: flex;
        
    }
    .checklist-group {
        @include flex;
        flex-direction: row;
        flex-wrap: wrap;

        .checklist-box {
            @include flex;
            flex-direction: row;
            align-items: center;
            position: relative;
            margin: 5px 0;
            margin-right: 25px;

            .hidden {
                position: absolute;
                opacity: 0;
            }

            // 文字样式
            .checklist-content {
                @include flex;
                flex: 1;
                flex-direction: row;
                align-items: center;
                justify-content: space-between;
                .checklist-text {
                    font-size: 14px;
                    color: #666;
                    margin-left: 5px;
                    line-height: 14px;
                }
            }

            // 单选样式
            .radio__inner {
                @include flex;
                
                flex-shrink: 0;
                box-sizing: border-box;
                
                justify-content: center;
                align-items: center;
                position: relative;
                width: 16px;
                height: 16px;
                border: 1px solid $border-color;
                border-radius: 16px;
                background-color: #fff;
                z-index: 1;

                .radio__inner-icon {
                    width: 8px;
                    height: 8px;
                    border-radius: 10px;
                    opacity: 0;
                }
            }

            // 标签样式
            &.is--tag {
                margin-right: 10px;
                padding: 5px 10px;
                border: 1px $border-color solid;
                border-radius: 3px;
                background-color: #f5f5f5;

                .checklist-text {
                    margin: 0;
                    color: #666;
                }

                // 禁用
                &.is-disable {
                    
                    cursor: not-allowed;
                    
                    opacity: $disable;
                }

                &.is-checked {
                    background-color: $checked-color;
                    border-color: $checked-color;

                    .checklist-text {
                        color: #fff;
                    }
                }
            }
        }
    }
</style>

其实代码本身内容很少,是样式的代码多,我样式是直接照抄uni-data-checkbox的。

传入的数据结构应该是:

interface radio{
    selected: number;
    option: {
        id: number;
        text: string;
        disable: boolean;
    }[];
}

selectedid可以是别的类型,但selected是取值于id

这里得注意,数据源必须是响应式的,考虑这里肯定是个对象,那么就是要用reactive去包围数据,使其具有响应性,否则页面不会更新,例如下面:

const radioData= reactive(radio);

PS1:由于vue3规范建议:子组件不修改父组件的数据源,否则会导致数据的变化难以理解。所以change方法中没有做任何修改数据的动作。比如将selected直接修改也是完全可以的,但是我这里还是交由父组件去决定如何修改。

PS2:咋一看change方法仅传递了当前选择的选项,并没有告知之前的选项是什么,如果要对比前后的时候不是没有办法?其实selected就是存储的之前的选项,在修改它之前用它作比较即可。

PS3:由于radio本身是不支持选中之后再取消的,我们这里采用将selected赋值为一个不存在的id,这样就会取消选择了。但是会报错:

uni-shared.es.js:470 Uncaught TypeError: Cannot destructure property 'id' of 'el' as it is null.
    at normalizeTarget (uni-shared.es.js:470:13)
    at createNativeEvent (uni-h5.es.js:1260:13)
    at $nne (uni-h5.es.js:1234:15)
    at HTMLElement.invoker (vue.runtime.esm.js:9397:19)

但是不影响功能哈。

PS4:目前仅在H5下测试功能时正常的。

总结

到此这篇关于uniapp下单选框实现的文章就介绍到这了,更多相关uniapp下单选框实现内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

uniapp下单选框的实现方法详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

uniapp下单选框的实现方法详解

在写表单的时候,总会遇到使用单选框或者复选框的时候,下面这篇文章主要给大家介绍了关于uniapp下单选框实现的相关资料,需要的朋友可以参考下
2022-11-13

详解uniapp的缓冲实现方案

【序】在移动App开发中,常常需要对数据进行缓存处理,以提升用户体验和节省网络流量消耗,而在uniapp开发中也可以通过一些方案来实现数据的缓存处理。本文将介绍uniapp的缓冲实现方案,从而帮助开发者优化应用的运行性能。【正文】一、uniapp应用的缓冲分类uniapp应用中数据缓存可以分为两类:内存缓存和磁盘缓存。内存缓存指的是数据存储在应用的内存中,而磁盘缓存则是数据存储
2023-05-14

Android开发中实现单选或多选对话框的方法

Android开发中实现单选或多选对话框的方法?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。具体代码如下所示:public void myClick(View view)
2023-05-31

C++ OpenCV实现boxfilter方框滤波的方法详解

box filter的作用很简单,即对局部区域求平均,并把值赋给某个点,一般我们赋给区域中心。本文将用C++实现boxfilter方框滤波,需要的可以了解一下
2022-11-13

使用python实现下拉选择框和页签的方法

ttk是Python中的一个模块,它提供了一组用于创建GUI界面的工具和控件,这些控件包括按钮、标签、文本框等,可以帮助开发者更方便地创建用户界面,这篇文章主要介绍了使用python实现下拉选择框和页签的方法,需要的朋友可以参考下
2023-03-11

PHP实现表单处理方法详解

本文章向大家介绍PHP表单处理,主要包括PHP表单处理使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下
2022-12-03

Golang sync.Once实现单例模式的方法详解

Go 语言的 sync 包提供了一系列同步原语,其中 sync.Once 就是其中之一。本文将深入探讨 sync.Once 的实现原理和使用方法,帮助大家更好地理解和应用 sync.Once,需要的可以参考一下
2023-05-18

Android端实现单点登录的方法详解

前言 单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。单点登录在大型网站里使用得非常频繁,例如像阿里巴巴这样的网站
2022-06-06

JS实现单个或多个文件批量下载的方法详解

在前端Web开发中,下载文件是一个很常见的需求。这篇文章就来和大家介绍下几种download解决方案,以及特殊Case的最佳方案选择,希望对大家有所帮助
2023-02-28

Flutter实现自定义筛选框的方法

本篇内容主要讲解“Flutter实现自定义筛选框的方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Flutter实现自定义筛选框的方法”吧!目录一、首先自定义筛选框的按钮视图,布局很简单,一个
2023-06-20

Android编程之菜单的实现方法实例详解

本文实例讲述了Android编程之菜单的实现方法。分享给大家供大家参考,具体如下: Options Menu 当用户按下menu button按钮时显示的菜单 Context Menu 当用户长久按住屏幕,被注册显示上下文菜单的视图时显示的
2022-06-06

Android简单实现屏幕下方Tab菜单的方法

本文实例讲述了Android简单实现屏幕下方Tab菜单的方法。分享给大家供大家参考,具体如下: 看到很多热门的Android程序(如:新浪微博、腾讯微博、京东商城、淘宝、当当等等)使用选项卡风格作为程序界面的主框架结构,而Android的选
2022-06-06

DW中建单选按钮不能实现二选一的解决方法

这篇文章主要介绍DW中建单选按钮不能实现二选一的解决方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!DW中设置了单选按钮 ,但是浏览的时候却可以选全部的单选按钮 ,怎样能够设置到只能选一个?不妨试试这个办法1、插入
2023-06-08

编程热搜

目录