首頁 > web前端 > js教程 > Vue 實作樹狀視圖資料功能

Vue 實作樹狀視圖資料功能

不言
發布: 2018-05-07 14:33:54
原創
1781 人瀏覽過

這篇文章主要介紹了關於實現Vue 實現樹形視圖資料功能,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

利用簡單的樹狀視圖實現,熟悉了元件的遞歸使用

這是模擬的樹形圖資料

#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

let all={

  name:'all',

  children:{

   A:{

    name:'A',

    children:{

     a1:{

      name:'a1',

      children:{

       a11:{ 

        name:'a11',

        children:null

       },

       a12:{ 

        name:'a12',

        children:null

       }

      }

     },

     a2:{

      name:'a2',

      children:{

       b21:{ 

        name:'b21',

        children:null

       }

      }

     }

    }

   },

   B:{

    name:'B',

    children:{

     b1:{

      name:'b1',

      children:{

       b11:{ 

        name:'b11',

        children:null

       },

       b12:{ 

        name:'b12',

        children:null

       }

      }

     },

     b2:{

      name:'b2',

      children:{

       b21:{ 

        name:'b21',

        children:null

       }

      }

     }

    }

   }

  }

 }

登入後複製

程式碼如下

treelist.vue

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

<template>

<p>

 <ul>

  <li >

   <span @click="isshow()">{{treelist.name}}</span>

    <tree v-for="item in treelist.children" 

     v-if="isFolder"

     v-show="open"

     :treelist="item"

     :keys="item"

    ></tree>

  </li>

 </ul>

</p>

</template>

<script>

export default {

 name:&#39;tree&#39;,

 props:[&#39;treelist&#39;],

 data(){

  return{

   open:false

  }

 },computed:{

  isFolder:function(){

   return this.treelist.children

   }

  }

 ,methods:{

  isshow(){

   if (this.isFolder) {

    this.open =!this.open

   }

  }

 }

}

</script>

<style lang="less">

</style>

登入後複製

index.html

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<!DOCTYPE html>

<html lang="en">

<head>

 <meta charset="UTF-8">

 <meta name="viewport" content="width=device-width, initial-scale=1.0">

 <meta http-equiv="X-UA-Compatible" content="ie=edge">

 <title>树形图</title>

</head>

<body>

 <p id="app">

  <tree :treelist="treeList"></tree>

    

 </p>

</body>

</html>

登入後複製

index. js

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

import Vue from 'vue';

import tree from '../components/treelist.vue'

let all={

  name:&#39;all&#39;,

  children:{

   A:{

    name:&#39;A&#39;,

    children:{

     a1:{

      name:&#39;a1&#39;,

      children:{

       a11:{ 

        name:&#39;a11&#39;,

        children:null

       },

       a12:{ 

        name:&#39;a12&#39;,

        children:null

       }

      }

     },

     a2:{

      name:&#39;a2&#39;,

      children:{

       b21:{ 

        name:&#39;b21&#39;,

        children:null

       }

      }

     }

    }

   },

   B:{

    name:&#39;B&#39;,

    children:{

     b1:{

      name:&#39;b1&#39;,

      children:{

       b11:{ 

        name:&#39;b11&#39;,

        children:null

       },

       b12:{ 

        name:&#39;b12&#39;,

        children:null

       }

      }

     },

     b2:{

      name:&#39;b2&#39;,

      children:{

       b21:{ 

        name:&#39;b21&#39;,

        children:null

       }

      }

     }

    }

   }

  }

 }

const app=new Vue({

 el:"#app",

 components:{

  'tree':tree

 },

 data:{

  treeList:all

 }

})

登入後複製

在經過踩坑之後,我發現Vue官網有類似的案例,連結→ 傳送門

參考過官網的方法後,我嘗試著實現了一下

這樣寫和我踩坑時的思路不同點在於, 這樣一個組件只負責一個對象,遍歷每個children 中的對象,逐個傳入組件處理,而我第一次嘗試則是將整個children  傳入自身   是一個元件處理多個對象,(第一次嘗試的失敗案例,有興趣請看最下方)

這樣一個元件處理一個物件寫的好處是什麼呢

我可以在元件內自訂開關了

我在data裡定義了變數open,因為元件遞歸,所以相當於每個元件都有個屬於自己的open

那為什麼第一次踩坑時我不可以用這種方法呢,因為我第一次嘗試是一個元件處理多個對象就是相當於一個開關控制children中的所有對象,當開關打開時會導致這個同級的所有對像都被展開

遍歷children 挨個傳入組件自身    用v-show 來控制是否顯示 


#定義了計算屬性,依據children來判斷是否繼續執行 


##在span標籤上綁定了一個自訂事件

更改open 的值 

1

<span @click="isshow()">{{treelist.name}}</span>

登入後複製


實作效果



以下是我剛開始嘗試的時候踩得坑

在這裡記錄一下,以後遇到類似問題留個印象首先上來就遇到了這樣的報錯

找了很久的問題,發現是因為元件內忘記寫name了,自身使用自身必須填入name,並且與標籤名一致

一開始的實作方法,利用元件遞歸,顯示出目前層級的name渲染出來,並將其中的children 中的所有物件傳給自己然後接著執行相同操作,直到children沒有數據,值得一提的是


,如果這裡不加上v-if 就會變成死迴圈,就會一直執行下去,所以我們要判斷一下目前執行的物件到底還有沒有下一層


這裡我資料有稍微的改動,所以我第一次傳入的資料就是(index.html頁面)


#然後我定義了一個事件來處理每一層的關閉和開啟,我用彈框來查看Isopen 的值是否被改變


#我們看一下結果

剛進入頁面時,括號中的undefined是Isopen 目前的值,因為此時未被定義,所以為undefined

################然後我點擊了A############ ######因為此時isopen已反轉值,所以此時isopen為true###


但頁面仍毫無變化,不說展開功能,就連undefined也沒變化



經過一番百度,發現原來是vue本身已經不允許這樣直接更改Props接受過來的值了

Vue2.0以後子元件不能更改父元件的值,只能透過子元件$emit(),父元件$on()進行回應更改

#相關推薦:

##Vue實作動態刷新Echarts元件

#

以上是Vue 實作樹狀視圖資料功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板