问题背景

我们在用 uni-app 开发前端项目时,经常会通过 radio 组件,并结合单项选择器组件 radio-group来实现单选效果。官方文档说明的也比较清楚,原本用起来也没啥问题。

然而,今天在开发收银台界面的时候,碰到一个用户有多个会员卡账户。我们的需求是用户可以通过选择其中任意一个会员卡账户并联合微信支付进行混合支付。另外允许用户不使用会员卡账户,单独使用微信支付。此时我们就需要对选中的单选框 radio 进行取消选中。而官方没有提供直接的取消方法,需要我们自己来实现。

解决方法

我们先来看下相关文档:

radio-group:

属性名类型默认值说明
@changeEventHandle<radio-group> 中的选中项发生变化时触发 change 事件,event.detail = {value: 选中项radio的value}

我们可以看到 @change 事件只有在选中项发生变化时才触发,无法进行取消选中操作。那么我们是否可以使用每个选项的点击事件来模拟类似的效果呢?答案是肯定,实现方式如下( 结合 colorui ):

HTML 代码:

<radio-group>
    <label v-for="(accountItem, accountIndex) in accountList" :key="accountIndex" @tap="changeAccountPayType(accountItem.accountId)">
        <!-- <image src="/static/images/pay/4.png"/>
        <view>
            <text>{{ accountItem.type }}会员支付</text>
            <text>会员余额: ¥{{ accountItem.amount }}</text>
        </view> -->
        <radio :class="selectedAccountId == accountItem.accountId ? 'checked' : ''" :checked="selectedAccountId == accountItem.accountId" :value="accountItem.accountId"/>
    </label>
</radio-group>

JS 代码:

export default {
    data() {
        return {
            accountList: [{ // 会员卡账户列表
                accountId: 'id1',
                amount: 100.01,
                type: '商户'
            }, {
                accountId: 'id2',
                amount: 0.02,
                type: '门店'
            }],
            selectedAccountId: null // 选中的会员卡ID
        }
    },
    methods: {
        changeAccountPayType (accountId) { // 点击其中的一张会员卡
            if (this.selectedAccountId == accountId) { // 如果已经选中,则取消选中
                this.selectedAccountId = null
            } else { // 否则进行选中赋值
                this.selectedAccountId = accountId
            }
        }
    }
}

我们也可以通过官方的另一组组件 checkbox-groupcheckbox 来实现类似效果,大家可以自己动手来实现。