vue项目+el-tree,树结构展示,非常完整的代码,包含调接口拿真实数据渲染

2023-10-27

温故而知新,最近项目中频繁使用树形结构展示效果,因为不熟悉,备受折磨。
代码贴出来,再复习一次。

代码太长了,想看分析的可以搜我下一篇文章,下一篇会详细的写如何在项目中使用

效果:左侧是树,右侧是表格。点击任何一行都会展示对应的表格
在这里插入图片描述
**完整代码如下:**模板区

  <el-card >
      <div style="display: flex; justify-content: start">
        <div class="leftBox">
          <div
            v-for="(item, index) in buttonList"
            :key="index"
            @click="num = index"
            style="float: left"
          >
            <el-button class="buttonList" size="medium" @click="treeDataList('parent_id')">{{
              item.label
            }}</el-button>
          </div>
          <div class="treeclass">
            <!-- :default-expanded-keys(默认展开项)
      通过render-content方法定义树节点内容(js代码)
       node-key:设置选中节点对应的值
       default-expand-all:是否默认展开所有节点
        :default-checked-keys 设置默认选中项的数组
        ref:设置引用
      :load="loadChildData" (load 加载子树数据的方法,仅仅当lazy属性为true时生效) -->
            <el-input
              placeholder="输入关键字进行过滤"
              v-model="filterText"
            ></el-input>
            <el-tree
              class="treeitems"
              :data="treeData"
              node-key="id"
              :props="defaultProps"
              accordion
              default-expand-all
              :filter-node-method="filterNode"
              @node-click="handleNodeClick"
              ref="tree"
            >
              <span
                class="custom-tree-node"
                slot-scope="{ node, data }"
                @mouseenter="mouseenter(data)"
                @mouseleave="mouseleave(data)"
              >
                <span>
                   <span v-if="!node.isLeaf">
                  <i class="folder-open" v-if="node.expanded"></i>
                  <i class="folder-close" v-else></i>
                </span>
                   <i v-else class="el-icon-document"></i>
                  {{ node.label }}</span>
                <span class="span_icon">
                  <span v-show="data.show" style="float: right">
                    <img
                      src="@/assets/images/png"
                      alt=""
                      @click.stop="() => append(node, data)"
                    />
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    <img
                      src="@/assets/images/png"
                      alt=""
                      @click.stop="() => appendChild(node, data)"
                    />
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    <img
                      src="@/assets/images/png"
                      alt=""
                      @click.stop="() => editNode(node, data)"
                    />
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    <img
                      src="@/assets/images/png"
                      alt=""
                      @click.stop="() => deleteNode(node, data)"
                    />
                  </span>
                </span>
              </span>
            </el-tree>
          </div>
        </div>
        <div class="rightBox">
          <el-table :data="tableData">
            <!-- <el-table-column type="index" label="序号" align="center"> </el-table-column> -->
            <el-table-column type="index" label="序号" align="center" width="70">
            </el-table-column>
            <el-table-column prop="" label="" align="center">
            </el-table-column>
            <el-table-column prop="" label="" align="center">
            </el-table-column>
            <el-table-column prop="cost_target" label="目标成本" align="center">
            </el-table-column>
            <el-table-column
              prop="cost_construction"
              label="建筑单方造价"
              align="center"
            >
            </el-table-column>
            <el-table-column
              prop="cost_sellable"
              label="可售单方造价"
              align="center"
            >
            </el-table-column>
            <!-- <el-table-column prop="mark" label="备注" align="center">
            </el-table-column> -->
            <el-table-column label="操作" align="center">
              <template slot-scope="scope">
                <!-- 表格查看 -->
                <img
                  src="~/@/assets/images/"
                  class="icon icon-deal"
                  alt=""
                  style="margin-right: 20px; color: #409eff"
                  @click="reviewworkFile(scope.row)"
                />
                <!-- 表格编辑 -->
                <img
                  src="~/@/assets/images/icon-update.png"
                  alt=""
                  class="icon icon-deal"
                  style="margin-right: 20px; color: #409eff"
                  @click="editworkFile(scope.row)"
                />
                <!-- 表格删除-->
                <img
                  src="~/@/assets/images/png"
                  alt=""
                  class="icon icon-deal"
                  style="color: #fe775c"
                  @click="removeworkFile(scope.row.id)"
                />
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      <!-- 添加树节点 -->
      <el-dialog
        :title="addNodeForm.id ? '修改xx分类' : '添加xx分类'"
        center
        :visible.sync="nodeDialogVisible"
        width="30%"
        :before-close="nodeClose"
      >
        <span>
          <el-form
            :model="addNodeForm"
            :rules="addNodeFormRules"
            ref="addNodeRef"
            label-width="130px"
          >
            <el-form-item label="关联项目:" prop="project_id">
              <el-select
                clearable
                v-model="addNodeForm.project_id"
                placeholder="请选择项目"
              >
                <el-option
                  v-for="item in projects"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label=":" prop="">
              <el-input v-model=""></el-input>
            </el-form-item>
            <el-form-item label="" prop="">
              <el-input v-model.number="t"></el-input>
            </el-form-item>
            <el-form-item label="" prop="">
              <el-input
                type="textarea"
                v-model=""
                rows="3"
              ></el-input>
            </el-form-item>
          </el-form>
        </span>
        <span slot="footer" class="dialog-footer">
          <el-button @click="nodeClose">取 消</el-button>
          <el-button type="primary" @click="submitNode">确 定</el-button>
        </span>
      </el-dialog>
      <!-- 添加表格 -->
      <el-dialog
        :title="dialogTitle"
        center
        :visible.sync="tableDialogVisible"
        width="30%"
        :before-close="tableClose"
      >
        <span>
          <el-form
            :model="addTableForm"
            :rules="addTableFormRules"
            ref="addTableRef"
            label-width="130px"
          >
            <el-form-item label="关联项目:">
              <el-select
                clearable
                v-model="addTableForm.project_id"
                 :disabled="inputFlag"
                placeholder="请选择项目"
              >
                <el-option
                  v-for="item in projects"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="项目分类:">
              <!--   label="title"   v-model="addTableForm.category_id"  -->
              <treeselect
                :options="treeData"
                :value='value'
               :normalizer="normalizer"
               placeholder="请选择项目类型"
              />

            </el-form-item>
            <el-form-item label="科目类型" prop="type">
              <el-select
            
                v-model="addTableForm.type_text"
               
                placeholder="请选择"
              >
                <el-option
                  v-for="item in typeSelect"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>

            <el-form-item label="" prop="">
              <el-input v-model.number=""  :disabled="inputFlag">
                    <template slot="append">万元</template>
              </el-input>
            </el-form-item>
            <el-form-item label="">
              <el-input v-model=""  :disabled="inputFlag">
                    <template slot="append">万元</template>
              </el-input>
            </el-form-item>
            <el-form-item label="">
              <el-input v-model.number=""  :disabled="inputFlag">
                      <template slot="append">万元</template>
              </el-input>
            </el-form-item>
            <el-form-item label="备注">
              <el-input
                type="textarea"
                v-model=""
                 :disabled="inputFlag"
                rows="3"
              ></el-input>
            </el-form-item>
          </el-form>
        </span>
        <span slot="footer" class="dialog-footer" v-if="!inputFlag">
          <el-button @click="tableClose">取 消</el-button>
          <el-button type="primary" @click="submitTable">确 定</el-button>
        </span>
      </el-dialog>
    </el-card>

