国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

vue遞歸組件實(shí)戰(zhàn)之簡(jiǎn)單樹形控件實(shí)例代碼

2019-11-19 10:57:09
字體:
供稿:網(wǎng)友

1、遞歸組件-簡(jiǎn)單樹形控件預(yù)覽及問題

 

在編寫樹形組件時(shí)遇到的問題:

  • 組件如何才能遞歸調(diào)用?
  • 遞歸組件點(diǎn)擊事件如何傳遞?

2、樹形控件基本結(jié)構(gòu)及樣式

<template> <ul class="vue-tree">  <li class="tree-item">   <div class="tree-content"><!--節(jié)點(diǎn)內(nèi)容-->    <div class="expand-arrow"></div><!--展開或收縮節(jié)點(diǎn)按鈕-->    <div class="tree-label">小學(xué)</div><!--節(jié)點(diǎn)文本內(nèi)容-->   </div>   <ul class="sub-tree"><!--子節(jié)點(diǎn)-->    <li class="tree-item expand">     <div class="tree-content">      <div class="expand-arrow"></div>      <div class="tree-label">語文</div>     </div>    </li>    <li class="tree-item">     <div class="tree-content">      <div class="expand-arrow"></div>      <div class="tree-label">數(shù)學(xué)</div>     </div>    </li>   </ul>  </li> </ul></template><style lang="stylus">.vue-tree{ list-style: none; padding: 0; margin: 0; .tree-item{  cursor: pointer;  transition: background-color .2s;  .tree-content{   position: relative;   padding-left: 28px;   &:hover{    background-color: #f0f7ff;   }  }  .expand-arrow{   position: absolute;   top: 0;   left: 0;   width: 28px;   height: 28px;   cursor: pointer;   &::after{    position: absolute;    top: 50%;    left: 50%;    display: block;    content: ' ';    border-width: 5px;    border-style: solid;    border-color: transparent;    border-left-color: #ccc;    margin: -5px 0 0 -2.5px;    transition: all .2s;   }  }  &.expand{   &>.tree-content{    background-color: #f0f7ff;    &>.expand-arrow{     &::after{      transform: rotate(90deg);      margin: -2.5px 0 0 -5px;     }    }   }  }  .tree-label{   height: 28px;   line-height: 28px;   font-size: 14px;  }  .sub-tree{   display: none;   list-style: none;   padding: 0 0 0 28px;   margin: 0;  }  &.expand>.sub-tree{   display: block;  }  &.no-child{   &>.tree-content{    &>.expand-arrow{     display: none;    }   }  } }}</style>

3、組件目錄及數(shù)據(jù)結(jié)構(gòu)

目錄結(jié)構(gòu)

vue-tree

VueTree.vue
TreeItem.vue

樹形控件數(shù)據(jù)結(jié)構(gòu)

let treeData = [ {  text: "一級(jí)", // 顯示的文字  expand: false, // 默認(rèn)是否展開  children: [ // 子節(jié)點(diǎn)   {    text: "一級(jí)-1",    expand: false,   },   {    text: "一級(jí)-2",    expand: false,    children: [     {      text: "一級(jí)-2-1",      expand: false,     },     {      text: "一級(jí)-2-2",      expand: false,     }    ]   }  ] }];

3.1、 TreeItem.vue 代碼

<template> <li class="tree-item" :class="{expand: isExpand, 'no-child': !treeItemData.children || treeItemData.children.length === 0}">  <div class="tree-content" @click="_clickEvent">   <div class="expand-arrow" @click.stop="expandTree()"></div>   <div class="tree-label">{{treeItemData.text}}</div>  </div>  <ul class="sub-tree" v-if="treeItemData.children && treeItemData.children.length > 0">   <!--TreeItem組件中調(diào)用TreeItem組件-->   <TreeItem    v-for="item in treeItemData.children"    :tree-item-data="item"    :key="uuid()"    :tree-click-event="treeClickEvent"></TreeItem>  </ul> </li></template><script> export default {  name: "TreeItem",  props: {   treeItemData: {    type: Object,    default(){     return {};    }   },   // 節(jié)點(diǎn)點(diǎn)擊事件   treeClickEvent: {    type: Function,    default() {     return function () {};    }   }  },  data(){   return {    // 節(jié)點(diǎn)是否展開    isExpand: this.treeItemData.expand || false   }  },  methods: {   // 展開/收縮   expandTree(flag){    if(!this.treeItemData.children || this.treeItemData.children.length === 0){     return;    }    if(typeof flag === 'undefined'){     flag = !this.isExpand;    }else{     flag = !!flag;    }    this.isExpand = flag;   },   // 創(chuàng)建一個(gè)唯一id   uuid(){    let str = Math.random().toString(32);    str = str.substr(2);    return str;   },   // 節(jié)點(diǎn)點(diǎn)擊事件   _clickEvent(){    // 如果有傳遞事件函數(shù),則調(diào)用事件函數(shù)并傳遞當(dāng)前節(jié)點(diǎn)數(shù)據(jù)及組件    if(this.treeClickEvent && typeof this.treeClickEvent === 'function'){     this.treeClickEvent(this.treeItemData, this);    }   }  } }</script>

3.1.1、解決 組件如何才能遞歸調(diào)用? 問題

在組件模板內(nèi)調(diào)用自身 必須明確定義組件的name屬性 ,并且遞歸調(diào)用時(shí)組件名稱就是name屬性。如在 TreeItem.vue 組件中組件的name名稱為'TreeItem',那么在template中調(diào)用時(shí)組件名稱就必須是 <TreeItem> 。

當(dāng)然也可以全局注冊(cè)組件,具體可以查看vue官方文檔 遞歸組件

3.1.2、解決 遞歸組件點(diǎn)擊事件如何傳遞? 問題

我這里的解決方案是使用 props 將事件函數(shù)傳遞進(jìn)來,在點(diǎn)擊節(jié)點(diǎn)的時(shí)候調(diào)用事件函數(shù),并把相應(yīng)的數(shù)據(jù)傳遞進(jìn)去。

之前也嘗試過使用 $emit 的形式并把數(shù)據(jù)傳遞過去,由于是遞歸組件,這樣一直 $emit ,到最外層時(shí)傳遞的數(shù)據(jù)就變了,比如傳遞是第3層節(jié)點(diǎn)的數(shù)據(jù),到最后執(zhí)行時(shí)數(shù)據(jù)就變成第1層節(jié)點(diǎn)的數(shù)據(jù)了

4、 VueTree.vue 組件

<template> <ul class="vue-tree">  <TreeItem    v-for="(item, index) in treeData"    :key="index"    :treeItemData="item"    :tree-click-event="treeClickEvent"></TreeItem> </ul></template><script> import TreeItem from "./TreeItem"; export default {  name: "VueTreeMenu",  components: {   TreeItem  },  props: {   // 樹形控件數(shù)據(jù)   treeData: {    type: Array,    default(){     return [];    }   },   // 節(jié)點(diǎn)點(diǎn)擊事件   treeClickEvent: {    type: Function,    default() {     return function () {};    }   }  } }</script><style lang="stylus">.vue-tree{ list-style: none; padding: 0; margin: 0; .tree-item{  cursor: pointer;  transition: background-color .2s;  .tree-content{   position: relative;   padding-left: 28px;   &:hover{    background-color: #f0f7ff;   }  }  .expand-arrow{   position: absolute;   top: 0;   left: 0;   width: 28px;   height: 28px;   cursor: pointer;   &::after{    position: absolute;    top: 50%;    left: 50%;    display: block;    content: ' ';    border-width: 5px;    border-style: solid;    border-color: transparent;    border-left-color: #ccc;    margin: -5px 0 0 -2.5px;    transition: all .2s;   }  }  &.expand{   &>.tree-content{    background-color: #f0f7ff;    &>.expand-arrow{     &::after{      transform: rotate(90deg);      margin: -2.5px 0 0 -5px;     }    }   }  }  .tree-label{   height: 28px;   line-height: 28px;   font-size: 14px;  }  .sub-tree{   display: none;   list-style: none;   padding: 0 0 0 28px;   margin: 0;  }  &.expand>.sub-tree{   display: block;  }  &.no-child{   &>.tree-content{    /*padding-left: 0;*/    &>.expand-arrow{     display: none;    }   }  } }}</style>

5、使用樹形組件

<template> <div class="app" id="app">  <VueTree :tree-data="treeData2" :tree-click-event="treeClickEvent"></VueTree> </div></template><script>import VueTree from "./components/vue-tree/VueTree";export default { name: 'app', data(){  return {   treeData2: [    {     text: "一級(jí)", // 顯示的文字     expand: false, // 默認(rèn)是否展開     children: [      {       text: "二級(jí)-1",       expand: false,      },      {       text: "二級(jí)-2",       expand: false,       children: [        {         text: "三級(jí)-1",         expand: false,        },        {         text: "三級(jí)-2",         expand: false,         children: [          {           text: "四級(jí)-1",           expand: false,          }         ]        }       ]      }     ]    },    {     text: "一級(jí)-2",     expand: false    }   ]  } }, methods: {  treeClickEvent(item, treeItem){   console.log(item);  } }, components: {  VueTree }}</script>

總結(jié)

以上所述是小編給大家介紹的vue遞歸組件實(shí)戰(zhàn)之簡(jiǎn)單樹形控件實(shí)例代碼,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)武林網(wǎng)網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 克东县| 资溪县| 宜州市| 涪陵区| 南川市| 桐庐县| 屏南县| 彰化县| 开平市| 尚志市| 丰镇市| 同江市| 临颍县| 当阳市| 汶上县| 张掖市| 舞钢市| 尼玛县| 洪江市| 阿克| 玉山县| 景泰县| 海城市| 独山县| 华宁县| 仙居县| 天津市| 彝良县| 绥宁县| 抚松县| 宁夏| 永泰县| 宕昌县| 泸州市| 杭州市| 扎鲁特旗| 云和县| 同仁县| 沭阳县| 平度市| 门头沟区|