多选:

使用的是插件市场的tree树组件(ly-tree)

<ly-tree ref="tree" :treeData="treeData" v-if="ready"
	nodeKey="id" @node-expand="handleNodeExpand" 
	@node-click="handleNodeClick" :showCheckbox="true" :checkOnClickNode="true" :expandOnClickNode="false"
	:defaultExpandAll="true" @check-change="handleCheck"
></ly-tree>

其中@node-expand当树要展开时点击树形图左边的箭头调用;@node-click:点击树上的文件节点时调用;@check-change:点击节点上的复选框和点击树文字都会调用。具体使用时只用@check-change即可。:showCheckbox="true"显示复选框

具体代码处理如下:

<template>
    <view v-if="isShowConfirm" class="my-confirm-notice">
        <view class="confirm-content-wrap1">
            <!-- 标题 -->
            <view class="unipop__ui_tit">
            	<view v-if="titleText" class="unipop__ui_tit_text">{{titleText}}</view>
            	<image src="../../static/images/workbeach/icon_close.png" class="close_image" @click="close()"></image>
            </view>
            <!-- 内容 -->
			<view class="content_margin">
				<view class="flex_row_center label_text">组织机构:
					<input type="text" disabled="true" class="inputStyle" ref='groupInput'
					 @click="popOrganization" placeholder="请选择组织机构" :value='groupName'>
				</view>
				<view v-show="isShow" class="top_level">
					<view class="flex_row_center label_text">
						<view style="width: 140rpx;"></view>
						<scroll-view style="height: 200px;" class="ly_tree_style" :scroll-y="true">
							<ly-tree ref="tree" :treeData="treeData" v-if="ready"
								nodeKey="id" @node-expand="handleNodeExpand" 
								@node-click="handleNodeClick" :showCheckbox="true" :checkOnClickNode="true" :expandOnClickNode="false"
								:defaultExpandAll="true" @check-change="handleCheck"
								></ly-tree>
						</scroll-view>
					</view>
				</view>
				<view class="flex_row_center label_text label_margin">部门名称:
					<input type="text" class="inputStyle" placeholder="部门名称" @input="onKeyInput" :value="departName" >
				</view>
			</view>
            <view v-if="btns" class="unipop__ui_btns">
                <text v-for="(item,index) in btns" :key="index" class="btn" :style="item.style" @tap="btnTaped(item)">{{item.text}}</text>
            </view>
        </view>
    </view>
</template>