script

<script>
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import {
  burgetAdd,
  burgetRemove,
  burgetUpdate,
  burgetFindProject,
  amountList,
  amountAdd,
  amountRemove,
  amountUpdate,
  amountFindProject,
  burgetSubject,
  burgetTree,
} from "@/api/burget";
import { list } from "@/api/user";
export default {
  name: "",
  components: { pages, Treeselect },
  props: {},
  data() {
    return {
      value:null,
      dialogTitle: "", //表格弹窗文本
      inputFlag: false, //查看表格的变量,隐藏取消和确认按钮,禁用弹窗
      nodeDialogVisible: false, //添加树弹窗
      tableDialogVisible: false, //添加表格弹窗
      filterText: "", //树过滤
      num: 0,
      projects: [], //多项目option绑的值
      cateprojects: [], //项目分类option绑的值
      typeSelect: [], //科目类型option绑的值
      activeName: "1",
      tableData: [], //表格数据源
      treeData: [], //权限树数据
      //添加节点表单
      addNodeForm: {
        parent_id: "",
      },
      // 添加表格表单
      addTableForm: {},
      //添加节点表单验证
      addNodeFormRules: {
        project_id: [
          { required: true, message: "请选择项目", trigger: "blur" },
        ],
        title: [{ required: true, message: "请输入标题", trigger: "blur" }],
      },
      // 添加表格验证
      addTableFormRules: {
        type: [
          { required: true, message: "请输入物资名称", trigger: "blur" },
        ],
        cost_target: [
          { required: true, message: "请输入整数", trigger: "blur" },
          { type: "number", message: "必须为数字值", trigger: "blur" },
        ],
      },

      //查询项目
      projectQuery: {
        project_id: "",
        category_id: "",
        page: 1,
        size: 10,
      },

      //多项目数据
      projectForm: {
        page: 1,
        size: 10000,
        tltle: "",
      },
      query: {
        page: "",
        size: "",
        project_id: "",
        parent_id: "",
      },
      buttonList: [
        { value: 1, label: "xx" },
        { value: 2, label: "xx" },
        { value: 3, label: "xx" },
        { value: 4, label: "xx" },
      ],
      // addform: {},

      defaultProps: {
        //树形控件的属性绑定对象
        children: "children", //设置通过children属性展示子节点信息
        label: "title", //通过label设置树形节点文本展示
        isLeaf: "leaf",
      },
    };
  },

  computed: {},
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    },
  },
  created() {
    this.treeDataList();
    this.moreProject();
    this.addProject();
  },
  mounted() {},
  methods: {
    //获取项目列表
    async moreProject() {
      try {
        const data = await list(this.projectForm);
        // console.log("列表", data);
        this.projectForm = data.data;
        this.projects = data.data.items.map((item) => {
          return {
            label: item.title,
            value: item.project_id,
          };
        });
          // window.localStorage.setItem('duoproject',JSON.stringify(this.projects))
      } catch (err) {
        console.log(err);
      }
    },
    // 添加数据弹窗里的科目类型
    async addProject() {
      const data = await burgetSubject(this.addTableForm);
      let obj = data.data;
      for (const key in obj) {
        this.typeSelect.push({
          value: key,
          label: obj[key],
        });
      }
      // console.log(this.typeSelect);
    },
normalizer(node){
  return{
    id:node.id,
    label:node.title,
    children:node.children,
  }
},
    handleCurrentChange() {},
    //获取左侧树
    async treeDataList(id) {
      try {
        const data = await burgetTree();
        this.treeData = data.data;

        // console.log("树数据", data.data);
      } catch (error) {
        console.log(error);
      }
    },
    //树过滤
    filterNode(value, data) {
      if (!value) return true;
      return data.title.indexOf(value) !== -1;
    },
    //树节点点击
    handleNodeClick(data, node) {
      // console.log("点击节点", data, node);
      this.projectQuery.category_id = node.key;
      this.getTableData();
    },
    // 树节点鼠标移入移出
    mouseenter(data) {
      this.$set(data, "show", true);
    },
    mouseleave(data) {
      this.$set(data, "show", false);
    },
    //添加同级节点
    append(node) {
      // console.log("1111111", node, data);
      this.nodeDialogVisible = true;
      this.addNodeForm.parent_id = node.parent.key;
    },
    // 添加子级节点
    appendChild(node) {
      this.nodeDialogVisible = true;
      this.treeDataList();
      this.addNodeForm.parent_id = node.key;
    },
    // 编辑节点
    async editNode(node) {
      const data = await burgetFindProject({ id: node.key });
      // console.log('树节点详情', data);
      if (data.code == 200) {
        this.addNodeForm = data.data;
        this.nodeDialogVisible = true;
      }
    },
    // 删除节点
    deleteNode(node) {
      this.$confirm("是否删除当前节点?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          burgetRemove({ id: node.key }).then((res) => {
            if (res.code == 200) {
              this.$message.success("删除成功");
              this.treeDataList();
            }
          });
        })
        .catch((err) => err);
    },
    //添加、修改节点提交
    submitNode() {
      this.$refs.addNodeRef.validate(async (valid) => {
        if (!valid) return;
        try {
          if (this.addNodeForm.id) {
            var data = await burgetUpdate(this.addNodeForm);
          } else {
            var data = await burgetAdd(this.addNodeForm);
          }
          // console.log('添加树', data);
          if (data.code == 200) {
            this.$message.success("操作成功");
            this.nodeDialogVisible = false;
            this.treeDataList();
            this.addNodeForm = { parent_id: "" };
          }
        } catch (error) {
          console.log(error);
        }
      });
    },
    //添加节点弹窗关闭
    nodeClose() {
      this.addNodeForm = { parent_id: "" };
      this.nodeDialogVisible = false;
    },
    //实现局部刷新,在点击弹窗处调用的
    partialRefreshpartialRefresh(node) {
      //设置loaded为false;模拟一次节点展开事件,加载重命名后的新数据;
      node.loaded = false;
      node.expand();
      //新建子节点是刷新一次本节点的展开请求,而重命名和删除则需要刷新父级节点的的展开事件,
      //可以设置node.parent.loaded = false;node.parent.expand();
    },
    //获取表格数据
    async getTableData() {
      try {
        // console.log('查询入参', this.projectQuery);
        const data = await amountList(this.projectQuery);
        // console.log("表", data);
        if (data.code == 200) {
          this.tableData = data.data.items;
        }
      } catch (error) {
        console.log(error);
      }
    },
    // 查看表格
    reviewworkFile(row) {
      this.dialogTitle = "查看xx";
      this.tableDialogVisible = true;
      this.addTableForm = row;
      this.inputFlag = true;
    },
    //  编辑表格
    editworkFile(row) {
       this.inputFlag = false;
      this.dialogTitle = "编辑xx";
      this.tableDialogVisible = true;
      this.addTableForm = JSON.parse(JSON.stringify(row)); //row当前行数据,把当前行的数据赋值给表单
    },
    //  添加表格
    addworkFile() {
        this.inputFlag = false;
      this.dialogTitle = "新增xx";
      this.tableDialogVisible = true;
    },
    //  删除表格
    async removeworkFile(id) {
      //弹出确定取消框,是否删除用户
      const confirmResult = await this.$confirm(
        "是否要永久删除该条数据",
        "删除提示",
        {
          confirmButtonText: "确认删除",
          cancelButtonText: "取消",
          type: "warning",
        }
      ).catch((err) => err);
      //如果用户点击确认,则confirmResult 为'confirm'
      //如果用户点击取消, 则confirmResult获取的就是catch的错误消息'cancel'
      if (confirmResult != "confirm") {
        return this.$message.info("已经取消删除");
      }
      // console.log(id);
      const data = await amountRemove({ id });
      // console.log(data);
      if (data.code == 200) {
        this.$message.success("删除成功");
        this.treeDataList();
        this.getTableData();
      }
    },
    //添加表格弹窗关闭
    tableClose() {
      this.resetForm();
      this.tableDialogVisible = false;
    },
    // 添加修改弹窗确认事件
    async submitTable() {
      this.$refs.addTableRef.validate(async (valid) => {
        if (!valid) return;
        try {
          if (this.addTableForm.id) {
            var data = await amountUpdate(this.addTableForm);
            // console.log("xiugai", data);
          } else {
            var data = await amountAdd(this.addTableForm);
            // console.log("add", data);
          }
          // console.log('data出参',data);
          if (data.code == 200) {
            this.$message.success("操作成功");
            this.resetForm();
            this.tableDialogVisible = false;
            this.getTableData();
          }
        } catch (error) {
          console.log(error);
        }
      });
    },
    resetForm() {
      this.addTableForm = {
        type: "",
        cost_target: "",
        mark: "",
      };
    },
  },
};
</script>

