element-ui checkbox树,选中后再二次生成新树

本文介绍了一种使用Vue.js实现的树形结构代码,包括树形结构的展示、节点点击事件处理、多选与搜索功能,以及如何在两个模态框间传递和更新树形数据。通过具体代码示例,详细解析了树形数据的处理方法,如子节点到父节点的数据获取、生成新树等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

树形结构代码:

<div class="modal-body" style="height:350px">
	<div class="fileTree">
		<el-tree v-cloak show-checkbox default-expand-all 
			node-key="id" 
			ref="tree" 
			@node-click="handleNodeClick" 
			:data="data" 
			:props="defaultProps" 
			check-strictly
			:expand-on-click-node="false"
			:filter-node-method="filterNode"
			class="filter-tree"
		>
			<span class="custom-tree-node" slot-scope="{ node, data }"> 
			<span> {{ node.label }}</span>
			<span>
				<el-button
					type="text"
					size="mini"
					@click="() => editMenu(data)">
					编辑菜单
			    </el-button>
			</span>
		</el-tree>
	</div>
</div>

事件执行入口:

<div class="modal-footer">
	<button  type="submit" class="btn btn-primary btn-sm btn-confirm" @click="getCheckedData">
		设为配置文件
	</button>
	<button type="button" class="btn btn-default btn-sm btn-cancel" data-dismiss="modal">
		 取消
	</button>
	<button  id="newTree" type="button" class="btn btn-primary btn-sm btn-confirm" @click="toNewTree()">
		 生成新树
	</button>
</div>

二次生成新树模态框代码:

<div class="modal fade" id="newdplyPackageFileTree" role="dialog" aria-labelledby="myModalLabel" style="z-index: 1056;">
        <div class="modal-dialog" role="document" id="newFileTree">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                    <h5 class="modal-title" id="newmyModalLabelForTask">发布包文件结构2</h5>
                </div>
				<!-- <ul id="fileTree" class="ztree" style="height: 360px;overflow-y: auto;">
				</ul> -->
				<div class="input-group" style="border-radius:0px;border-bottom:1px solid #ddd;box-shadow:none;">
					<input type="text" style="border-radius:0px;border:none;box-shadow:none;" v-model="filterText" class="form-control" placeholder="请输入" aria-describedby="basic-addon2">
					<span style="padding:0px 20px;border-radius:0px;background-color:#fff;box-shadow:none;border:none;" class="input-group-addon" id="basic-addon2"><img style='height:30px;' src="${ctx}/images/search_total.png"></span>
				</div>
				<div class="modal-body" style="height:350px">
					<div class="fileTree">
						<el-tree v-cloak default-expand-all 
							node-key="id" 
							ref="tree" 
							@node-click="handleNodeClick" 
							:data="dataNew" 
							:props="defaultProps" 
							
							:expand-on-click-node="false"
							:filter-node-method="filterNode"
							class="filter-tree"
						>
							<span class="custom-tree-node" slot-scope="{ node, data }"> 
							<span> {{ node.label }}</span>
						</el-tree>						
					</div>
				</div>
				<div class="modal-footer">
			        <button type="button" class="btn btn-default btn-sm btn-cancel" data-dismiss="modal">
			        	取消
			        </button>
                </div>
			</div>
        </div>
    </div>

Vue代码:

