<template> <view class="check-list-pages"> <view> <view class="selList" v-for="(item, index) in list" :key="index"> <view class="radios" @click="chooseItem(item)"> <view v-if="checkIconPositon=='right'" style="flex-grow: 1;" class="title">{{ item[titleKeys] }}</view> <view> <radio v-if="types == 'radio'" :checked="item.checked" :value="item.id" /> <u-checkbox size="45" v-if="types == 'checkbox'" :disabled="item.disabled" v-model="item.checked" :name="item.id" /> </view> <view v-if="checkIconPositon=='left'" class="title">{{ item[titleKeys] }}</view> </view> <view class="details" :style="showArrow && types != 'views'?'padding-right:20upx':''" @click="rightClick(item)"> <slot name="right"></slot> <u-icon v-if="showArrow && types != 'views'" name="icon-xian-11" custom-prefix="xd-icon" size="28" color="#888888"></u-icon> </view> </view> <view style="padding-top: 10vh;" v-if="list.length==0 && status!='loading'"> <u-empty :text="noDataText" mode="list"></u-empty> </view> </view> <!-- 选择按钮 --> <view v-if="types == 'checkbox'" @click="kpOk" class="kp-ok">确认选择</view> </view> </template> <script> export default { name: 'UniCheckList', props: { listData: { type: Array, default: function() { return []; } }, // 类型 radio 或 checkbox 或 views 指 只是展示列表 types: { type: String, default: 'radio' }, // 标题显示的字段 titleKeys: { type: String, default: 'name' }, // 暂无数据提示内容 noDataText: { type: String, default: '暂无数据' }, // 是否在加载中 status: { type: String, default: 'onmore' }, // 是否显示右边箭头 showArrow: { type: Boolean, default: true }, // 赋值,格式要和backValue 一致 defValue: { type: Array, default: function() { return []; } }, // 返回结果是 // idArr: [id,id,id...],objArr:[obj,obj,obj...] backValue:{ type: String, default: 'idArr' }, // 选择按钮位置,left ,right checkIconPositon:{ type: String, default: 'left' } }, data() { return { list: JSON.parse(JSON.stringify(this.listData)), value: this.defValue }; }, watch: { listData(newValue, oldValue) { this.list = JSON.parse(JSON.stringify(newValue)); this.hasCheck(); }, defValue(newValue, oldValue){ this.value = newValue; } }, mounted() { this.hasCheck(); }, methods: { hasCheck() { this.list.map((item,index) => { let a = this.value.findIndex(k=>{ return this.backValue == 'idArr' ? k == item.id : k.id == item.id }) item.checked = a>=0 this.list.splice(index,1,item) }) }, // 选中 chooseItem(item) { if (item.disabled) { return } // 单选 if (this.types == 'radio') { this.value[0] = this.backValue == 'idArr' ? item.id : item; this.$emit('ok', this.value); } else { // 已选项点击文本,取消选中 item.checked = this.value.find(a=>a.id==item.id) ? false : true // 选中 if (item.checked) { this.value.push(this.backValue == 'idArr' ? item.id : item); } else { let index = this.backValue == 'idArr' ? this.value.indexOf(item.id) : this.value.findIndex(a=> a.id == item.id); this.value.splice(index, 1); } } this.hasCheck(); }, rightClick(item) { this.$emit('rightClick', item); }, kpOk() { this.$emit('ok', this.value); } } }; </script> <style lang="less"> .check-list-pages { height: 100%; display: flex; flex-direction: column; > view { &:first-child { flex-grow: 1; overflow: auto; } } } .selList { width: 100%; border-bottom: 1px solid #eee; display: flex; align-items: center; .radios { display: flex; align-items: center; flex-grow: 1; width: 50%; padding: 26upx 20upx; &:active { background-color: #f8f8f8; } .title { word-break: break-all; } >view{ &:last-child{ padding-left: 50upx; } } } .details { color: #007aff; display: flex; align-items: center; &:active { color: #d9363e; } } } .kp-ok { text-align: center; padding: 26upx; background: #55aaff; color: #fff; font-size: 18px; } </style>