摘要:近期項(xiàng)目用到大量的樹結(jié)構(gòu),比如目錄樹文章標(biāo)記動(dòng)態(tài)生成樹結(jié)構(gòu),實(shí)現(xiàn)的過程是基于的框架,結(jié)合數(shù)據(jù)驅(qū)動(dòng)應(yīng)用遞歸函數(shù)實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)的增刪改查一切思緒的來(lái)源,結(jié)合官方提供的樹形圖實(shí)例,可以輕松實(shí)現(xiàn)自定義開源樹結(jié)構(gòu),上優(yōu)秀的開源插件我都看過,都是基于樹形
近期項(xiàng)目用到大量的樹結(jié)構(gòu),比如目錄樹、文章標(biāo)記動(dòng)態(tài)生成樹結(jié)構(gòu),實(shí)現(xiàn)的過程是基于vue的框架,結(jié)合vue數(shù)據(jù)驅(qū)動(dòng)應(yīng)用遞歸函數(shù)實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)的增刪改查
一切思緒的來(lái)源,結(jié)合vue官方提供的樹形圖實(shí)例,可以輕松實(shí)現(xiàn)自定義開源樹結(jié)構(gòu),github上優(yōu)秀的開源插件我都看過,都是基于樹形結(jié)構(gòu)實(shí)現(xiàn)的
vue樹形視圖
以上是定義模板以及在頁(yè)面中應(yīng)用,首先遍歷treedata把單項(xiàng)傳入子組件也就是本例的模板,下面js文件
// 定義子組件 Vue.component("item", { template: "#item-template", props: { model: Object, }, data: function () { return { openr:false, } }, computed: { isFolder: function () { return this.model.children && this.model.children.length; } }, methods: { //獲取選中節(jié)點(diǎn)數(shù)據(jù) toggle(model){ if (this.isFolder) { vm.$set(model, "isExpand", !model.isExpand); } }, //獲取選中節(jié)點(diǎn)數(shù)據(jù)以及設(shè)置選中狀態(tài) handle (item) { this.emitHandle(item) console.log(item) var nodeId; if (event.path[0].id) { nodeId = event.path[0].id; } else if(event.path[1].id){ nodeId = event.path[1].id; } else{ nodeId = event.path[2].id; } setMouseMenu(nodeId,".treeMenu"); }, emitHandle (item) { this.$emit("handle", item) } } }) // 定義父組件 var vm = new Vue({ el: "#bookMarker", data: { templateName:"",//內(nèi)容模板 associations:"",//癥狀關(guān)系 elements:"", //模板下elements數(shù)組 allIsExpand: true, dialogTit:"", //彈框的title getRangeText:"",//標(biāo)引選中的文本 resultName:"",//彈框input值 elementId:"", elementType:"", orderNum:"", postArray:[], off:false, radio:"", scrollTop:0,//codemirror滾動(dòng)條高度 height:"",//codemirror內(nèi)容高度 oldContent:"",//子組件自定義title屬性數(shù)據(jù) associationsElements:"", ariaHidden:true,//語(yǔ)義彈框顯隱控制 ztreeData:[],//ztree的數(shù)據(jù)列表 }, created(){ this.getMarkerList(); this.getTemplateInfo(); }, mounted(){ this.initView(); this.setCodeMenu(); setActiveClass(); $("body").click(()=>{ this.oldContent=""; }) setTreeFoundation(this.$refs.treebox, this.$refs.treeFoundation); }, watch:{ "ztreeData":{ handler: function(val, oldval) { this.$nextTick(() => { this.$refs.treeMenu.style.display="none" }) }, deep: true } }, methods:{ // 獲取選中節(jié)點(diǎn) setSelectedNode(model){ this.off = true; var g=function(child){ child.forEach(function (item, index) { if (item.Selected==true) { vm.$set(item, "Selected", false) } var subChild = item.children; if(subChild!=null && subChild.length>0){ g(subChild); } }); } this.ztreeData.forEach(function (item, index) { if (item.Selected==true) { vm.$set(item, "Selected", false) } var child =item.children; g(child); }); vm.$set(model, "Selected", true) this.onCodemirrorLight(model); }, getSelectedNode () { var roots = []; var model; this.ztreeData.forEach(function(item,index){ if(item.parentId ==0){ roots.push(item); } }); var g=function(child){ child.forEach(function (item, index) { if (item.Selected==true) { model=item; return; } var subChild = item.children; if(subChild!=null && subChild.length>0){ g(subChild); } }); } roots.forEach(function (item, index) { if (item.Selected==true) { model=item; return; } var child =item.children; g(child); }); return model; }, //獲取模態(tài)框title getDialogTitle: function(item){ this.dialogTit=""; this.dialogChilTit=""; if (this.getRangeText) { this.dialogTit = item.elementName||item.associationName; this.orderNum=item.orderNum; this.elementId=item.elementId; this.elementType=item.elementType; event.target.dataset.toggle="modal"; } else{ event.target.dataset.toggle=""; } }, //全部折疊 allClose(){ this.updateAllIsExpand(false); this.allIsExpand = true; }, //全部展開 allOpen(){ this.updateAllIsExpand(true); this.allIsExpand = false; }, //刪除節(jié)點(diǎn) removeNode(){ var item = this.getSelectedNode() var index=0; if (item.parentId==0) { for(var i in this.ztreeData){ if(this.ztreeData[i]["id"]==item.id){ index=i; break; } } this.ztreeData.splice(index,1); } else{ var parentItem = this.getNodeItem(item.parentId).children; parentItem.splice(parentItem.indexOf(item), 1); } //重置選中狀態(tài) $("div").removeClass("activeClass"); }, //codemirror鼠標(biāo)右鍵菜單 setCodeMenu(){ var doc = document.getElementById("box_fr"); var forRight = $(".codeMenu") var _this = this; doc.oncontextmenu=function(event){//關(guān)鍵點(diǎn) var event=event||window.event; if (_this.getRangeText) { forRight.get(0).style.display="block"; forRight.get(0).style.left=event.pageX+"px"; forRight.get(0).style.top=event.pageY+"px"; return false; } }; doc.onclick=function(e){ forRight.get(0).style.display= "none"; e.preventDefault(); }; }, //設(shè)置語(yǔ)義關(guān)聯(lián) setAssociation(item){ this.resultName = item.elementName; this.Submit(); }, //全部展開收起公共方法 updateAllIsExpand(boolean){ var g=function(child,expand){ child.forEach(function (item, index) { var childisExpand; childisExpand = vm.$set(item, "isExpand", expand); var subChild = item.children; if(subChild!=null && subChild.length>0){ g(subChild,childisExpand); } }); } if (this.off==true) { var item = this.getSelectedNode() if (item) { var expand; expand = vm.$set(item, "isExpand", boolean); var child =item.children; g(child,expand); } } else{ this.ztreeData.forEach((ite)=>{ var expand; expand = vm.$set(ite, "isExpand", boolean); var child =ite.children; g(child,expand); }) } }, //獲取結(jié)構(gòu)模板信息 getTemplateInfo: function(){ this.$ajax({ method: "post", url: "/marker/api/getTemplateInfo", data: { taskId:19 } }).then((res)=>{ if (res.data.code === 1000) { this.elements = res.data.data.elements; this.associations = res.data.data.associations; this.templateName = res.data.data.templateName; res.data.data.associations.forEach((item)=>{ this.associationsElements = item.elements }) console.log(res.data.data,"getTemplete"); } },(err)=>{ console.log(err); }) }, //獲取根節(jié)點(diǎn)id getRoot(){ this.off=false; }, //獲取樹結(jié)構(gòu)列表 getMarkerList: function(){ this.$ajax({ method: "post", url: "/marker/api/getMarkerList", data: { taskId:19 } }).then((res)=>{ if (res.data.code === 1000) { if (res.data.data==null) {return}; this.ztreeData = res.data.data; var roots = []; this.ztreeData.forEach(function(item,index){ if(item.parentId ==0){ roots.push(item); } }); var g=function(child,level,isExpand,Selected){ var childLevel=level+1; var childisExpand = isExpand; var childSelected = Selected; child.forEach(function (item, index) { item.level=childLevel; vm.$set(item, "isExpand", childisExpand) vm.$set(item, "Selected", childSelected) var subChild = item.children; if(subChild!=null && subChild.length>0){ g(subChild,childLevel,childisExpand,childSelected); } }); } roots.forEach(function (item, index) { item.level= 0 ; vm.$set(item, "isExpand", false) vm.$set(item, "Selected", false) var child =item.children; g(child, item.level, item.isExpand, item.Selected); }); console.log(res.data,"getMarkerList"); } },(err)=>{ console.log(err); }) }, //通過resultId獲取item getNodeItem:function(resultId){ var resultItem = {}; var g=function(child,resultId){ child.forEach(function (item) { if (item.resultId==resultId) { resultItem = item; return; } var subChild = item.children; if(subChild!=null && subChild.length>0){ g(subChild,resultId); } }); } this.ztreeData.forEach((item)=>{ var child = item.children; if (item.resultId==resultId) { resultItem = item; return; } g(child, resultId); }) return resultItem; }, //codemirror滾動(dòng)到頂部 goDocUp(){ this.CodeMirrorEditor.scrollTo(0,0) }, //codemirror滾動(dòng)到底部 goDocDown(){ var initH = 5000 this.CodeMirrorEditor.scrollTo(0,this.height+ initH+ this.scrollTop) }, //codemirror顯示高亮 onCodemirrorLight:function(item){ if (!item) {return}; var startPos = item.startPos, endPos = item.endPos, strat, end; //將返回_index轉(zhuǎn)為Pos對(duì)象 strat = this.posFromIndex(startPos-1); end = this.posFromIndex(endPos-1); //文本高亮 this.CodeMirrorEditor.setSelection(strat,end); // this.CodeMirrorEditor.scrollTo(0,item.scrollTop) // this.CodeMirrorEditor.setValue(model.oldContent) }, //提交用戶操作 Submit:function(){ var parentId,level,Selected,isExpand; if (this.off==true) { var item = this.getSelectedNode(); if (item) { parentId = item.resultId; level = item.level+1; Selected = item.Selected; isExpand = item.isExpand } } else{ parentId = 0; level = 0; Selected = false; isExpand = false; } if (!this.resultName) { alert("請(qǐng)?zhí)顚憳?biāo)題");return event.target.dataset.dismiss=""}; var _data = { taskId:19, parentId:parentId, startPos:this.postArray[0], endPos:this.postArray[1], resultName:this.resultName, elementId:this.elementId, elementType:this.elementType, orderNum:this.orderNum, oldContent:this.getRangeText, level:level, children:[], Selected:Selected, isExpand:isExpand, }; this.$ajax({ method: "post", url: "/marker/api/save", data: _data }).then((res)=>{ if (res.data.code === 1000) { $("#myModal").modal("hide") //結(jié)合接口返回設(shè)置_data數(shù)據(jù) this.resultName = ""; this.allIsExpand = true; this.$refs.codeMenu.style.display="none"; _data.resultId = res.data.data; if(parentId == 0){ this.ztreeData.push(_data); // console.log(JSON.parse(JSON.stringify(this.ztreeData)),"追加以后ztreeData") } else{ item.children.push(_data); vm.$set(item, "isExpand", true); } console.log(JSON.parse(JSON.stringify(this.ztreeData)),"追加以后ztreeData"); } },(err)=>{ console.log(err); }) }, //用戶取消操作 Cancel:function(){ this.resultName=""; this.getRangeText=""; }, //初始化頁(yè)面結(jié)構(gòu)以及數(shù)據(jù) initView: function(){ //獲取右側(cè)文章 this.$ajax({ method: "post", url: "/marker/api/getFullText", data: { taskId:19 } }).then((res)=>{ if (res.data.code === 1000) { this.CodeMirrorEditor.setValue(res.data.data); } },(err)=>{ console.log(err); }) //初始化codemirror let myTextarea = document.getElementById("editor"); this.CodeMirrorEditor = CodeMirror.fromTextArea(myTextarea, { lineWrapping :true, styleActiveLine: true, foldGutter: true, styleSelectedText: true, mode: "text/javascript", matchBrackets: true, cursorScrollMargin:120,//光標(biāo)上下預(yù)留額外空間 showCursorWhenSelecting: true, theme: "default", }); // 光標(biāo)或選中(內(nèi)容)事件 this.cursorActivity(); // 記錄內(nèi)容改變事件 this.CodeMirrorEditor.on("change",(instance,changeObj)=>{ console.log("change",instance,changeObj) this.height = instance.doc.height; }); //記錄滾動(dòng)事件 this.CodeMirrorEditor.on("scroll",(cm)=>{ this.scrollTop = cm.doc.scrollTop }); }, //設(shè)置resultName setResultName(event){ this.resultName = getSelectText(event); }, //根據(jù)Pos轉(zhuǎn)為數(shù)字下標(biāo) indexFromPos: function(Pos) { if(Pos.line < 0 || Pos.ch < 0) { return false; } var _index= Pos.ch+1; this.CodeMirrorEditor.eachLine(0, Pos.line, function(item){ _index+= item.text.length+1; }) return _index; }, //根據(jù)數(shù)字下標(biāo)轉(zhuǎn)為Pos posFromIndex: function(_index) { var line = 0, ch; this.CodeMirrorEditor.eachLine(0, this.CodeMirrorEditor.lineCount(), function(item) { var textNum = item.text.length + 1; if(textNum > _index) { ch = _index; return true; } else{ _index -= textNum; ++line; } }); return({ line: line, ch: ch }) }, // 光標(biāo)或選中(內(nèi)容)事件 cursorActivity(){ this.CodeMirrorEditor.on("cursorActivity",(cm)=>{ var startObj = {}, endObj = {}, objArray = [], newObjArray = [], activeArray = []; //拖動(dòng)鼠標(biāo)開始位置結(jié)束位置,支持正反選 endObj.line = cm.getCursor("head").line; endObj.ch = cm.getCursor("head").ch; startObj.line = cm.getCursor("anchor").line; startObj.ch = cm.getCursor("anchor").ch; objArray.push(startObj,endObj); // 保存開始結(jié)束位置數(shù)字下標(biāo) newObjArray.push(this.indexFromPos(startObj),this.indexFromPos(endObj)); newObjArray.sort((x,y)=>{ return x-y; }) this.postArray = newObjArray; //根據(jù)Pos獲取選中文本 sortPosArray(objArray); this.getRangeText = cm.getRange(objArray[0],objArray[1]); }); } } }); /*** ***dom.js*** ***/ //設(shè)置選中active狀態(tài) function setActiveClass(){ $(document).on("click",".menuLi>div", function(){ $(".treeFoundation").removeClass("activeClass") $("div").removeClass("activeClass"); $(this).addClass("activeClass"); }) $(document).on("click",".item>div", function(){ $("div").removeClass("activeClass"); $(".treeFoundation").removeClass("activeClass") $(this).addClass("activeClass"); }) $(".treeFoundation").click(function(){ $(this).addClass("activeClass") $(".sidebar-menu div").removeClass("activeClass"); }) }; //鼠標(biāo)右鍵菜單 function setMouseMenu(target, cursorClass){ if (!target||target==null||!cursorClass) {return} var doc = document.getElementById(target); var forRight = $(cursorClass) doc.oncontextmenu=function(event){//關(guān)鍵點(diǎn) var event=event||window.event; forRight.get(0).style.display="block"; forRight.get(0).style.left=event.pageX+"px"; forRight.get(0).style.top=event.pageY+"px"; return false; }; doc.onclick=function(e){ forRight.get(0).style.display="none"; e.preventDefault(); }; }; //根據(jù)codemirror對(duì)Pos下標(biāo)排序 function sortPosArray(PosArray){ PosArray.sort((c1, c2) => { if (c1.ch == c2.ch) { return c1.line - c2.line } else if (c1.line>c2.line) { return c1.line - c2.line } else if(c1.line{ if (parent.scrollTop>=90) { child.style.position="fixed"; child.style.width=47.5+"%"; child.style.zIndex=2; child.style.boxShadow="0px 1px 1px #d9d9d9"; } else{ child.style.position="static"; child.style.width="auto"; child.style.boxShadow="none"; } }, false) };
var roots = []; this.ztreeData.forEach(function(item,index){ if(item.parentId ==0){ roots.push(item); } }); var g=function(child,level,isExpand,Selected){ var childLevel=level+1; var childisExpand = isExpand; var childSelected = Selected; child.forEach(function (item, index) { item.level=childLevel; vm.$set(item, "isExpand", childisExpand) vm.$set(item, "Selected", childSelected) var subChild = item.children; if(subChild!=null && subChild.length>0){ g(subChild,childLevel,childisExpand,childSelected); } }); } roots.forEach(function (item, index) { item.level= 0 ; vm.$set(item, "isExpand", false) vm.$set(item, "Selected", false) var child =item.children; g(child, item.level, item.isExpand, item.Selected); });
以上是遞歸函數(shù)的應(yīng)用,很實(shí)用可以解決很多后端的問題
另外說(shuō)一嘴,解決遞歸組件事件傳遞的方法有很多,比如事件車,本實(shí)例之初也用到了事件車,因?yàn)榇a設(shè)計(jì)的要求換了另一種實(shí)現(xiàn)的方式,心細(xì)的朋友多看幾遍就會(huì)發(fā)現(xiàn)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/98210.html
摘要:像剛才的這幅圖,就是二叉搜索樹。而我們本文要學(xué)習(xí)的內(nèi)容,就是如何寫一個(gè)二叉搜索樹。但在二叉搜索樹中,我們把節(jié)點(diǎn)成為鍵,這是術(shù)語(yǔ)。前端路漫漫,且行且歌的前端樂園原文鏈接寒假前端學(xué)習(xí)學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法四二叉搜索樹 本系列的第一篇文章: 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(一),棧與隊(duì)列第二篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(二):鏈表第三篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)...
摘要:詢問權(quán)威的服務(wù)器域名服務(wù)器會(huì)繼續(xù)檢查請(qǐng)求的下一部分,并將查詢指向負(fù)責(zé)此特定域名的服務(wù)器這些權(quán)威的服務(wù)器將負(fù)責(zé)了解關(guān)于特定域的所有信息,并將信息存儲(chǔ)在記錄。 面試經(jīng)典題——URL加載 一、涉及基本知識(shí)點(diǎn): 1. 計(jì)算機(jī)網(wǎng)絡(luò) 五層因特爾協(xié)議棧: 應(yīng)用層(dns、http):DNS解析成IP并完成http請(qǐng)求發(fā)送; 傳輸層(tcp、udp):三次握手四次揮手模式建立tcp連接; 網(wǎng)絡(luò)層...
摘要:詢問權(quán)威的服務(wù)器域名服務(wù)器會(huì)繼續(xù)檢查請(qǐng)求的下一部分,并將查詢指向負(fù)責(zé)此特定域名的服務(wù)器這些權(quán)威的服務(wù)器將負(fù)責(zé)了解關(guān)于特定域的所有信息,并將信息存儲(chǔ)在記錄。 面試經(jīng)典題——URL加載 一、涉及基本知識(shí)點(diǎn): 1. 計(jì)算機(jī)網(wǎng)絡(luò) 五層因特爾協(xié)議棧: 應(yīng)用層(dns、http):DNS解析成IP并完成http請(qǐng)求發(fā)送; 傳輸層(tcp、udp):三次握手四次揮手模式建立tcp連接; 網(wǎng)絡(luò)層...
閱讀 1630·2023-04-25 18:19
閱讀 2078·2021-10-26 09:48
閱讀 1079·2021-10-09 09:44
閱讀 1731·2021-09-09 11:35
閱讀 3027·2019-08-30 15:54
閱讀 2021·2019-08-30 11:26
閱讀 2285·2019-08-29 17:06
閱讀 884·2019-08-29 16:38