<script>
	export default {
		data() {
		    return {
				isShowConfirm: false,
				titleText: '', // 提示框标题
				outerData: null, // 用于记录外部传进来的数据,也可以给外部监听userBehavior,事件的函数提供判断到底是哪个事件触发的
				btns: {},
				treeData:[],
				ready:false,
				isShow:false,
				defalutValue:'请选择组织机构',
				selectCondition:{},
				departName:'',
				groups:[],
				groupName:''
		    }
		},
		created() {
			console.log('created')
		},
		mounted() {
			console.log('mounted')
			this.loadData()
		},
		methods: {
			show (titleText, config) {
				this.titleText = titleText || '查询条件'

				if (Object.prototype.toString.call(config) === '[object Object]') {
					// 确保用户传递的是一个对象
					this.outerData = config.data || null
					this.btns = this.outerData.btns
					console.log('noticeDialog', this.outerData)
				}

				this.isShowConfirm = true
			},
			close() {
				this.isShowConfirm = false;
				this.isShow = false;
				this.groupName = '';
				this.groups = [];
				this.departName = '';
				this.selectCondition = {};
			},
			btnTaped(item) {
				let self = this;
				console.log(item);
				if(item.text == '重置') {
					console.log('重置');
					this.isShow = false;
					this.groupName = '';
					this.groups = [];
					this.$refs.tree.setCheckAll(false);
					this.departName = '';
					this.selectCondition = {};
				} else {
					item.onTap(this.selectCondition);
					this.close();
				}
			},
			popOrganization() {
				this.isShow = !this.isShow;
			},
			onKeyInput(event) {
				this.departName = event.target.value;
				this.selectCondition['deptName'] = this.departName;
			},
			loadData() {
				setTimeout(()=> {
					this.treeData = [
						{
							id:1,label:'客流分析与管理',
							children:[
								{id:11,label:'IT部'},
								{id:12,label:'运维部'},
								{id:13,label:'营销部'},
								{id:14,label:'实施部'},
								{id:15,label:'售后部'},
							]
						},
						{
							id:2,label:'一级2',
							children:[
								{id:21,label:'二级21'},
								{id:22,label:'二级22'},
							]
						},
						{
							id:3,label:'客流分析与管理',
							children:[
								{id:31,label:'IT部'},
								{id:32,label:'运维部'},
								{id:33,label:'营销部'},
								{id:34,label:'实施部'},
								{id:35,label:'售后部'},
							]
						},
					];
					this.ready = true;
				},2000);
			},
			handleNodeExpand(obj) {
				console.log('handleNodeExpand='+JSON.stringify(obj))
			},
			handleNodeClick(obj) {
				//console.log('handleNodeClick='+JSON.stringify(obj));
			},
			handleCheck(obj) {
				console.log('handleCheck='+JSON.stringify(obj))
				this.getSelectData(obj.node);
			},
			getSelectData(obj) {
				if(obj.checked) {
					if(this.groups.indexOf(obj.data) != -1) {
						console.log('groups.contains')
					} else {
						this.groups.push(obj.data);
					}
				} else {
					var index = this.groups.indexOf(obj.data);
					console.log('groups.splice==='+index)
					if(index != -1) {
						this.groups.splice(index,1);
					}
				}
				let groupParam = '';
				let groupNames = '';
				for(var i=0;i< this.groups.length; i++) {
					if(groupParam) {
						groupParam = groupParam+','+this.groups[i].id;
					} else {
						groupParam = this.groups[i].id;
					}
					if(groupNames) {
						groupNames = groupNames+','+this.groups[i].label;
					} else {
						groupNames = this.groups[i].label;
					}
				}
				this.groupName = groupNames;
				this.selectCondition = {'deptIds':groupParam};
				console.log('selectCondition='+groupParam)
			}
		}
	}
</script>

<style lang="scss">
	.my-confirm-notice {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: rgba(0, 0, 0, 0.5);
		z-index: 998;
		/* 这里防止当用户长按屏幕,出现的黑色背景色块,以及 iPhone 横平时字体的缩放问题 */
		-webkit-text-size-adjust: 100%;
		-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
		display: flex;
		align-items: center;
	}
	.confirm-content-wrap1 {
		position: relative;
		left: 0;
		right: 0;
		// width: 60%;
		width: 90%;
		height: 247px;
		margin: 0 auto;
		background-color: #FFFFFF;
		border-radius: 10px;
		z-index: 999;
		user-select: none;
	}
	.unipop__ui_tit_text {
		color: white;
		text-align: center;
		line-height: 44px;
		width: 100%;
		font-size: 16px;
	}
	.close_image {
		z-index: 100;position: absolute;float: right;right: 10px;width:30px;height: 30px;
	}
	.unipop__ui_tit {
		background-color: #074498;
		width: 100%;
		border-top-left-radius: 10px;
		border-top-right-radius: 10px;
		height: 44px;
		display: flex;
		align-items: center;
	}
	.unipop__ui_btns{
		height: 80px;
		justify-content: space-around;
		display: flex;
		padding-left: 20px;
		padding-right: 20px;
		align-items: center;
	}
	.btn {
		width: 81px;
		height: 40px;
		background-color: #074498;
		line-height: 34px;
		text-align: center;
		font-size: 13px;
		border-radius: 6rpx;
	}
	.content_margin {
		padding: 15px 0px 15px 0px;
	}
	.flex_row_center {
		display: flex; flex-direction: row; justify-content: center; align-items: center;
	}
	.label_text {
		font-size: 28rpx;color: #555555;
	}
	.label_margin {
		margin-top: 36rpx;
	}
	.inputStyle {
		border: #bababa 0.5px solid; width: 169px;height: 34px; box-sizing: border-box; font-size: 13px; padding: 3px 2px;
	}
	.top_level {
		position: fixed;z-index: 100;width: 90%;
	}
	.ly_tree_style {
		border: #F5F5F5 1px solid; width: 169px;
	}
</style>

 单选:

