Vue Element Tree 树形控件

Element Tree 树形控件   

本示例以 Vue Element Admin 项目为基础,介绍 Element Tree 树形控件
【注意:返回的数据是平级数据,前端自动递归处理】
 

1、/src/views/tree.vue

<template>
  <div class="app-container">
    <el-row>
      <el-col :span="24">
        <el-button @click="getCheckedNodes">通过 node 获取</el-button>
        <el-button @click="getCheckedKeys">通过 key 获取</el-button>
        <el-button @click="setCheckedNodes">通过 node 设置</el-button>
        <el-button @click="setCheckedKeys">通过 key 设置</el-button>
        <el-button @click="resetChecked">清空</el-button>
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="8">
        <div class="grid-content bg-purple">
          <el-tree ref="tree1" :data="list" node-key="menu_code" :props="defaultProps" default-expand-all @node-click="handleNodeClick"/>
        </div>
      </el-col>
      <el-col :span="8">
        <div class="grid-content bg-purple">
          <el-input placeholder="输入关键字进行过滤" v-model="filterText"></el-input>
          <el-tree ref="tree" :data="list" :props="defaultProps" default-expand-all :filter-node-method="filterNode" @node-click="handleNodeClick"></el-tree>
        </div>
      </el-col>
      <el-col :span="8">
        <div class="grid-content bg-purple-light">
          <el-tree
            ref="tree2"
            :data="list"
            show-checkbox
            node-key="menu_code"
            highlight-current
            :default-expanded-keys="[1,2,3]"
            :default-checked-keys="[5]"
            :filter-node-method="filterNode"
            :props="defaultProps"
            @check-change="handleCheckChange"
            @node-click="handleNodeClick"/>
        </div>
      </el-col>
    </el-row>

  </div>
</template>

<script>
// import { getTreeMenus } from "@/api/tree";
import { jsonTree } from "@/utils/tree";

export default {
  data() {
    return {
      filterText: '',
      list: [],
      defaultProps: {
        id: "menu_code",
        label: "menu_name",
        children: "children"
      },
      listQuery: {
        resource_code: 1,
        page: 1,
        per_page: 20
      }
    };
  },
  watch: {
    filterText(val) {
      console.log(val)
      this.$refs.tree.filter(val);
    }
  },
  created() {
    this.getList();
  },
  methods: {
    async getList() {
      // 动态查询
      // getTreeMenus(this.listQuery)
      //   .then(res => {
      //     this.list = jsonTree(res.data.items, {
      //       id: "menu_code",
      //       pid: "parent_code",
      //       children: "children"
      //     });
      //   })
      //   .catch(err => {
      //     console.error(err);
      //     console.log("修改出错了");
      //   });

      //本地数据
      this.list = jsonTree([
        { "menu_code": 1,"menu_name": "一级菜单 1","parent_code": 0 },
        { "menu_code": 2,"menu_name": "一级菜单 2","parent_code": 0 },
        { "menu_code": 3,"menu_name": "一级菜单 3","parent_code": 0 },
        { "menu_code": 4,"menu_name": "二级菜单 1-1","parent_code": 1 },
        { "menu_code": 5,"menu_name": "二级菜单 2-1","parent_code": 2 },
        { "menu_code": 6,"menu_name": "二级菜单 3-1","parent_code": 3 },
        { "menu_code": 7,"menu_name": "二级菜单 3-2","parent_code": 3 },
        { "menu_code": 8,"menu_name": "二级菜单 3-3","parent_code": 3 },
        { "menu_code": 9,"menu_name": "三级菜单 3-3-1","parent_code": 8 },
        { "menu_code": 10,"menu_name": "三级菜单 3-3-2","parent_code": 8 },
        { "menu_code": 11,"menu_name": "四级菜单 3-3-2-1","parent_code": 10 },
        { "menu_code": 12,"menu_name": "四级菜单 3-3-2-2","parent_code": 10 },
        { "menu_code": 13,"menu_name": "四级菜单 3-3-2-3","parent_code": 10 }
      ], 
      {
        id: "menu_code",
        pid: "parent_code",
        children: "children"
      })
    },
    handleCheckChange(data, checked, indeterminate) {
      console.log(data, checked, indeterminate);
    },
    handleNodeClick(data) {
      console.log(JSON.stringify(data))
      this.filterText = data.menu_name
    },
    filterNode(value, data) {
      if (!value) return true;
      console.log(JSON.stringify(data))
      //return data.label.indexOf(value) !== -1;//官方写法
      return data.menu_name.indexOf(value) !== -1;//自定义写法
    },
    getCheckedNodes() {
      console.log(this.$refs.tree.getCheckedNodes());
    },
    getCheckedKeys() {
      console.log(this.$refs.tree.getCheckedKeys());
    },
    setCheckedNodes() {
      this.$refs.tree.setCheckedNodes([
        { id: 5, label: "二级 2-1" },
        { id: 9, label: "三级 1-1-1" }
      ]);
    },
    setCheckedKeys() {
      var arr = ['menu68','menu66','menu65'];
      this.$refs.tree.setCheckedKeys(arr);
    },
    resetChecked() {
      this.$refs.tree.setCheckedKeys([]);
    }
    // renderContent(h, { node, data, store }) {},
  }
};
</script>
<style>
  .el-row { margin-bottom: 20px; &:last-child { margin-bottom: 0; }}
  .el-col { border-radius: 4px; }
  .bg-purple-dark { background: #99a9bf; }
  .bg-purple { background: #d3dce6; }
  .bg-purple-light { background: #e5e9f2; }
  .grid-content { border-radius: 4px; min-height: 36px; }
  .row-bg { padding: 10px 0; background-color: #f9fafc; }
</style>

2、/src/api/tree.js

import request from '@/utils/request'

export function getTreeMenus(query) {
  return request({
    url: '/v1/menus',
    method: 'get',
    params: query
  })
}

3、/src/utils/tree.js

export function jsonTree(data, config) {
    var id = config.id || "id",
        pid = config.pid || "pid",
        children = config.children || "children";
    var idMap = [],
        newIdMap = [],
        jsonTree = [];
    data.forEach(function (v) {
        idMap[v[id]] = v;
    });
    data.forEach(function (v) {
        var parent = idMap[v[pid]];
        delete v.parent;
        if (parent) {
            !parent[children] && (parent[children] = []);
            parent[children].push(v);
        } else {
            jsonTree.push(v);
        }
    });
    return jsonTree;
}

4、服务端 API 接口返回 json 数据

{
  "data": {
    "items": [
      { "menu_code": 1,"menu_name": "一级菜单 1","parent_code": 0 },
      { "menu_code": 2,"menu_name": "一级菜单 2","parent_code": 0 },
      { "menu_code": 3,"menu_name": "一级菜单 3","parent_code": 0 },
      { "menu_code": 4,"menu_name": "二级菜单 1-1","parent_code": 1 },
      { "menu_code": 5,"menu_name": "二级菜单 2-1","parent_code": 2 },
      { "menu_code": 6,"menu_name": "二级菜单 3-1","parent_code": 3 }
    ],
    "total": 6,
    "page_count": 1
  },
  "code": "200",
  "msg": null
}

*
*
*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值