因为项目需求,需要一个树形下拉选择框,参考了网上的树形结构整理出了这样一个效果图
下载地址:wx_treeSelect下载
其实主要还是参考了treeview的递归思想 微信小程序实现简单的树形图treeview 绘制出下拉框内的内容,在加个状态判断展开隐藏下拉框,方法回调显示选择值 其实思想还是很容易的 接下来直接上代码
1.首先新建树形菜单组件 —— mytree
(1) mytree.wxml
<view class="container"><view style="padding:5rpx 0;"><image wx:if='{{ isBranch }}' bindtap='toggle' src="{{ open ? '/image/show_less.png' : '/image/show_more.png'}}" class='item-sImg'></image><image wx:else src='/image/page_turning_right.png' class='item-sImg'></image><text bindtap='tapItem' data-itemid='{{ model.id }}' data-value='{{ model.text }}'>{{ model.text }}</text></view><view style='padding-left: 25rpx;' wx:if='{{ isBranch }}' hidden='{{ !open }}'><mytree wx:for='{{ model.nodes }}' wx:key='id' model='{{ item }}'></mytree></view>
</view>
(2) mytree.wxss
.container{font-size: 30rpx;color: #333;
}.item-sImg{width: 40rpx;height: 40rpx;vertical-align: middle;
}
(3) mytree.json
{"component": true,"usingComponents": {"mytree": "../mytree/mytree"}
}
(4) mytree.js
Component({properties: {model: Object,},data: {open: true,isBranch: false,},methods: {toggle: function(e) {if (this.data.isBranch) {this.setData({open: !this.data.open,})}},tapItem: function(e) {var itemid = e.currentTarget.dataset.itemid;var value = e.currentTarget.dataset.value;this.triggerEvent('tapitem', { value: value,itemid: itemid }, { bubbles: true, composed: true });}},ready: function(e) {this.setData({isBranch: Boolean(this.data.model.nodes && this.data.model.nodes.length),});}
})
2.再创建下拉树形列表组件 —— treeSelect
(1) treeSelect.wxml
<view class='com-selectBox'><view class='com-sContent' bindtap='selectToggle'><view class='com-sTxt'>{{nowText}}</view><image src='/image/show_more.png' class='com-sImg'></image></view><view class='com-sList' wx:if="{{selectShow}}"><view wx:if='{{ isBranch }}' hidden='{{ !open }}'><mytree wx:for='{{ model.nodes }}' wx:key='id' model='{{ item }}' bind:tapitem='tapItem'></mytree></view></view>
</view>
(2) treeSelect.wxss
.com-selectBox{width: 500rpx;
}
.com-sContent{border: 2rpx solid #d3d3d3;background: white;border-radius: 5%;position: relative;padding: 5rpx 30rpx;line-height: 2;height: 60rpx;
}
.com-sImg{position: absolute;right: 0;top: 50%;width: 40rpx;height: 40rpx;transform: translate(-50%,-50%);
}
.com-sTxt{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}
.com-sList{background: white;width: inherit;position: absolute;border: 1px solid #e2e2e2;border-top: none;box-sizing: border-box;z-index: 3;height: 200px;overflow: auto;padding: 15rpx;
}
.com-sItem{height: 30px;line-height: 30px;border-top: 1px solid #e2e2e2;padding: 0 6px;text-align: left;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;font-size: 14px;
}
.com-sItem:first-child{border-top: none;
}.item-sImg{width: 40rpx;height: 40rpx;vertical-align: middle;
}
(3) treeSelect.json
{"component": true,"usingComponents": {"mytree": "../mytree/mytree"}
}
(4) treeSelect.js
Component({/*** 组件的属性列表*/properties: {model: Object},/*** 组件的初始数据*/data: {selectShow:false,nowText : "请选择",open: true,isBranch: false,},/*** 组件的方法列表*/methods: {selectToggle:function(){var nowShow=this.data.selectShow;this.setData({selectShow: !nowShow})},toggle: function(e) {if (this.data.isBranch) {this.setData({open: !this.data.open,})}},tapItem: function(e) {var itemid = e.detail.itemid;var value = e.detail.value;this.triggerEvent('tapitem', { value: value,itemid: itemid }, { bubbles: true, composed: true });this.setData({selectShow: false,nowText:value})}},ready: function(e) {this.setData({isBranch: Boolean(this.data.model.nodes && this.data.model.nodes.length)});}
})
3.最后就是创建一个页面测试一下啦 —— index
(1) index.wxml
<!--index.wxml-->
<view class="container"><treeSelect model='{{selectArray}}' bind:tapitem='tapItem'></treeSelect>
</view>
(2) index.wxss
.container{padding: 30rpx;
}
(3) index.json
{"navigationBarTitleText": "树形下拉框","usingComponents": {"treeSelect": "/components/treeSelect/treeSelect"}
}
(4) index.js
//index.js
//获取应用实例
const app = getApp()Page({data: {selectArray: {text: '', id: '',nodes: [{"id": 5,"text": "沈阳市","nodes": []}, {"id": 6,"text": "本溪市","nodes": [{"id": 7,"text": "本溪石街","nodes": []}, {"id": 8,"text": "本溪梨树","nodes": []}, {"id": 9,"text": "辽宁本溪","nodes": []}, {"id": 10,"text": "本溪平山","nodes": []}, {"id": 11,"text": "本溪明山","nodes": []}]}, {"id": 12,"text": "盘锦市","nodes": [{"id": 13,"text": "盘锦辽东湾","nodes": []}]}, {"id": 14,"text": "辽阳市","nodes": [{"id": 15,"text": "辽阳灯塔","nodes": []}]}, {"id": 16,"text": "铁岭市","nodes": [{"id": 17,"text": "铁岭银州","nodes": []}]}, {"id": 18,"text": "鞍山市","nodes": [{"id": 19,"text": "鞍山千山","nodes": []}]}]}},tapItem: function (e) {var itemid = e.detail.itemid;var itemval = e.detail.value;console.log("所选中的分区编号:" + itemid + ", 名称:" + itemval);}
})
index.js中有相应的数据格式,因为项目需要我只用了两级,其实可以很多级,有需要的小伙伴可以自己测试一下。因为另外的需要我要准备在封装个树形数据表格了(꒦_꒦) 所以关于备注还有详细的介绍以后有时间再慢慢补吧。时间紧张具体的细节还没有仔细确认,如果有问题欢迎给我留言啊~
注:本人工作两年的菜鸟前端,代码还是过于稚嫩,出来的效果自己也不是那么满意,如果大家有更好的组件欢迎推荐给我(╹▽╹) 大家一起加油啊! ヾ(◍°∇°◍)ノ゙