<scroll-view style="height: 200px;" class="ly_tree_style" :scroll-y="true">
    <ly-tree ref="tree" :treeData="treeData" v-if="ready" :showRadio="true"
         nodeKey="id" :checkOnClickNode="true" 
         :expandOnClickNode="false" :defaultExpandAll="true"
	 @node-click="handleNodeClick"
	 @check='handleCheck'
    ></ly-tree>
</scroll-view>

 其中:@node-click:点击树上的文字节点时调用;@check:点击树上的文字节点或单选框时都会调用。具体使用时只用@check即可。:showRadio="true"显示单选框

具体代码使用如下:

<template>
    <view v-if="isShowConfirm" class="my-confirm-notice">
        <view class="confirm-content-wrap1">
            <!-- 标题 -->
            <view class="unipop__ui_tit">
				<view v-if="titleText" class="unipop__ui_tit_text">{{titleText}}</view>
				<image src="../../static/images/workbeach/icon_close.png" class="close_image" @click="close()"></image>
			</view>
            <!-- 内容 -->
            <view class="content_margin">
            	<view class="flex_row_center label_text">组织机构:
            		<input type="text" disabled="true" class="inputStyle" ref='groupInput'
            		 @click="popOrganization" placeholder="请选择组织机构" :value='groupName'>
            	</view>
            	<view v-show="isShow" class="top_level">
            		<view class="flex_row_center label_text">
            			<view style="width: 140rpx;"></view>
            			<scroll-view style="height: 200px;" class="ly_tree_style" :scroll-y="true">
            				<ly-tree ref="tree" :treeData="treeData" v-if="ready" :showRadio="true"
            					nodeKey="id" :checkOnClickNode="true" 
            					:expandOnClickNode="false" :defaultExpandAll="true"
								@check='handleCheck'
            					></ly-tree>
            			</scroll-view>
            		</view>
            	</view>
            	<view class="flex_row_center label_text label_margin">
					<view style="width: 140rpx;">姓名:</view>
            		<input type="text" class="inputStyle" placeholder="姓名" @input="onKeyInput" :value="userName" >
            	</view>
				<view class="flex_row_center label_text label_margin">
					<view style="width: 140rpx;">状态:</view>
					<wyb-drop-down 
						 ref="dropDown"
						 :options="dropDownOptions"
						 :heightSize="heightSize"
						 @select="onItemSelect"
						 class="dropDownStyle">
					   <!-- 自定义模式开启时,这里可以放内容 -->
					</wyb-drop-down>
				</view>
				<view class="flex_row_center label_text label_margin">
					<view style="width: 140rpx;">入职时间:</view>
					<datetimePicker
						type="date"
						:value="start"
						@change="changeStart"
						class="dataPickerStyle"/>
				</view>
				<view class="flex_row_center label_text label_margin">
					<view class="dateOperator">-</view>
					<datetimePicker
						type="date"
						:value="end"
						@change="changeEnd"
						class="dataPickerStyle"/>
				</view>
            </view>
            <view v-if="btns" class="unipop__ui_btns">
                <text v-for="(item,index) in btns" :key="index" class="btn" :style="item.style" @tap="btnTaped(item)">{{item.text}}</text>
            </view>
        </view>
    </view>
</template>


