這次帶給大家怎麼用Vue實現樹狀視圖數據,用Vue實現樹狀視圖數據的注意事項有哪些,下面就是實戰案例,一起來看一下。
這是模擬的樹狀圖資料
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
<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:'tree', props:['treelist'], 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
<!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
import Vue from 'vue'; import tree from '../components/treelist.vue' 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 } } } } } } } 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 的值
<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()進行響應更改
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
#以上是怎麼用Vue實現樹狀視圖數據的詳細內容。更多資訊請關注PHP中文網其他相關文章!