uni-app的checkbox组件有些情况下视图层不更新解决方案(实现全选代码)
应用场景-使用uni-app的checkbox组件进行全选/反选功能时,视图不更新情况
问题1:
在使用uniapp的复选框组件checkbox实现列表的全选跟不全选功能时发现,列表的checkbox视图层在某些情况下不生效
解决方法
解决方案1:利用 this.$set 改变数据,即 this.$set(item, 'checked', false),这个时候视图层跟数据都一起更新了,但是在上面那种情况下,数据层改变了,但是视图层没有更新,所以这个时候采用方案2
解决方案2:
原因:解决uniapp开发小程序中复选框组件checkbox监听change事件设置checked属性不生效的问题。原因是复选框组件没有@change事件,而是checkbox-group组件拥有该事件。
解决方案:是在@change事件中,先将checked设置为true,再设置成false即可生效。
问题2:全选的时候,全选这个视图不生效更新
解决方法:用一个div定位在全选按钮上面,进行模拟点击全选视图更新
总结:uni-app使用checkbox组件实现列表全选/反选的具体代码如下
视图层列表
<!-- 列表代码结构--> <view class="data-list"> <checkbox-group @change="handleSelect"> <view v-for="(item, index) in dataList" :key="index" class="item"> <view class="side"> <!-- 最左边的复选框 --> <label class="checkbox"> <checkbox :value="String(item.id)" :checked="item.checked" color="#007aff" iconColor="#007aff" style="transform:scale(0.7)" :disabled="item.disabled" /> </label> </view> <view class="cont-box"> <view class="head">头部内容xxxxxxxxxxxxxxxx</view> <view class="cont">主要内容xxxxxxxxxxx</view> <view class="detail">查看详情</view> </view> </view> </checkbox-group> </view> <!-- 底部全选代码结构 --> <view class="total checkbox-box"> <checkbox-group> <label class="all-checkbox"> <checkbox value="allCheck" :disabled="isDisableAllCheck" color="#007aff" :checked="allCheck" style="transform:scale(0.7)" />已选<text class="num-value">{{selectData.length}}</text>笔,金额<text class="fee">¥2000</text> </label> </checkbox-group> <view class="imitate-check" @click="imitateAllCheck"></view> </view>
script代码
export default {
data() {
return {
dataList: [],
allCheck: false, // 是否全选
isAllCheck: true, // 是否可以全选,true是可以
}
},
computed: {
selectData() {
return this.dataList.filter(item => item.checked);
},
// 是否禁止全选,true就是禁止全选,false是可以全选
isDisableAllCheck() {
return this.dataList.some(item => item.disabled)
}
},
methods: {
handleSelect({
detail
}) {
this.dataList.map(item => {
if (detail.value.includes(String(item.id))) {
this.$set(item, 'checked', true)
} else {
this.$set(item, 'checked', false)
}
})
if(detail.value.length===this.dataList.length){
this.allCheck = true
} else {
this.allCheck = false
}
},
// 模拟全选,解决allCheck不生效
imitateAllCheck() {
if (!this.allCheck) {
const isAllCheck = this.dataList.some(item=>item.disabled)
if (!isAllCheck) {
this.allCheck = true
this.dataList.map(item => {
// item.checked = true
this.$set(item, 'checked', true)
})
} else {
this.allCheck = false
}
} else {
this.allCheck = false
this.dataList.map(item => {
// item.checked = false
this.$set(item, 'checked', false)
})
}
}
}
}
如果上面的代码,点击全选/反选时列表中的checkbox视图有不更新时
imitateAllCheck方法改为如下
imitateAllCheck() { if (!this.allCheck) { const isAllCheck = this.dataList.some(item=>item.disabled) if (!isAllCheck) { this.allCheck = true this.dataList.map(item => { // item.checked = true this.$set(item, 'checked', true) }) } else { this.allCheck = false } } else { this.allCheck = false this.selectData = [] this.ids = [] this.dataList.map(item => { this.$set(item, 'checked', true) }) // 解决checkbox视图不更新问题 setTimeout(()=>{ this.dataList.map(item => { this.$set(item, 'checked', false) }) },50) } }
对于有分页的需求,选中全选的时候,需要新出来的列表数据跟着选中
以上用到的地方分别在D:/fzz-code/new-mobile/page_bill/flows/list.vue、D:/fzz-code/new-mobile/page_invoice/index.vue