Vue 實現(xiàn)樹形視圖數(shù)據(jù)功能
利用簡單的樹形視圖實現(xiàn),熟悉了組件的遞歸使用
這是模擬的樹形圖數(shù)據(jù)
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> <div> <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> </div> </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> <div id="app"> <tree :treelist="treeList"></tree> </div> </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 } })
在經(jīng)過踩坑之后,我發(fā)現(xiàn)Vue官網(wǎng)有類似的案例,鏈接→ 傳送門
參考過官網(wǎng)的方法后,我嘗試著實現(xiàn)了一下
這樣寫和我踩坑時的 思路不同點在于, 這樣一個組件只負責(zé)一個 對象,遍歷每個children 中的對象,逐個傳入組件處理,而我第一次嘗試則是 將整個children 傳入自身 是一個組件處理多個對象,(第一次嘗試的失敗案例,有興趣請看最下方)
這樣一個組件處理一個對象 寫的好處是什么呢
我可以在組件內(nèi)自定義開關(guān)了
我在data里定義了變量open,因為組件遞歸,所以相當(dāng)于每個組件都有個屬于自己的open
那為什么第一次踩坑時我不可以用這種方法呢,因為我第一次嘗試 是一個組件處理多個對象 就是相當(dāng)于 一個開關(guān)控制 children中的所有對象,當(dāng)開關(guān)打開時會導(dǎo)致 這個同級的所有 對象都被展開
遍歷children 挨個傳入組件自身 用v-show 來控制是否顯示
定義了一個計算屬性,依據(jù)children來判斷是否繼續(xù)執(zhí)行
在span標(biāo)簽上綁定了一個自定義事件
更改open 的值
<span @click="isshow()">{{treelist.name}}</span>
實現(xiàn)效果
以下 是我剛開始嘗試的時候踩得坑
在這里記錄一下,以后遇到類似問題留個印象
首先上來就遇到了這樣的報錯
找了很久的問題,發(fā)現(xiàn)是因為組件內(nèi)忘記寫name了,自身使用自身必須填寫name,并且與標(biāo)簽名一致
一開始的實現(xiàn)方法,利用組件遞歸,顯示出當(dāng)前級的name渲染出來,并將其中的 children 中的所有對象 傳給自己然后接著執(zhí)行相同操作,直到children沒有數(shù)據(jù),值得一提的是
,如果這里不加上 v-if 就會變成 死循環(huán),就會一直執(zhí)行下去,所以我們要判斷一下當(dāng)前執(zhí)行的對象到底還有沒有下一級
這里我數(shù)據(jù)有稍微的改動,所以我第一次傳入的數(shù)據(jù)就是(index.html頁面)
然后我定義了一個事件來處理 每一層的關(guān)閉和開啟,我用彈框來查看Isopen 的值是否被改變
我們看一下結(jié)果
剛進入頁面時,括號中的undefined是 Isopen 當(dāng)前的值,因為此時未被定義,所以為undefined
然后我點擊了A
因為此時isopen已被反轉(zhuǎn)值,所以此時isopen為true
但是頁面仍毫無變化,不說展開功能,就連undefined也沒變化
經(jīng)過一番百度 ,發(fā)現(xiàn)原來是vue本身已經(jīng)不允許這樣直接更改 Props接受過來的值了
Vue2.0以后子組件不能更改父組件的值,只能通過子組件$emit(),父組件$on()進行響應(yīng)更改
相關(guān)文章
Vue 子組件使用 this.$parent 無法訪問到父組件數(shù)據(jù)和方法(解決思路)
這篇文章主要介紹了Vue 子組件使用 this.$parent 無法訪問到父組件數(shù)據(jù)和方法,解決思路也很簡單,本文結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2023-07-07vite+ts vite.config.ts使用path報錯問題及解決
這篇文章主要介紹了vite+ts vite.config.ts使用path報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10vue中使用Cesium加載shp文件、wms服務(wù)、WMTS服務(wù)問題
這篇文章主要介紹了vue中使用Cesium加載shp文件、wms服務(wù)、WMTS服務(wù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05通過實例解析vuejs如何實現(xiàn)調(diào)試代碼
這篇文章主要介紹了通過實例解析vuejs如何實現(xiàn)調(diào)試代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07