前言
根据单位项目的需要,需要开发一个树状的部门人物选择,无限层级的。查看了半天发现小程序官方是没有相关组件的,只好自己写一个自定义组件了。
在网上找了好久,找到了两个感觉能用的,给了我很多启发。
微信小程序-树形菜单替代方案
微信小程序:树形菜单
但是两个代码都不全,所以自己结合两位前辈整合了一份自己的。
话不多说了,上代码吧。
checkbox-view.wxml
选择人员
取消
确定
{{ rootText }}
{{ current.DEPT_NAME }}
{{item.REAL_NAME}}
{{ item.DEPT_NAME }}
checkbox-view.js
Component({
properties:{
list: {
type: Array,
value :[],
observer() {
this.init();
}
},
rootText:{
type: String,
value : 'root'
},
title: {
type: String,
value: 'key'
},
children:{
type: String,
value: 'children'
},
content:{
type: String,
value: 'userlist'
},
selected:{
type: Array,
value: []
}
},
data:{
showPicker: false,
firstShow: false,
outlist: [],
path: [],
current: {},
isRoot: true,
selected: []
},
methods:{
// 展示picker
showPicker() {
if (!this.data.firstShow) {
this.setData({
firstShow: true
})
}
this.setData({
showPicker: true,
})
},
// 隐藏picker
hidePicker() {
this.setData({
showPicker: false
})
},
// 取消按钮事件
cancal() {
this.hidePicker();
},
// 确定按钮事件
sure() {
this.hidePicker();
this.triggerEvent('click', {
selected: this.data.selected
});
// this.triggerEvent('click', { value: user });
},
init(){
this.data.selected = this.properties.selected;
this.toRoot();
},
toRoot(){
// console.log(this.properties.list)
this.properties.list.forEach((item)=>{
item.itemShow='';
item.itemTrans='';
})
this.setData({
outlist: this.properties.list,
current:{},
isRoot: true,
path:[]
})
},
intoNextPath(e){
var caninto = e.currentTarget.dataset.caninto;
// console.log(e.currentTarget.dataset)
if(!caninto){
return
}
var item = e.currentTarget.dataset.item;
var index = e.currentTarget.dataset.index;
var path = this.data.path;
path.push(index);
item = this.initUser(item)
this.setData({
path: path,
current: item,
outlist: item[this.properties.children],
isRoot: false
});
this.scrollTop();
},
backLastPath(e){
var path = this.data.path;
var floor = path.length;
if (floor <= 1){
this.toRoot()
}else{
path.pop();
console.log('back:' + path)
var list = this.properties.list;
var item = {};
path.forEach((index) =>{
item = list[index];
list = item[this.properties.children]
})
var isRoot = false;
if (this.data.path.length <= 0){
isRoot = true;
}
// console.log(item)
item = this.initUser(item);
this.setData({
path: path,
current: item,
outlist: list,
isRoot: isRoot
})
}
this.scrollTop();
},
openContent(e){
var index = e.currentTarget.dataset.index;
var itemShow = this.data.outlist[index].itemShow
if (itemShow == null || itemShow == ''){
this.setData({
['outlist[' + index + '].itemShow']: 'item-show',
['outlist[' + index + '].itemTrans']:'item-trans90'
})
}else{
this.setData({
['outlist[' + index + '].itemShow']: '',
['outlist[' + index + '].itemTrans']: ''
})
}
},
checkboxChange(e) {
let checkarr = this.data.selected
const items = this.data.current
const values = e.detail.value
for (let i = 0, lenI = items.userlist.length; i < lenI; ++i) {
items.userlist[i].checked = false
if(checkarr.indexOf(items.userlist[i].USER_NAME) > -1) {
checkarr.splice(checkarr.indexOf(items.userlist[i].USER_NAME), 1)
}
for (let j = 0, lenJ = values.length; j < lenJ; ++j) {
if (items.userlist[i].USER_NAME === values[j]) {
items.userlist[i].checked = true
if(!checkarr.includes(values[j])) {
checkarr.push(values[j])
}
break
}
}
}
// console.log(checkarr)
this.setData({
current: items,
selected: checkarr
})
},
initUser(dept){
// console.log(dept)
var selected = this.data.selected;
var userlist = dept.userlist;
userlist.forEach((user) => {
user.checked = false;
for(let j = 0, lenJ = selected.length; j < lenJ; ++j) {
if (selected[j] == user.USER_NAME) {
user.checked = true;
}
}
})
dept.userlist = userlist
return dept
},
scrollTop(){
setTimeout(function () {
wx.pageScrollTo({
scrollTop: 0,
duration: 300
})
}.bind(this), 200)
}
}
})
checkbox-view.json
{
"component": true,
"usingComponents": {
"mp-icon": "/miniprogram_npm/weui-miniprogram/icon/icon"
}
}
checkbox-view.wxss
page {
height: 100%;
width: 100%;
}
.showPicker {
width: 100%;
height: 80rpx;
line-height: 80rpx;
font-size: 30rpx;
background-color: paleturquoise;
text-align: center;
}
.showtext{
font-size: 32rpx;
color: rgb(32, 154, 224);
}
.shade-container {
position: fixed;
height: 100%;
width: 100%;
top: 0;
right: -200%;
display: flex;
justify-content: space-around;
background-color: rgba(0, 0, 0, 0.5);
transform: translateX(-200%);
transition: all 0.5s ease;
z-index: 9999;
}
.hide-container {
position: fixed;
height: 100%;
width: 100%;
top: 0;
right: -200%;
z-index: 9999;
display: flex;
justify-content: space-between;
transform: translateX(100%);
transition: all 0.5s ease-in;
}
.left-shade {
width: 30%;
height: 100%;
}
.right-choose {
width: 70%;
height: 100%;
background-color: #fff;
padding: 40rpx;
}
.picker-container {
height: calc(100% - 200rpx);
overflow-x: hidden;
overflow-y: scroll;
}
.picker-container::-webkit-scrollbar {
display: none;
}
.title{
font-size: 36rpx;
font-weight: bold;
border-bottom: 1px solid #dddee1
}
.tran-icon{
color: #5cadff;
}
.padder{
padding: 10px;
}
.padder-l{
padding-left: 10px;
}
.padder-l-sm{
padding-left: 5px;
}
.padder-l-md{
padding-left: 15rpx;
}
.padder-r-md{
padding-right: 15rpx;
}
.cell-group{
border: 0px !important;
position: relative;
}
.left_icon{
position: absolute;
top: 18rpx;
left: 0;
}
.left_text{
margin-left: 45rpx;
}
.b-t{
border-top: 1px solid #e9eaec!important;
}
.cell{
padding: 20rpx 0;
border-top: 1px solid #e9eaec;
position: relative;
}
.cell_righticon{
position: absolute;
right: 15rpx;
top: 15rpx;
}
.item-group .item:last-child{
border: 0px !important;
}
.item{
padding: 15px 0;
border-bottom: 1px solid #f8f8f9 !important;
}
.item-show{
display: block;
}
.item-trans90{
transform:rotate(90deg);
-ms-transform:rotate(90deg); /* Internet Explorer */
-moz-transform:rotate(90deg); /* Firefox */
-webkit-transform:rotate(90deg); /* Safari 和 Chrome */
-o-transform:rotate(90deg); /* Opera */
}
.button-container {
width: 100%;
height: 80rpx;
display: flex;
justify-content: space-between;
font-size: 24rpx;
text-align: center;
border-bottom: 2rpx solid #eaeaea;
}
.cancal {
width: 100rpx;
height: 40rpx;
line-height: 40rpx;
border: 2rpx solid #ddd;
border-radius: 8rpx;
}
.sure {
width: 100rpx;
height: 40rpx;
line-height: 40rpx;
border: 2rpx solid rgb(132, 235, 132);
border-radius: 8rpx;
}
上面就是自定义组件的代码。基本拿去改一改就能用
引用的地方
index.wxml
* 代打人员:
{{retpeop}}
index.json
{
"usingComponents": {
"checkbox-view": "../../../Components/checkbox-view/checkbox-view"
}
}
index.js
// 点击确定事件
choose(e) {
let retpeop = this.setoptuser(this.data.peopleList, e.detail.selected)
retpeop = retpeop.join(',')
this.setData({
selected: e.detail.selected,
retpeop: retpeop
})
},
setoptuser(arrData, selected) {
let retpeop = []
for(let i = 0; i < arrData.length; i++) {
if(arrData[i].userlist.length > 0) {
arrData[i].userlist.forEach((item) => {
for(let j = 0; j < selected.length; j++) {
if(item.USER_NAME == selected[j]) {
retpeop.push(item.REAL_NAME)
}
}
})
}
if(arrData[i].children) {
this.setoptuser(arrData[i].children, selected)
}
}
return retpeop
},
数据自己去和后台要吧。我这里大概是这样的数据。
好了,去试试吧。欢迎交流。