样式的代码不贴了,写的有点乱,这个自己调试都可以调出来的

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue项目+el-tree,树结构展示,非常完整的代码,包含调接口拿真实数据渲染 的相关文章

随机推荐

  • Image and Graphics Best Practices,总结及延伸

    预备知识 解码 Q 什么是解码 A 将压缩的图片数据解码成未压缩的位图形式 即二进制数据转换成像素数据的过程 PS 这是一个非常耗时的 CPU 操作 Q 是否可以不要解码 不经过解压缩 直接将图片显示到屏幕上 A 不可以
  • 原码和补码在计算机中的应用,二进制、原码、反码和补码详解

    原码反码和补码都是计算机中表示数字的一种编码 维基百科上说 编码是信息从一种形式或格式转换为另一种形式的过程 其实 计算机内部使用二进制 n位的二进制一共可以表示2 n个不同的数字 至于具体哪个二进制序列对应哪个数字 原则上可以随意 例如
  • 边界值分析法

    一 定义 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法 通常边界值分析法是作为对等价类划分法的补充 这种情况下 其测试用例来自等价类的边界 边界值分析法是对等价类划分法做补充的一种黑盒测试设计方法 实践中 由于大量的错误发
  • 字符与字符串的“+”操作

    字符的 操作 public class Firstproj public static void main String args 定义两个变量 int i 10 char c A A 的值是65 ASCII值 c a a 的值是97 c
  • redis之安装部署

    redis之安装部署 redis之基本使用 redis之应用场景 redis之源码制作rpm包 redis之安装部署 1 redis 6 2 12单机部署 1 1 redis 6 2 12下载安装 1 2 查看服务进程 2 redis 6
  • IOS 基础开发之 addSubview和insertSubview:atIndex: 区别

    两者都是添加子视图 视图的添加都是以栈的方式 即后进先出 addSubview 是添加到最后 即最后一个进栈 显示在所有子视图的最上面 insertSubview AtIndex 是根据索引添加到栈里面 可以根据需要添加到对应的栈的位置里面
  • android 语音识别 语音手电(一)

    一 语音识别库 cmu pocketsphinx 当然要用现成的语音识别库了 自己的水平离开发语音识别库还远的很呢 网上搜索找到卡内基梅龙大学的开源语音项目 好象是李开复创办的项目 有JAVA实现 有C语言实现 pocketsphinx是专
  • 使用vscode编码器统计代码行数

    在一些特殊情况中我们需要计算代码的行数 这时我们就可以借助vscode的VS Code Counter插件进行统计 第一步 选择VS Code Counter进行安装 安装完毕有条件的可以重启编码器 第二步 快捷键ctrl shift p进
  • Tensorflow 下测试gpu是否可用

    import tensorflow as tf tf test is gpu available
  • servlet和java区别_java – servlet和Web服务之间的区别

    Web服务是一种使用REST编程范例或SOAP协议为其客户端提供服务方法以进行通信的服务 有几种方法来实现Web服务 编写Web服务的最简单的方法是编写一个类并使用javax jws中的 WebService和 WebMethod注释进行注
  • php 导出excel的三种方法

    1 PHPExcel thinkphp PHPExcel放到这个目录下 导出excel表格 function exportExcel data filename xlsTitle iconv utf 8 gb2312 filename 文件
  • BI工程师日记

    从17年十月份入职BI工程师半年多的时间里 已熟练使用Tableau及SQL 越来越感觉到tableau的天花板 思考了好久如何打破天花板 想从几个方面入手 1 学习Python数据处理 神经网络庫的使用 结合tableau和Python
  • kubeadm 安装集群 1.16.12

    kubeadm 安装集群 添加源 mirror https mirrors aliyun com mirror https mirrors ustc edu cn docker 源 curl fsSL mirror docker ce li
  • 【喊7的次数重排】

    题目描述 喊7的次数重排 喊7是一个传统的聚会游戏 N个人围成一圈 按顺时针从1到N编号 编号为1的人从1开始喊数 下一个人喊的数字为上一个人的数字加1 但是当将要喊出来的数字是7的倍数或者数字本身含有7的话 不能把这个数字直接喊出来 而是
  • 对串级PID控温算法的解析

    目录 前言 单级PID 串级PID 系统分析 算法分析 总结 前言 笔者在做项目的过程中 需要对一个目标物体做精确控温 精度要求 1 需要在两分钟内使用电阻发热贴将温度由20控制到41 且无超调 根据控制原理 做精确控温应该使用PID算法
  • 026-从零搭建微服务-文件服务(二)

    写在最前 如果这个项目让你有所收获 记得 Star 关注哦 这对我是非常不错的鼓励与支持 源码地址 后端 https gitee com csps mingyue 源码地址 前端 https gitee com csps mingyue u
  • 【点云】PointCNN: Convolution On X-Transformed Points

    目录 测试 1 摘要 2 介绍 3 PointCNN 3 1 分层卷积 3 2 X Conv操作 3 3 PointCNN结构 4 参考 4 1 ELU激活函数 4 2 BatchNorm 测试 在Semantic3D上跑了PointCNN
  • jitter概念理解

    一般 PLL等时钟产生模块 都会有RMS jitter的描述 根据这个参数 可以计算出相关时钟的clock jitter 方便设置综合sdc的时钟约束 为什么只有RMS jitter 因为期望值就是理论周期值 根据期望值 RMS 均方差 就
  • 数据运营-计算留存率和转化率(漏斗分析&Python)

    一 案例数据 在数据运营中 留存率分析和转化率 漏斗 分析是经常用到的 本文结合具体案例总结了如何利用python求n日留存率以及各环节间转化率 指标释义 案例数据集介绍 本文是利用淘宝app的运营数据进行分析的 数据集中包含以下字段 部分
  • vue项目+el-tree,树结构展示,非常完整的代码,包含调接口拿真实数据渲染

    温故而知新 最近项目中频繁使用树形结构展示效果 因为不熟悉 备受折磨 代码贴出来 再复习一次 代码太长了 想看分析的可以搜我下一篇文章 下一篇会详细的写如何在项目中使用 效果 左侧是树 右侧是表格 点击任何一行都会展示对应的表格 完整代码如