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

碰到的问题

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


<el-button @click="isBatch=!isBatch;!isBatch&&checkedList.splice(0)">
		{{isBatch?'取消操作':'批量操作'}}
el-button>


<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>



<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>
		
	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;
    }
}

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

解决办法1:

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


<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用起来简直爽爆了

你可能感兴趣的:(checkbox)