1. 程式人生 > 實用技巧 >element tree元件

element tree元件

element tree 樹形元件的使用

前言:
1.element tree有很多的方法獲取資料但不是我們想要的型別
2.相信大家需要的資料型別是當你選中某個子級的時候要獲取原始父級一直到你選中的子級的所有關係(說的不太明白),請先看圖

圖片

  • 圖片展示
    順序 元件展示 返回的資料
    第一次 (未全部選中)
    第二次(全部選中)

解釋

很明顯資料的關聯沒有被斷開,可以一直找到你選中資料的原始父級,而且如果同級資料沒有選中,返回的資料裡面不會包含未選中的同級,我感覺應該是大部分的人需要的型別,下面貼上返回的資料圖片

程式碼 (裡面是我整個頁面,可只看tree元件)

//資料樣例展示
 data2: [{
        id: 1,
        label: 'Level one 1',
        children: [{
          id: 4,
          label: 'Level two 1-1',
          children: [{
            id: 9,
            label: 'Level three 1-1-1'
          }, {
            id: 10,
            label: 'Level three 1-1-2'
          }]
        }]
      }, {
        id: 2,
        label: 'Level one 2',
        children: [{
          id: 5,
          label: 'Level two 2-1'
        }, {
          id: 6,
          label: 'Level two 2-2'
        }]
      }, {
        id: 3,
        label: 'Level one 3',
        children: [{
          id: 7,
          label: 'Level two 3-1'
        }, {
          id: 8,
          label: 'Level two 3-2'
        }]
      }]

//程式碼

<template>
  <div>
    <el-row :gutter="20">
      <el-col :span="12">
        <el-card>
          <div slot="header" class="clearfix">
            <span>建立管理員</span>
          </div>
          <el-form label-width="80px" :model="formLabelAlign">
            <el-form-item label="賬號">
              <el-input v-model="formLabelAlign.name"></el-input>
            </el-form-item>
            <el-form-item label="密碼">
              <el-input v-model="formLabelAlign.path"></el-input>
            </el-form-item>
            <el-collapse v-model="activeNames" @change="handleChange">
              <!-- 路由 -->
              <el-collapse-item title="許可權配置" name="0">

                <!-- <el-table :data="trees" style="width: 100%;margin-bottom: 20px;" row-key="id" border default-expand-all :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
                  <el-table-column  prop="label" label="路由名稱" sortable width="180">
                  </el-table-column>
                  <el-table-column prop="path" label="路徑展示" sortable width="180">
                  </el-table-column>
                </el-table> -->

                <!-- :load="loadNode" lazy-->
                <el-tree @check-change="treeChange" id="tree" :data="trees" node-key="id" :props="defaultProps" :show-checkbox="true" ref="tree"></el-tree>
                <el-button style="margin-top:20px" size="mini" @click="getCheckedNodes">儲存</el-button>
              </el-collapse-item>
            </el-collapse>
          </el-form>
        </el-card>
      </el-col>

      <!-- 展示 -->
      <el-col :span="12">
        <el-card header="資料展示">
           <el-tree :data="checkRoute" :props="defaultProps" ref="tree-2"></el-tree>
        </el-card>
       
      </el-col>
    </el-row>
  </div>
</template>

<script>
  import { permissionRoutes } from "@/router/index";
  // console.log(permissionRoutes)
  let noderoutes = []
  export default {
    name: '',
    components: {

    },
    props: {

    },
    data() {
      return {
        formLabelAlign: {
          name: "",
          region: "",
          type: ""
        },
        activeNames: ['1'],
        trees: [],
        defaultProps: {
          children: "children",
          label: 'label',
          id: 'path',
          isLeaf: 'leaf'
        },
        saveTrees: [],
        parentNode: "",
        checkRoute: []

      };
    },
    computed: {

    },
    watch: {

    },
    created() {
      noderoutes = this.trees = this.generateRouter(permissionRoutes);
      // console.log(this.trees)
    },
    mounted() {

    },
    methods: {


      handleClick(tab, event) {
        console.log(tab, event);
      },

      handleChange() {

      },

      // 將許可權路由生成tree元件需要的資料格式
      generateRouter(arr) {
        let newArr = []

        arr.forEach(item => {
          if (item.label) {
            let params = {
              id: item.id,
              label: item.label || "",
              path: item.path || ""
            }
            if (item.children) {
              params.children = this.generateRouter(item.children)
            }
            newArr.push(params)
          }

        })
        return newArr
      },

      // 最終獲取所有選中路由的陣列
      getCheckedNodes() {
        if (!this.parentNode) {
          return
        }

        const { childNodes } = this.parentNode;

        if (this.parentNode.childNodes.filter(item => item.checked === false).length === 0) {
          this.checkRoute = this.trees
        } else {
          console.log("childNodes===>", this.generateCheckRouter(childNodes))
          this.checkRoute = this.generateCheckRouter(childNodes)
        }

      },

      //向下方獲取獲取tree元件的root(最高)節點方法傳遞需要資料 
      treeChange(data, node, check) {
        const nodeData = this.$refs.tree.getNode(data.id);
        this.getParent(nodeData)
      },

      // 懶載入 棄用
      loadNode(node, resolve) {
        if (node.level === 0) {
          const level_1 = []
          this.trees.forEach(item => {
            level_1.push({
              label: item.label,
              path: item.path
            })
          })
          return resolve(level_1);
        }

        if (node.level === 1) {
          noderoutes = this.trees
        }

        let hasChild;

        if (Array.isArray(noderoutes)) {
          noderoutes.forEach(item => {
            if (item.children) {
              hasChild = true
            } else {
              hasChild = false
            }
          })

          const arr = noderoutes.filter(item => item.label === node.data.label);
          if (arr[0].children) {
            noderoutes = arr[0].children
            resolve(arr[0].children)
          } else {
            resolve([])
          }

        } else {
          hasChild = false
        }
      },

      // 工具方法 獲取tree元件的root(最高)節點
      getParent(obj) {
        if (obj.parent) {
          return this.getParent(obj.parent);
        } else {
          this.parentNode = obj
        }
      },

      // 生成一個被選中的路由表
      generateCheckRouter(arr) {
        let newArr = [];

        arr.forEach((item, index) => {
        
          if (item.checked || this.getBoolean(item.childNodes)) {

            let params = {
              id: item.data.id,
              label: item.data.label || "",
              path: item.data.path || ""
            }

            if (item.childNodes.length > 0) {
              params.children = this.generateCheckRouter(item.childNodes)
            }

            newArr.push(params)
          }
        })
        return newArr
      },

      // 對路由選中進行判斷
      getBoolean(array) {
        // console.log(array)
        let flag = false;
        for (let index = 0; index < array.length; index++) {
          const element = array[index];

          if (element.checked) {
           return flag = true
          }
          if (element.childNodes.length > 0) {
             flag = this.getBoolean(element.childNodes)
          } else {
            continue
          }
        }
        return flag
      }


    }
  };
</script>

<style scoped lang="scss">
</style>