在分享我手写多选框之前,我们先看一下uniapp官方组件是怎么实现的。
<view class="uni-list">
<checkbox-group @change="checkboxChange">
<label class="uni-list-cell uni-list-cell-pd" v-for="item in items" :key="item.value">
<view>
<checkbox :value="item.value" :checked="item.checked" />
</view>
<view>{{item.name}}</view>
</label>
</checkbox-group>
</view>
items: [{
value: 'USA',
name: '美国'
},
{
value: 'CHN',
name: '中国',
checked: 'true'
},
{
value: 'BRA',
name: '巴西'
},
{
value: 'JPN',
name: '日本'
},
{
value: 'ENG',
name: '英国'
},
{
value: 'FRA',
name: '法国'
}
]
checkboxChange: function (e) {
var items = this.items,
values = e.detail.value;
for (var i = 0, lenI = items.length; i < lenI; ++i) {
const item = items[i]
if(values.includes(item.value)){
this.$set(item,'checked',true)
}else{
this.$set(item,'checked',false)
}
}
}
这js代码用for循环加icludes来动态设置‘checked’属性,不但冗余而且给原数据添加了新属性,如果后端正好要这个数组对象的数据,还要用delect来删除新加的‘checked’,代码看起来逻辑不是很清晰。
那么怎么来改进呢?
- 除了要遍历的数组(items)外再新建一个数组(selectItems)来接收勾选后的数据。
- 用户点击复选框时先通过indexOf判断复选框是否为选中状态,如果为没勾选状态帮当前item的id用push方法追加到selectItems中,如果为勾选状态帮当前item的id用splice方法从selectItems中删除。
- 复选框的样式通过动态添加css属性和字体图标实现。
<view class="issue-row box-item check-info" v-for="item in items" :key="item.value">
<view class="check-box">
<view class="round" @click="checkboxChange(item)" :data-value="item.value" :class="{circleAtive:selectItems.includes(item.id)}">
<view v-if=" choosedId.includes(item.id)}" class="iconfont iconduidezhifuchenggong"></view>
</view>
</view>
<view class="box-name" @click="checkboxChange(item)" :data-value="item.value">{{item.name}}</view>
</view>
items: [{
value: 'USA',
name: '美国'
},
{
value: 'CHN',
name: '中国',
checked: 'true'
},
{
value: 'BRA',
name: '巴西'
},
{
value: 'JPN',
name: '日本'
},
{
value: 'ENG',
name: '英国'
},
{
value: 'FRA',
name: '法国'
}
],
selectItems: []
css(.circleAtive {
background: rgba(109, 212, 0, 1);
})
checkboxChange(item) {
let index = this.selectItems.indexOf(item.id)
if (index == -1) {
this.selectItems.push(item.id)
} else {
this.selectItems.splice(index, 1)
}
},
选中的元素都在selectItems中,后端需要,直接帮数组传过去就行了。