这两天做项目,pc端本来是一个简单的select多选功能,做到客户端的时候,产品要求做成按字母排序功能,类似手机通讯录功能,由于我们客户端用的滴滴的cube-ui 组件,我选择了cube-ui IndexList,在它的基础上进行扩展。大致效果如果下图
其实难点在于如何处理数据,研发返回的数据,返回的格式如:{ "error": 0, "payload": { "count": "16", "list": [{ "userid": 100008, "truename": "Ayoung", "mobile": "13592579211", "firstchar": "A" }, { "userid": 100007, "truename": "安", "mobile": "", "firstchar": "A" }, { "userid": 100006, "truename": "bbs", "mobile": "", "firstchar": "B" }, { "userid": 100011, "truename": "兵馬", "mobile": "", "firstchar": "B" }, { "userid": 100012, "truename": "陈", "mobile": "", "firstchar": "C" }, { "userid": 100000, "truename": "创始人", "mobile": "13503457031", "firstchar": "C" }, { "userid": 100015, "truename": "huang", "mobile": "", "firstchar": "H" }, { "userid": 100009, "truename": "韩", "mobile": "", "firstchar": "H" }, { "userid": 100010, "truename": "黄", "mobile": "", "firstchar": "H" }, { "userid": 100005, "truename": "Jea", "mobile": "", "firstchar": "J" }, { "userid": 100025, "truename": "lzc", "mobile": "15638550436", "firstchar": "L" }, { "userid": 100013, "truename": "栗", "mobile": "", "firstchar": "L" }, { "userid": 100003, "truename": "彭", "mobile": "", "firstchar": "P" }, { "userid": 100002, "truename": "晴天~", "mobile": "", "firstchar": "Q" }, { "userid": 100004, "truename": "强", "mobile": "", "firstchar": "W" }, { "userid": 100001, "truename": "dddd", "mobile": "", "firstchar": "W" }] }, "message": "", "baseinfo": { "userid": 100001, "username": "huang", "truename": "lanfeng", "mobile": "15003844853", "isvalid_mobile": 1, "email": "", "isvalid_email": 0, "bind_gcw": 0, "bind_qiwei": 1, "bind_dingding": 0, "logintime": 1562912343, "cer_status": 1, "is_notice_bind": 0, "base_role": 0 } }
转换数据代码如下
//先转换成对象,根据firstchar字段对应的字母,先循环字母数组,设置字母为k,对应数组为键值
lists () {
const { adminListDatas } = this
let obj = {}
const arr2 = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ]
for (let i = 0; i < arr2.length; i++) {
obj[arr2[i]] = []
adminListDatas.forEach((item, index) => {
item.value = item.userid
item.name = item.truename
this.$set(item, 'checked', false)
if (arr2[i] === item.firstchar) {
obj[arr2[i]].push(item)
}
})
}
return obj
},
//把数据转换成cube-ui IndexList 需要的数据
lastList () {
let arr = []
for (let[key, value] of Object.entries(this.lists)) {
if (value.length) {
arr.push({
name: key,
items: value
})
}
}
return arr
}
然后利用组件的slot自定义,把checkbox组件加到相应的里面,不能用cube-ui IndexList的select事件,因为它会触发两次事件,建议用checkbox的input绑定值变化的事件,再对数据进行相应的改变,代码如下
{{ item.name }}
利用checkbox的input事件,把选中的数据userid放到checkList里面,取消的从checklist数组中移除,然后触发getaminlist 传给父组件,把选中的值传给父组件
getval (item, $event) {
const index = this.checkList.indexOf(item.userid)
if ($event && (index === -1)) {
this.checkList.push(item.userid)
} else if (!$event && (index > -1)) {
this.checkList.splice(index, 1)
}
this.$emit('getadminList', this.checkList)
}
看起来似乎简单,但在处理checkbox上浪费了不少时间,刚开始一直想着从indexlist的select事件方法中处理数据,发现怎么试都容易引起两次触发,后来改成checkbox的input事件问题就解决了,处理数据刚开始不知道怎么下手,因为刚开始研发让前端来实现汉子转换拼音,筛选出首字母,后来研发把每条数据加了一个拼音的首字母,问题自然而然的解决了,