欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue遞歸實現(xiàn)樹形組件

 更新時間:2022年07月15日 11:44:10   作者:南方的森林  
這篇文章主要為大家詳細介紹了vue遞歸實現(xiàn)樹形組件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了vue遞歸實現(xiàn)樹形組件的具體代碼,供大家參考,具體內(nèi)容如下

1. 先來看一下效果:

2. 代碼部分 (myTree.vue)

圖片可以自己引一下自己的圖片,或者使用iconfont的css引入。

<template>
? ? <div class="tree">
? ? ? ? <ul class="ul">
? ? ? ? ? ? <li v-for="(item,index) of treeMenu" :key="index">
? ? ? ? ? ? ? ? <div class="jiantou" @click="changeStatus(index)">
? ? ? ? ? ? ? ? ? ? <img src="../../assets/right.png" v-if="!scopesDefault[index]===true && item.children">
? ? ? ? ? ? ? ? ? ? <img src="../../assets/down.png" v-if="scopesDefault[index]===true && item.children ">
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? ? ? <input type="checkbox" @click="checkBox(item)" v-model="item.check">
? ? ? ? ? ? ? ? <span @click="changeStatus(index)">{{item.label}}</span>
? ? ? ? ? ? ? ? <div class="subtree">
? ? ? ? ? ? ? ? ? ? <tree-menu :treeMenu='item.children' v-if="scopesDefault[index]" @selectnode = "selectnode"></tree-menu>
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? </li> ?
? ? ? ? </ul>?
? ? </div>?
</template>
<script>
?? ?export default{
? ? name:'treeMenu',
? ? ?props:{
? ? ? ? treeMenu:{
? ? ? ? ? ? type:Array,
? ? ? ? ? ? default:[]
? ? ? ? },
? ? },
? ? data(){
? ? ? ? return{
? ? ? ? ? ? scopesDefault: [],
? ? ? ? ? ? scopes: [],?
? ? ? ? ? ? node:[],
? ? ? ? ? ? flatTreeMenu:[],
? ? ? ? ? ? check:'',
? ? ? ? }
? ? },
? ? methods:{
? ? ? ? //展開
? ? ? ? scope() {
? ? ? ? ? ? this.treeMenu.forEach((item, index) => {
? ? ? ? ? ? ? ? this.scopesDefault[index] = false
? ? ? ? ? ? ? ? if ('children' in item) {
? ? ? ? ? ? ? ? ? ? this.scopes[index] = true
? ? ? ? ? ? ? ? ? ? //console.log(item, index)
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? this.scopes[index] = false
? ? ? ? ? ? ? ? }
? ? ? ? ? ? })
? ? ? ? },
? ? ? ? changeStatus(index) {
? ? ? ? ? ? if (this.scopesDefault[index] == true) {
? ? ? ? ? ? ? ? this.$set(this.scopesDefault, index, false)
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? this.$set(this.scopesDefault, index, this.scopes[index])
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? //nodelist 深度優(yōu)先遞歸
? ? ? ? checkBox(node,nodelist=[]){
? ? ? ? ? ? //console.log("start:",node,nodelist)
? ? ? ? ? ? if(node!==null){
? ? ? ? ? ? ? ? nodelist.push(node);
? ? ? ? ? ? ? ? if(node.children){
? ? ? ? ? ? ? ? ? ? let children=node.children;
? ? ? ? ? ? ? ? ? ? for(let i=0;i<children.length;i++){
? ? ? ? ? ? ? ? ? ? ? ? this.checkBox(children[i],nodelist)//遞歸調(diào)用
? ? ? ? ? ? ? ? ? ? ? ? children[i].check = nodelist[0].check==false?true:false;//選中父節(jié)點,子節(jié)點全選,取消,子節(jié)點取消
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? this.node=node;
? ? ? ? ? ? this.check=node.check
? ? ? ? },
? ? ? ? selectnode(node){
? ? ? ? ? ? this.$emit("selectnode",node);
? ? ? ? }
? ? },
? ? watch:{?
? ? ? ? node:{
? ? ? ? ? ? handler(val){
? ? ? ? ? ? ? ? this.selectnode(val);
? ? ? ? ? ? },
? ? ? ? ? ? immediate: true
? ? ? ? },
? ? ? ? check:{
? ? ? ? ? ? handler(val){
? ? ? ? ? ? ? ? this.selectnode(this.node);
? ? ? ? ? ? },
? ? ? ? ? ? immediate: true
? ? ? ? }
? ? },
? ? mounted(){
? ? ? ? this.scope();?
? ? }
}
</script>
<style lang = "scss" scoped>
.tree{
? ? .ul{
? ? ? ? margin: 5px 0 5px 0;
? ? ? ? >li{
? ? ? ? ? ? .jiantou{
? ? ? ? ? ? ? ? display: inline-block;
? ? ? ? ? ? ? ? width: 15px;
? ? ? ? ? ? ? ? >img{
? ? ? ? ? ? ? ? position: relative;
? ? ? ? ? ? ? ? top: 2.0px;
? ? ? ? ? ? ? ? left: 4px;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? .subtree{
? ? ? ? ? ? ? ? margin-left: 20px;
? ? ? ? ? ? ? ? margin-top: 8px;
? ? ? ? ? ? ? ? margin-bottom: 8px;
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
input[type=checkbox]{
? ? visibility: hidden;
? ? cursor: pointer;
? ? position: relative;
? ? width: 15px;
? ? height: 15px;
? ? font-size: 14px;
? ? border: 1px solid #dcdfe6;
? ? background-color: #fff !important;
? ? &::after{
? ? ? ? position: absolute;
? ? ? ? top: 0;
? ? ? ? background-color: #fff;
? ? ? ? border: 1px solid #ddd;
? ? ? ? color: #000;
? ? ? ? width: 15px;
? ? ? ? height: 15px;
? ? ? ? display: inline-block;
? ? ? ? visibility: visible;
? ? ? ? padding-left: 0px;
? ? ? ? text-align: center;
? ? ? ? content: ' ';
? ? ? ? border-radius: 3px;
? ? ? ? transition: all linear .1s;
? ? }
? ? &:checked::after{
? ? ? ? content: "\2713";
? ? ? ? font-size: 12px;
? ? ? ? background-color: #409eff;
? ? ? ? border: 1px solid #409eff;
? ? ? ? transition: all linear .1s;
? ? ? ? color: #fff;
? ? ? ? font-weight: bold;
? ? }
}
.check{
? ? &:checked::after{
? ? ? ? content: "--" !important;
? ? }
}
</style>

講解:

1、調(diào)用組件:

我這用來一個global.js來控制組件的使用(這個js附在文章末尾了),在component文件夾中建立一個myTree文件夾,里面放同名vue文件(myTree.vue),這樣無論在哪里調(diào)用這個組件,都可以直接使用<my-tree></my-tree>的方式去調(diào)用。

2、組件的方法:

scope():會生成一個數(shù)組,里面有根節(jié)點是否有子節(jié)點,如本代碼里設定的數(shù)據(jù),會有scopes=[true,true,true]這樣的結果。
changeStatus():每點擊標題或者箭頭,如果當前下標的節(jié)點有沒有子節(jié)點,再將結果動態(tài)賦值給scopesDefault[index],將這個值放于dom上控制開關,遞歸組件。
checkBox():在組件內(nèi)部實現(xiàn)了點擊全選、點擊取消全選的功能,遞歸調(diào)用當前方法,將子元素的狀態(tài)隨父元素一起變化。
selectnode():將當前點擊的node的節(jié)點內(nèi)容上傳到父組件。

3、監(jiān)聽:

同時監(jiān)聽:不同節(jié)點的切換、同一個節(jié)點的是否選中的切換,監(jiān)聽得到的結果都傳到父組件中。

4、組件遞歸:調(diào)用時與父組件相同

3. 使用組件(useMyTree.vue)

<template>
? ? <div class = "loginModuel">
? ? ? ? <my-tree :treeMenu='tree' @selectnode="selectnode"></my-tree>
? ? </div>
</template>
<script>
export default{
? ? data(){
? ? ? ? return{
? ? ? ? ? ? msg:"這是登錄頁面",
? ? ? ? ? ? tree:[
? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? id:1,
? ? ? ? ? ? ? ? ? ? label:"1級目錄1",
? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? children:[
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"1-1",
? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"1.1目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false
? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"1-2",
? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"1.2目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false
? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"1-3",
? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"1.3目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false
? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? id:2,
? ? ? ? ? ? ? ? ? label:"1級目錄2",
? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? children:[
? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? id:"2-1",
? ? ? ? ? ? ? ? ? ? ? ? ? label:"2.1目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? ? ? ? pid:2,
? ? ? ? ? ? ? ? ? ? ? ? ? children:[
? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"2-1-1",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:'2-1',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"2.1.1目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? children:[
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"2-1-1-1",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:'2-1-1',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"2.1.1.1目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? children:[
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"2-1-1-1-1",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:'2-1-1-1',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"2.1.1.1.1目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"2-1-1-1-2",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:'2-1-1-1',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"2.1.1.1.2目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"2-1-2",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:'2-1',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"2.1.2目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"2-1-3",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:'2-1',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"2.1.3目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? id:"2-2",
? ? ? ? ? ? ? ? ? ? ? ? ? pid:2,
? ? ? ? ? ? ? ? ? ? ? ? ? label:"2.2目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? check:false
? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? ? },//在此繼續(xù)添加目錄
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? id:3,
? ? ? ? ? ? ? ? label:"1級目錄3",
? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? children:[
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? id:"3-1",
? ? ? ? ? ? ? ? ? ? ? ? pid:3,
? ? ? ? ? ? ? ? ? ? ? ? label:"3.1目錄",
? ? ? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? ? ? children:[
? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"3-1-1",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:"3-1",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"3.1.1目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? children:[
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"3-1-1-1",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:"3-1-1",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"3.1.1.1目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? children:[
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id:"3-1-1-1-1",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pid:"3-1-1-1",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? label:"3.1.1.1.1目錄",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? check:false
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? ? ? ]
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ]
? ? ? ? ? ? },
? ? ? ? ? ? ],
? ? ? ? ? ? plist:[],//此級以上所有父節(jié)點列表
? ? ? ? ? ? flatTree:[],//tree的平行數(shù)據(jù)
? ? ? ? ? ? node:'',//當前點擊的node,
? ? ? ? }
? ? },
? ? methods:{
? ? ? ? //將tree樹形數(shù)據(jù)轉(zhuǎn)換為平行數(shù)據(jù)
? ? ? ? transformData(tree){
? ? ? ? ? ? tree.forEach(item=>{
? ? ? ? ? ? ? ? this.flatTree.push(item);
? ? ? ? ? ? ? ? item.children && item.children.length>0 ? this.transformData(item.children) : ""
? ? ? ? ? ? })
? ? ? ? },
? ? ? ? //子組件傳遞過來的點擊的node的值
? ? ? ? selectnode(node){
? ? ? ? ? ? this.node=node;
? ? ? ? ? ? this.flatTree=[];
? ? ? ? ? ? this.transformData(this.tree);
? ? ? ? ? ? if(node.check==false){//這個節(jié)點已經(jīng)被選中,正在點擊取消選中
? ? ? ? ? ? ? ? this.plist=[];//每次點擊一個新的節(jié)點都將原來plist的內(nèi)容清空
? ? ? ? ? ? ? ? this.getParentnode(this.flatTree,node.pid)
? ? ? ? ? ? }else{//正在選中
? ? ? ? ? ? ? ? this.childAllToParent(node,this.flatTree,1);
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? //子節(jié)點取消選中,拿到此子節(jié)點所有的父節(jié)點plist
? ? ? ? getParentnode(tree,pid){
? ? ? ? ? ? //this.plist=[]
? ? ? ? ? ? if(pid!==null){
? ? ? ? ? ? ? ? tree.forEach(item=>{
? ? ? ? ? ? ? ? ? ? if(item.id==pid){
? ? ? ? ? ? ? ? ? ? ? ? this.plist.push(item)
? ? ? ? ? ? ? ? ? ? ? ? this.getParentnode(this.flatTree,item.pid)
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? })
? ? ? ? ? ? }?
? ? ? ? ? ? if(!pid){
? ? ? ? ? ? ? ? this.plist.forEach(item=>{
? ? ? ? ? ? ? ? ? ? this.updateParentCheck(this.tree,item)
? ? ? ? ? ? ? ? })
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? //將原數(shù)據(jù)tree對應id的項的check值改為false
? ? ? ? updateParentCheck(tree,plistItem){
? ? ? ? ? ? //console.log("方法updateParentCheck接收的plistItem參數(shù):",plistItem)
? ? ? ? ? ? tree.forEach(item=>{
? ? ? ? ? ? ? ? if(item.id==plistItem.id){
? ? ? ? ? ? ? ? ? ? item.check=false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if(item.id!==plistItem.id && item.children){
? ? ? ? ? ? ? ? ? ? this.updateParentCheck(item.children,plistItem)
? ? ? ? ? ? ? ? }
? ? ? ? ? ? })
? ? ? ? },
? ? ? ? //子節(jié)點全部選中后父節(jié)點選中
? ? ? ? childAllToParent(node,flatTree,j){
? ? ? ? ? ? let fatherNode='';
? ? ? ? ? ? let brotherNode=[];
? ? ? ? ? ? this.flatTree.forEach(item=>{
? ? ? ? ? ? ? ? if(node.pid && node.pid==item.id){
? ? ? ? ? ? ? ? ? ? fatherNode=item;//找到了父節(jié)點--用于改變check的值
? ? ? ? ? ? ? ? }
? ? ? ? ? ? })
? ? ? ? ? ? //判斷該結點所有的兄弟節(jié)點是否全部選中
? ? ? ? ? ? flatTree.forEach(item=>{
? ? ? ? ? ? ? ? if(item.pid && node.pid && item.pid==node.pid){
? ? ? ? ? ? ? ? ? ? brotherNode.push(item)//找到所有的兄弟節(jié)點
? ? ? ? ? ? ? ? }
? ? ? ? ? ? })
? ? ? ? ? ? //i為被選中的兄弟節(jié)點的個數(shù)
? ? ? ? ? ? let i=0;
? ? ? ? ? ? this.flatTree.forEach(item=>{
? ? ? ? ? ? ? ? if(node.pid==item.pid && item.check==true){
? ? ? ? ? ? ? ? ? ? i=i+1;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? })
? ? ? ? ? ? //修改父節(jié)點的選中值
? ? ? ? ? ? if(i==brotherNode.length && fatherNode){
? ? ? ? ? ? ? ? fatherNode.check=true
? ? ? ? ? ? }
? ? ? ? ? ? // console.log(`第j次遞歸 j=${j}`)
? ? ? ? ? ? // console.log(`選中的bro=${i},brother的個數(shù):${brotherNode.length}`)
? ? ? ? ? ? // console.log("父節(jié)點:",fatherNode,"兄弟節(jié)點",brotherNode)
? ? ? ? ? ? if(fatherNode.pid!==undefined){
? ? ? ? ? ? ? ? j=j+1;
? ? ? ? ? ? ? ? this.childAllToParent(fatherNode,this.flatTree,j)
? ? ? ? ? ? }
? ? ? ? }
? ? },
? ? mounted(){
? ? ? ? this.transformData(this.tree);//數(shù)據(jù)初始化:將tree樹形數(shù)據(jù)轉(zhuǎn)換為平行數(shù)據(jù)
? ? ? ? //console.log(this.flatTree)
? ? }
}
</script>
<style lang = "scss" scoped>
.loginModuel{
? ? margin-left: 400px;
? ? margin-top: 100px;
? ? .tree{
? ? ? ? .ul{
? ? ? ? ? ? >li{
? ? ? ? ? ? ? ? margin: 5px 0 5px 0;
? ? ? ? ? ? ? ? >img{
? ? ? ? ? ? ? ? ? ? position: relative;
? ? ? ? ? ? ? ? ? ? top: 2.4px;
? ? ? ? ? ? ? ? ? ? left: 4px;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? .ul2{
? ? ? ? ? ? ? ? >li{
? ? ? ? ? ? ? ? ? ? position: relative;
? ? ? ? ? ? ? ? ? ? left: 20px;
? ? ? ? ? ? ? ? ? ? margin: 5px 0 5px 0;
? ? ? ? ? ? ? ? ? ? >img{
? ? ? ? ? ? ? ? ? ? ? ? //transition: all ease-in-out 1s;
? ? ? ? ? ? ? ? ? ? ? ? position: relative;
? ? ? ? ? ? ? ? ? ? ? ? top: 2.4px;
? ? ? ? ? ? ? ? ? ? ? ? left: 4px;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
}

input[type=checkbox]{
? ? cursor: pointer;
? ? position: relative;
? ? width: 15px;
? ? height: 15px;
? ? font-size: 14px;
? ? border: 1px solid #dcdfe6;
? ? background-color: #fff !important;
? ? &::after{
? ? ? ? position: absolute;
? ? ? ? top: 0;
? ? ? ? background-color: #fff;
? ? ? ? border: 1px solid #ddd;
? ? ? ? color: #000;
? ? ? ? width: 15px;
? ? ? ? height: 15px;
? ? ? ? display: inline-block;
? ? ? ? visibility: visible;
? ? ? ? padding-left: 0px;
? ? ? ? text-align: center;
? ? ? ? content: ' ';
? ? ? ? border-radius: 3px;
? ? ? ? transition: all linear .1s;
? ? }
? ? &:checked::after{
? ? ? ? content: "?";
? ? ? ? font-size: 12px;
? ? ? ? background-color: #409eff;
? ? ? ? border: 1px solid #409eff;
? ? ? ? transition: all linear .1s;
? ? ? ? color: #fff;
? ? ? ? font-weight: bold;
? ? }
}
</style>

子組件主要是實現(xiàn)全選和取消全選。由于遞歸組件的原因,子組件拿不到完整的數(shù)據(jù),所以接下來的兩個功能:全選后某一個子節(jié)點取消選中則父節(jié)點取消選中、子節(jié)點全選后父節(jié)點自覺選中的功能就要在父組件中完成了。

講解:

1、設值:

樹形數(shù)據(jù)必須有pid屬性,用于向上遍歷。

2、方法:

transformData():將層級數(shù)據(jù)轉(zhuǎn)為平行數(shù)據(jù),避免后期不停的遞歸調(diào)用消耗時間,平級數(shù)據(jù)使用一般的循環(huán)即可完成。
selectnode():由子組件傳遞過來的方法,大致分為兩個方向:選中、取消選中。選中時實現(xiàn)功能一:子節(jié)點全選后父節(jié)點自覺選中;取消選中實現(xiàn)功能二:全選后某一個子節(jié)點取消選中則父節(jié)點取消選中。
getParentnode():用于實現(xiàn)功能二。子節(jié)點取消選中后,根據(jù)pid,將在它上面級別的所有父節(jié)點列表拿到,再由方法updateParentCheck()將父節(jié)點的check值全部改為false。
childAllToParent():用于實現(xiàn)功能一。遞歸調(diào)用該方法,將操作節(jié)點的父節(jié)點拿到,根據(jù)兄弟節(jié)點有相同的pid,拿到兄弟節(jié)點的個數(shù),如果兄弟節(jié)點中被選中的個數(shù)等于兄弟節(jié)點的個數(shù),則修改父節(jié)點的check值為true,直到到了根節(jié)點結束遞歸。

  • 這個組件實現(xiàn)起來不是很難,只要是心細就能很好的完成。
  • 如果后期需要使用某些數(shù)據(jù)的話,直接掛到data里就可以。
  • 如果有更好的方法或者存在某些疑問,歡迎小伙伴留言!

附: (global.js => 放于component文件夾下)

import Vue from 'vue';

function capitalizeFirstLetter(string){
? ? return string.charAt(0).toUpperCase() + string.slice(1);
}
const requireComponent = require.context(
? ? '.',true,/\.vue$/
? ? //找到components文件夾下以.vue命名的文件
)
requireComponent.keys().forEach(fileName => {
? ? const componetConfig = requireComponent(fileName);
? ? let a = fileName.lastIndexOf('/');
? ? fileName = '.' + fileName.slice(a);
? ? const componetName = capitalizeFirstLetter(
? ? ? ? fileName.replace(/^\.\//,'').replace(/\.\w+$/,'')
? ? )
? ? Vue.component(componetName,componetConfig.default || componetConfig)
})
  • 由此其實可以實現(xiàn)很多遞歸組件,如側(cè)邊欄。
  • 下面我放一個自己寫的側(cè)邊欄的動圖,方法比這個樹形組件要簡單些,畢竟不用考慮復選框的值。感興趣的小伙伴們可以試著實踐一下

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 詳解win7 cmd執(zhí)行vue不是內(nèi)部命令的解決方法

    詳解win7 cmd執(zhí)行vue不是內(nèi)部命令的解決方法

    這篇文章主要介紹了詳解win7 cmd執(zhí)行vue不是內(nèi)部命令的解決方法的相關資料,這里提供了解決問題的詳細步驟,具有一定的參考價值,需要的朋友可以參考下
    2017-07-07
  • vue中的事件觸發(fā)(emit)及監(jiān)聽(on)問題

    vue中的事件觸發(fā)(emit)及監(jiān)聽(on)問題

    這篇文章主要介紹了vue中的事件觸發(fā)(emit)及監(jiān)聽(on)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Vue3中#default=“scope”的使用

    Vue3中#default=“scope”的使用

    在Vue3中,我們經(jīng)常會遇到需要處理列表渲染的情況,Vue3引入了一種新的語法,即#default=“scope”,本文就來介紹一下Vue3中#default=“scope”的使用,感興趣的可以了解一下
    2023-10-10
  • vue修改對象的屬性值后頁面不重新渲染的實例

    vue修改對象的屬性值后頁面不重新渲染的實例

    今天小編就為大家分享一篇vue修改對象的屬性值后頁面不重新渲染的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • vue基礎之詳解ElementUI的表單

    vue基礎之詳解ElementUI的表單

    這篇文章主要為大家詳細介紹了vue基礎之ElementUI的表單,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • 關于vue-admin-element中的動態(tài)加載路由

    關于vue-admin-element中的動態(tài)加載路由

    這篇文章主要介紹了關于vue-admin-element的動態(tài)加載路由,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue引用echarts餅圖不顯示圖例的解決

    vue引用echarts餅圖不顯示圖例的解決

    這篇文章主要介紹了vue引用echarts餅圖不顯示圖例的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 在Vue項目中用fullcalendar制作日程表的示例代碼

    在Vue項目中用fullcalendar制作日程表的示例代碼

    這篇文章主要介紹了在Vue項目中用fullcalendar制作日程表,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • unplugin-auto-import的配置以及eslint報錯解決詳解

    unplugin-auto-import的配置以及eslint報錯解決詳解

    unplugin-auto-import?解決了vue3-hook、vue-router、useVue等多個插件的自動導入,也支持自定義插件的自動導入,是一個功能強大的typescript支持工具,這篇文章主要給大家介紹了關于unplugin-auto-import的配置以及eslint報錯解決的相關資料,需要的朋友可以參考下
    2022-08-08
  • 一文搞定vue3中的函數(shù)式彈窗

    一文搞定vue3中的函數(shù)式彈窗

    函數(shù)式彈窗是一種使用函數(shù)來創(chuàng)建彈窗的技術,它可以簡化彈窗的使用,只需要在需要彈窗的地方調(diào)用函數(shù)就可以了,下面我們就來看看vue3中函數(shù)式彈窗的具體應用吧
    2024-01-01

最新評論