<script>
	var vm = new Vue({
		el:'#fileTree',
		data: {
	         data: [{
	             name: '加载中......',
	         }],
	         checkedId: [],
	         checkedObj:[],		//所有选中节点的  对象数组
	         defaultProps: {			//el-tree默认数据格式
	             children: 'children',
	             label: 'name',  
	         },
	         currentClick:[],
	         filterText: '',			//声明搜索框中初始值为空
	         newTreeArr:null
	     },
	     watch: {					//搜索框内容监控(固定方法)
	  	    filterText(val) {
	  	      this.$refs.tree.filter(val);
	  	    }
	  	},
	    updated() {
	        // 给多选树设置默认值
	        this.$refs.tree.setCheckedKeys(this.checkedId);
	    },
		methods:{
			dataTranse:function(val){
				var that = this;
				var sth = val;
				console.log('sth>>>>>');
				console.log(sth);
				var res = dataTrans(sth, function (from, to) {
                    to.name = from.NAME;
                    to.id=from.ID;
                    to.label=from.NAME;
					to.disabled = from.DISABLED;
                });
				that.data = res;
			},
			//单选树节点获取当前数据的函数
			/* clickDeal(currentObj, treeStatus){
                this.clickCheck(currentObj, treeStatus,this.$refs.tree);
            }, */
           /*  clickCheck(currentObj, treeStatus, ref) {
            	var clickObj = currentObj;
            	this.checkedObj.push(clickObj);
            	console.log('selected --- obj>>>>>');
            	console.log(clickObj);
            }, */
            //子节点-->>>父节点全部一串数据的函数
			getCheckedData() {
            	var aKey = this.getCheckedKeys(this.data, this.$refs.tree.getCheckedKeys(),'ID');
                console.log('aKey>>>>>');
            	console.log(aKey);
                //this.newTreeArr = $.extend(true, [], aKey);
                //this.newTreeArr.push()
		    },
		    //子节点-->>>父节点全部一串数据的函数
		    getCheckedKeys (data, keys, key) {
                var res = [];
                recursion(data, false);
                return res;
                // arr -> 树形总数据
                // keys -> getCheckedKeys获取到的选中key值
                // isChild -> 用来判断是否是子节点
                function recursion (arr, isChild) {
                    var aCheck = [];
                    for ( var i = 0; i < arr.length; i++ ) {
                        var obj = arr[i];
                        aCheck[i] = false;

                        if ( obj.children ) {
                            aCheck[i] = recursion(obj.children, true) ? true : aCheck[i];
                            if ( aCheck[i] ) {
                                //res.push(obj[key]);//push的key 当前为ID
                                res.push(obj);		//push选中节点的父节点对象数据
                            }
                        }

                        for ( var j = 0; j < keys.length; j++ ) {
                            if ( obj[key] == keys[j] ) {
                                aCheck[i] = true;
                                if ( res.indexOf(obj[key]) == -1 ) {
                                    //res.push(obj[key]);//push的key 当前为ID
                                    //res.push(obj);		//push选中的子节点对象数据
                                }
                                break;
                            }
                        }
                    }
                    if ( isChild ) {
                        return aCheck.indexOf(true) != -1;
                    }
                }
            },
          	//子节点&&父节点全部一串数据的函数
			getCheckedDataAll() {
            	var aKeyAll = this.getCheckedKeysAll(this.data, this.$refs.tree.getCheckedKeys(),'ID');
                console.log('aKeyAll>>>>>');
            	console.log(aKeyAll);
                this.newTreeArr = $.extend(true, [], aKeyAll);
                //this.newTreeArr.push()
		    },
		  	//子节点&&父节点全部一串数据的函数
		    getCheckedKeysAll (data, keys, key) {
                var res = [];
                recursionAll(data, false);
                return res;
                // arr -> 树形总数据
                // keys -> getCheckedKeys获取到的选中key值
                // isChild -> 用来判断是否是子节点
                function recursionAll (arr, isChild) {
                    var aCheck = [];
                    for ( var i = 0; i < arr.length; i++ ) {
                        var obj = arr[i];
                        aCheck[i] = false;

                        if ( obj.children ) {
                            aCheck[i] = recursionAll(obj.children, true) ? true : aCheck[i];
                            if ( aCheck[i] ) {
                                //res.push(obj[key]);//push的key 当前为ID
                                res.push(obj);		//push选中节点的父节点对象数据
                            }
                        }

                        for ( var j = 0; j < keys.length; j++ ) {
                            if ( obj[key] == keys[j] ) {
                                aCheck[i] = true;
                                if ( res.indexOf(obj[key]) == -1 ) {
                                    //res.push(obj[key]);//push的key 当前为ID
                                    res.push(obj);		//push选中的子节点对象数据
                                }
                                break;
                            }
                        }
                    }
                    if ( isChild ) {
                        return aCheck.indexOf(true) != -1;
                    }
                }
            },
	     	handleNodeClick(data) {
	     		console.log('clickdata>>>>>');
	     		console.log(data);
	     	},
	     	showRMenu:function(x, y, data){
	     		  $("#rMenu").css({ "display":"block","z-index":9999});
	      		  $("#rMenu a").show();
	      		  if(y>($(window).height())/2){
	      	    	//向上弹
	      	    	$("#rMenu").css({"top":y-70+"px", "left":x+5+"px", "visibility":"visible"}); //设置右键菜单的位置、可见
	      	      } else {
	      	    	//向下弹
	      	    	$("#rMenu").css({"top":y-5+"px", "left":x+25+"px", "visibility":"visible"}); //设置右键菜单的位置、可见
	      	      }
	        	  $("body").bind("mousedown", onBodyMouseDown);
	          },  
	     	editMenu(data) {
	        	this.currentClick = [];
	     		if(data){
	     			console.log('点击编辑菜单获取当前节点数据>>>>>');
	     			console.log(data);
	     			this.currentClick.push(data);
	     			this.showRMenu(event.clientX, event.clientY, data);
	     		}
	       },
	       //树搜索框
	       filterNode(value, data) {
	      	 	if (!value) return true;
	      	    return data.name.indexOf(value) !== -1;
	       },
	       toNewTree(){
	    	   this.getCheckedDataAll();
	    	   console.log('新树数据>>>>>');
			   console.log(this.newTreeArr);
			   $("#dplyPackageFileTree").modal('hide');
			   $("#newdplyPackageFileTree").modal('show');
			   vm2.dataTranseNew(this.newTreeArr);
	       }
	          
		},
		mounted: function () {
			
	    }
	    
	})
	
	
	var vm2 = new Vue({
		el:'#newFileTree',
		data: {
	         dataNew: [{
	             name: '加载中......',
	         }],
	         defaultProps: {			//el-tree默认数据格式
	             children: 'children',
	             label: 'name',  
	         },
	         filterText: '',			//声明搜索框中初始值为空
	     },
	     watch: {					//搜索框内容监控(固定方法)
	  	    filterText(val) {
	  	      this.$refs.tree.filter(val);
	  	    }
	  	},
		methods:{
			dataTranseNew:function(val){
				var that = this;
				var sth2 = val;
				console.log('sth2>>>>>');
				console.log(sth2);
				 $.each(sth2,function(i,item){
					if(item.children){
						delete item['children'];
					}
				}) 
				
				console.log('sth2---after>>>>>');
				 console.log(sth2);
				 sth2=getTree(sth2,0)
				 console.log('sth2---after---jhhhhh>>>>>');
				 console.log(sth2);
				 function getTree(data, PID) {			//二次生成树 删掉children属性,再转换ID、PID
					    let result = []
					    let temp
					    for (let i = 0; i < data.length; i++) {
					        if (data[i].PID == PID) {
					            temp = getTree(data, data[i].ID)
					            if (temp.length > 0) {
					                data[i].children = temp
					            }
					            result.push(data[i])
					        }
					    }
					    
					    return result
				}
				that.dataNew = sth2;
			},
	     	handleNodeClick(data) {
	     		console.log('clickdata2>>>>>');
	     		console.log(data);
	     	},
	       //树搜索框
	       filterNode(value, data) {
	      	 	if (!value) return true;
	      	    return data.name.indexOf(value) !== -1;
	       },   
		},
		mounted: function () {
			
	    }
	    
	})
