el-checkbox中的checked勾选状态问题 2021-08-02

碰到的问题

今天用elment-ui时碰到了一个坑,记录一下:
项目中有一个页面是带批量下载功能的,需要点击批量操作才会出现全选按钮和item中的多选框,但是直接用v-if没有过渡效果感觉很生硬。于是自己写了一个css过渡效果,把全选按钮隐藏在批量操作按钮下方,点击批量操作后,从按钮的右侧移出

<!-- 点击切换操作和取消操作,取消操作后清空已选列表 -->
<el-button @click="isBatch=!isBatch;!isBatch&&checkedList.splice(0)">
		{{isBatch?'取消操作':'批量操作'}}
</el-button>

<!-- 通过添加class类名实现come-out过渡,通过change事件实现全选按钮的勾选和取消勾选逻辑 -->
<el-checkbox label="全选" border @change="checkAll" :class="isBatch?'come-out':''"
	:checked="!!checkedList.length && checkedList.length === dataList.length"
	:indeterminate="!!checkedList.length && checkedList.length < dataList.length"></el-checkbox>
<!-- 通过checkedList和dataList的长度来控制indeterminate和checked状态 -->

<!-- 通过checkedList的长度来控制下载本页还是下载选中 -->
<el-button type="primary" @click="downloadFn">
	{{!checkedList.length?'下载本页':`下载选中 (${checkedList.length})`}}
</el-button>

<el-checkbox-group v-model="checkedList">
	<div v-for="item in dataList">
		<el-checkbox v-if="isBatch" :label="item.id"></el-checkbox>
		<!-- other content -->
	</div>
</el-checkbox-group>
export default{
    data:() => ({
    	isBatch: false,
    	checkedList: [],
        dataList:[
        	{ id:1, name:'Keith' },
        	{ id:2, name:'Annie' }
        ]
    }),
    methods:{
        checkAll(isCheckAll){
            this.checkedList = isCheckAll? this.dataList.map(item => item.id) : []
        },
        downloadFn(){
        	if(this.checkedList.length){
        		// download checkList
        	} else {
        		// download all
        	}
        }
    }
}
.el-button{
	position: relative;
	z-index: 10;
}
.el-checkbox.is-bordered {
	background-color: #fff;
    padding-left: 20px;
    opacity: 0.5;
    margin-left: -99px;
    transition: all 0.5s;
    &.come-out {
    	opacity: 1;
    	margin-left: 10px;
    }
}

但是出现了一个很奇怪的问题,当我全部选中时点击取消操作,清空了已选列表,但是再点击批量操作的时候,全选按钮还是勾选状态,于是就出现了奇怪的一幕
奇怪的一幕
子选项一个都没选,而且checkedList也是空的,但全选按钮是选中状态

解决办法1:

既然是checked状态的问题,那么改用v-model绑定一个变量不就可以解决了,通过watch监控checkedList的值变化来改变变量的值

<!-- 去掉:checked 加上v-model -->
<el-checkbox label="全选" border @change="checkAll" :class="isBatch?'come-out':''" v-model="isAllChecked"
	:indeterminate="!!checkedList.length && checkedList.length < dataList.length"></el-checkbox>
export default{
    data:() => ({
    	// ...
    	isAllChecked: false		// 加上控制组件的变量
    }),
    watch:{
    	// 监控checkedList的变化来控制全选按钮的v-model
    	checkedList(arr){
    		this.isAllChecked = !!arr.length && arr.length === this.dataList.length
    	}
    },
    // ...
}

解决办法2:

前面说过用v-if的时候并不存在这个问题,因为v-if对组件进行了销毁,再次出现会正确显示勾选状态,那么我们需要解决的问题就是过渡css效果,那就可以用vue的transition来制作过渡样式
进入/离开 & 列表过渡

el-checkbox放入transition标签内并指定name

<transition name="come">
	<el-checkbox v-if="isBatch" label="全选" border @change="checkAll"
		:checked="!!checkedList.length && checkedList.length === dataList.length"
        :indeterminate="!!checkedList.length && checkedList.length < dataList.length">
	</el-checkbox>
</transition>

css中改为

.el-checkbox.is-bordered {
    background-color: #fff;
    padding-left: 20px;
    margin-left: 10px;
    &.come-enter-active,
    &.come-leave-active {
        transition: all 0.5s;
    }
    &.come-enter,
    &.come-leave-to {
        margin-left: -99px;
        opacity: 0;
    }
}

这样也能实现保留过渡效果,也能保证全选按钮的checked状态是正常的。
墙裂建议用第二种解决方法,vue的transition用起来简直爽爆了

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值