<script>
	import datetimePicker from '@/components/uni-datetime-picker/uni-datetime-picker.vue'
	export default {
		components:{datetimePicker},
		data() {
		    return {
		        isShowConfirm: false,
		        titleText: '', // 提示框标题
		        outerData: null, // 用于记录外部传进来的数据,也可以给外部监听userBehavior,事件的函数提供判断到底是哪个事件触发的
		        btns: [],
				treeData:[],
				ready:false,
				isShow:false,
				selectCondition:{},
				userName:'',
				groups:[],
				groupName:'',
				start: '',
				end:'',
				dropDownOptions: [{
					header: '状态',
					// contents在自定义开启时可以不用传
					contents: ['状态', '启用', '禁用'], 
					custom: false // 该栏目开启自定义模式
				}],
				heightSize:{
					header:40,content:48
				},
		    }
		},
		mounted() {
			console.log('mounted')
			this.loadData()
			// this.single = new Date();
		},
		methods: {
			show (titleText, config) {
				this.titleText = titleText || '查询条件'
			
				if (Object.prototype.toString.call(config) === '[object Object]') {
					// 确保用户传递的是一个对象
					this.outerData = config || null
					this.btns = this.outerData.btns
					console.log('noticeDialog', this.outerData)
				}
			
				this.isShowConfirm = true
			},
			close(){
				this.isShowConfirm = false;
				this.isShow = false;
				this.groupName = '';
				this.groups = [];
				this.userName = '';
				this.start = '';
				this.end = '';
				this.dropDownOptions[0].header = '状态';
				this.selectCondition = {};
			},
			btnTaped(item) {
				console.log(item);
				if(item.text == '重置') {
					this.isShow = false;
					this.groupName = '';
					this.groups = [];
					this.$refs.tree.setCheckAll(false);
					this.userName = '';
					this.start = '';
					this.end = '';
					this.dropDownOptions[0].header = '状态';
					this.$refs.dropDown.onContentItemsTap(0);
					this.selectCondition = {};
				} else {
					item.onTap(this.selectCondition);
					this.close();
				}
			},
			loadData() {
				setTimeout(()=> {
					this.treeData = [
						{
							id:1,label:'客流分析与管理',
							children:[
								{id:11,label:'IT部'},
								{id:12,label:'运维部'},
								{id:13,label:'营销部'},
								{id:14,label:'实施部'},
								{id:15,label:'售后部'},
							]
						},
						{
							id:2,label:'一级2',
							children:[
								{id:21,label:'二级21'},
								{id:22,label:'二级22'},
							]
						},
						{
							id:3,label:'客流分析与管理',
							children:[
								{id:31,label:'IT部'},
								{id:32,label:'运维部'},
								{id:33,label:'营销部'},
								{id:34,label:'实施部'},
								{id:35,label:'售后部'},
							]
						},
					];
					this.ready = true;
				},2000);
			},
			popOrganization() {
				this.isShow = !this.isShow;
			},
			onKeyInput(event) {
				this.userName = event.target.value;
				this.selectCondition['nickName'] = this.userName;
			},
			handleCheck(obj) {
				console.log('handleCheck='+JSON.stringify(obj))
				this.getSelectData(obj.node);
			},
			getSelectData(obj) {
				let groupParam = '';
				let groupNames = '';
				if(obj.checked) {
					groupParam = obj.data.id;
					groupNames = obj.data.label;
				} else {
					groupParam = '';
					groupNames = '';
				}
				this.groupName = groupNames;
				this.selectCondition = {'deptId':groupParam};
				console.log('selectCondition='+groupParam)
			},
			changeStart(e) {
				this.start = e;
				console.log("-change事件:", e);
				this.selectCondition['paramBeginTime'] = this.start;
			},
			changeEnd(e) {
				this.end = e;
				console.log("-change事件:", e);
				this.selectCondition['paramEndTime'] = this.end;
			},
			onItemSelect(e) {
				console.log("onItemSelect事件:", e);
				this.dropDownOptions[0].header = e.content;
				this.selectCondition['status'] = (e.contentIndex-1).toString();
				this.$refs.dropDown.close();
			}
		}
	}
</script>

注意:

1。当获取到的json数据不是{"id":1,"label":"****"}的形式时,而是{"deptId":201,"deptName":"B分店",}时,

label可以通过设置props解决:

props: {
	// id:'deptId',
	label: 'deptName' // 指把数据中的‘categoryName’当做label也就是节点名称
},
<ly-tree ref="tree" :treeData="treeData" v-if="ready" :showRadio="true"
      nodeKey="deptId" :checkOnClickNode="true" 
      :expandOnClickNode="false" :defaultExpandAll="true"
      @check='handleCheck' :props="props"
></ly-tree>

程序会将deptName的值,替换成label显示;取值的时候还是取deptName的值,

getSelectData(obj) {
	let groupParam = '';
	let groupNames = '';
	if(obj.checked) {
		groupParam = obj.data.deptId;
		groupNames = obj.data.deptName;
	} else {
		groupParam = '';
		groupNames = '';
	}
	this.groupName = groupNames;
	this.selectCondition = {'deptId':groupParam};
	console.log('selectCondition='+groupParam)
},

但是deptId不可以用同样的方法转成id,它可以在ly-tree的nodeKey属性中直接设置。

2。当单选时,取消选中的值用

this.$refs.tree.setCheckedKeys([]);

当多选时,取消选中的项用:

this.$refs.tree.setCheckAll(false);

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