</script> 
<think>首先,用户的问题是关于 Element UIel-checkbox 组件。他们想将值为 '是' 和 '否' 的字符串回显为选中的复选框状态。具体来说,他们需要知道如何绑定这些字符串值到复选框的选中状态。 回顾引用内容: - 引用[1] 提到,el-checkbox-group 的 v-model 绑定的是 label 的值,必须是字符串、数字或布尔值,不能是对象。 - 引用[2] 显示了一个例子:使用 el-checkbox-group 和 v-for 循环,其中 :label="city.id",并在标签内显示 {{city.name}}。v-model 绑定到 value,这是一个数组。 - 引用[3] 是一个简单的例子:el-checkbox-group v-model="checkList",每个 el-checkbox 有一个 label 属性,如 label="aaa"。 - 引用[4] 说明了如何回显:从后台获取字符串数据,分割成数组,然后设置到 v-model 绑定的变量上。 用户的具体场景:他们有两个选项,值是 '是' 和 '否',需要根据这些字符串值来设置复选框的选中状态。 关键点: - el-checkbox-group 的 v-model 应该绑定到一个数组,这个数组包含当前选中的项的 label 值。 - 每个 el-checkbox 的 label 属性定义了其值。 - 对于回显,如果后台返回的字符串是 '是' 或 '否',我们需要将这些字符串映射到复选框的选中状态。 可能的实现: 1. 定义两个复选框:一个对应 '是',另一个对应 '否'。 2. 使用 v-model 绑定到一个数组,比如 selectedValues。 3. 当回显时,根据后台返回的数据设置 selectedValues 数组。例如,如果返回 '是',则 selectedValues 应该包含 '是';如果返回 '否',则包含 '否'。 用户可能只有一个复选框?但问题中说的是 "回显为选中的复选框状态",并提到 '是' 和 '否',所以可能有两个独立的复选框,或者一个复选框表示是否,但通常复选框用于多选,单选可能用 radio 更好。但用户指定了 el-checkbox,所以可能有两个复选框:一个为 "是",一个为 "否"。 在 Element UI 中,el-checkbox 常用于多选,所以如果用户需要单选行为,他们可能应该使用 el-radio-group。但既然用户问了 el-checkbox,我会假设他们想用复选框。 如何绑定: - 例如,定义两个复选框: ```html <el-checkbox-group v-model="selectedOptions"> <el-checkbox label="是">是</el-checkbox> <el-checkbox label="否">否</el-checkbox> </el-checkbox-group> ``` - 在 data 中,selectedOptions 应该是一个数组,比如 ['是'] 如果选中了 "是"。 回显: - 假设后台返回的数据是一个字符串,比如 '是' 或 '否'。 - 我们需要将这个字符串转换为数组形式,因为 v-model 期望一个数组。 - 例如,如果返回 '是',则设置 selectedOptions = ['是'];如果返回 '否',则设置 selectedOptions = ['否']。 在代码中: - 在获取数据后,设置 this.selectedOptions = [response.data.value]; // 假设 response.data.value 是 '是' 或 '否' 如果用户有多个值,但这里只有两个选项,并且可能互斥,但复选框允许多选。如果行为应该是单选,用户可能需要额外的逻辑来确保只选一个,或者使用 radio。 但用户的问题是具体关于回显字符串 '是' 和 '否' 到选中状态。 参考引用[4],它展示了如何将字符串分割成数组用于回显:this.checkListData = rowData.orgAttribute.split(','); 但在这个案例中,字符串是单个值,没有逗号,所以不需要分割。 例如,后台返回 '是',那么设置 selectedOptions = ['是']。 现在,构建回答。 回答结构: 1. 解释问题:如何使用 el-checkbox 回显 '是' 和 '否' 字符串。 2. 提供示例代码。 3. 解释步骤。 4. 确保使用中文。 5. 添加相关问题。 系统指令要求: - 行内数学表达式用 $...$,但这里可能不需要数学。 - 独立公式用 $$...$$,但这里不相关。 - LaTeX 语法正确,但代码块用代码格式。 - 使用中文回答。 - 生成相关问题。 - 引用末尾添加标识,如 [^1],但引用是给定的,我需要参考它们。 引用是给定的,但用户的问题是基于这些引用,所以我应该在回答中引用它们。 用户上一次问题:用户提供了引用,并问 "如何将值为'是'和'否'的字符串回显为选中的复选框状态"。 所以,回答: - 介绍:在 Element UI 中,el-checkbox-group 的 v-model 绑定到一个数组,数组包含选中的 label 值。 - 对于 '是' 和 '否',定义两个复选框,label 分别为 '是' 和 '否'。 - 回显时,将后台返回的字符串(如 '是')设置为数组形式。 代码示例: 基于引用[2]和[3]。 数据定义: 在 data() 中: return { selectedOptions: [], // 初始空数组 // 其他数据 } 模板: <el-checkbox-group v-model="selectedOptions"> <el-checkbox label="是">是</el-checkbox> <el-checkbox label="否">否</el-checkbox> </el-checkbox-group> 当获取数据时(例如,编辑回显): 假设从 API 获取数据,response.data.answer 是 '是' 或 '否'。 this.selectedOptions = [response.data.answer]; // 因为单个值,但作为数组 如果返回的是多个值,但这里只有一个。 如果后台返回的是逗号分隔的字符串,但用户指定了 '是' 和 '否',所以可能单个值。 在引用[4]中,他们用了 split,但这里不需要,因为只有一个值。 所以,直接设置数组。 如果用户需要两个复选框但只能选一个,可能需要添加逻辑,但那是额外的东西。 现在,生成相关问题: 基于主题,相关问题可能包括: 1. 如何处理 el-checkbox 的多选行为? 2. 如何确保 el-checkbox 的单选行为? 3. 其他回显问题或绑定问题。 具体点。 相关问题: 1. 如果后台返回的是布尔值而不是字符串,如何绑定? 2. 如何自定义 el-checkbox 的显示文本? 3. 在表单验证中如何处理 el-checkbox? 引用添加:在回答中,当提到关键点时,添加引用标识。 例如,根据引用[1],label 必须是基本类型[^1]。 在回答中: - 引用关键点。</think>### Element UI el-checkbox 字符串值回显实现 在 Element UI 中使用 `el-checkbox` 组件时,将值为 '是' 和 '否' 的字符串回显为选中状态,核心在于正确绑定 `v-model` 并处理后台返回的字符串数据。`el-checkbox-group` 的 `v-model` 需要绑定到一个数组,该数组包含当前选中的 `label` 值(必须是字符串、数字或布尔类型,不能是对象)[^1]。对于 '是' 和 '否' 的字符串值,你需要将后台返回的单个字符串转换为数组形式,然后设置到 `v-model` 绑定的变量上。以下是详细步骤和示例: #### 实现步骤 1. **定义复选框组**:在模板中,使用 `el-checkbox-group` 包裹两个 `el-checkbox`,分别设置 `label` 属性为 '是' 和 '否',并将 `v-model` 绑定到一个数组变量(如 `selectedOptions`)。 2. **初始化数据**:在 Vue 组件的 `data` 中,定义 `selectedOptions` 为一个空数组,用于存储选中的值。 3. **回显数据处理**:当从后台获取数据时(如编辑模式),将返回的字符串(如 '是' 或 '否')转换为单元素数组,并赋值给 `selectedOptions`。如果后台返回多个值(如逗号分隔字符串),需先分割,但本例中 '是'/'否' 是单个值,直接包装成数组即可[^4]。 4. **显示绑定**:复选框的显示文本(如 "是" 或 "否")通过标签内容(`{{ }}`)自定义,与 `label` 值解耦,确保灵活回显[^2]。 #### 完整代码示例 ```html <template> <div> <el-checkbox-group v-model="selectedOptions"> <el-checkbox label="是">{{ displayText.yes }}</el-checkbox> <el-checkbox label="否">{{ displayText.no }}</el-checkbox> </el-checkbox-group> <p>当前选中值: {{ selectedOptions }}</p> </div> </template> <script> export default { data() { return { selectedOptions: [], // v-model 绑定的数组,存储选中的 label 值 displayText: { yes: "是", no: "否" } // 自定义显示文本,不影响回显逻辑 }; }, methods: { // 模拟从后台获取数据(例如编辑回显) fetchDataFromBackend() { // 假设后台返回的字符串为 '是' 或 '否' const backendData = '是'; // 示例数据,实际中替换为 API 响应 this.selectedOptions = [backendData]; // 将字符串转换为数组 } }, mounted() { this.fetchDataFromBackend(); // 组件加载时触发数据获取 } }; </script> ``` #### 关键解释 - **为什么使用数组**:`el-checkbox-group` 的 `v-model` 必须绑定到数组类型,因为复选框支持多选。即使只有一个值(如 '是'),也需包装为数组(如 `['是']`)[^1][^4]。 - **回显逻辑**:后台返回的字符串(如 '是')通过 `this.selectedOptions = [backendData]` 设置,确保与 `label` 值匹配。如果返回值为空或无效,数组应为空。 - **显示文本自定义**:通过 `{{ displayText.yes }}` 和 `{{ displayText.no }}` 自定义显示内容,与 `label` 值分离,避免混淆(`label` 是实际绑定的值,显示文本是 UI 内容)[^2][^3]。 - **注意事项**:如果 '是' 和 '否' 需要互斥(单选),建议改用 `el-radio-group`;如果必须用复选框,需添加逻辑手动控制单选行为(例如通过 `@change` 事件清空其他选项)。 #### 示例场景 - 后台返回 '是':`selectedOptions` 设置为 `['是']`,第一个复选框选中- 后台返回 '否':`selectedOptions` 设置为 `['否']`,第二个复选框选中- 后台返回空:`selectedOptions = []`,所有复选框未选中。 通过以上步骤,你可以轻松实现字符串值 '是' 和 '否' 的回显绑定。如果遇到复杂数据(如多个值),参考字符串分割方法(如 `split(',')`)[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值