基于JEECG-BOOT制作“左树右表”交互页面

13 篇文章 4 订阅
订阅专栏
11 篇文章 1 订阅
订阅专栏

前置知识:

1、ant-design-vue

2、vue的slot概念

需求效果:

如上界面所示。

后端不改动,基于jeecg-boot生成的代码,前端自定义,分为左右两块,典型的“左树右表”结构。实现目的:

1、左边树结构从两张表生成,并封装成控件,方便后期重复调用;

2、右边列表,默认展示点击的叶子节点的关联数据,点击保存后,保存最终结果;

3、通过ant-design-vue统一UI风格

具体开发:

1、树控件的封装

(1)后端代码:从数据库取出要生成的树结构的节点数据;

首先,定义树结构属性。此处,定义了一个通用类,按照jeecg-boot推荐,按规范建立目录和文件

(2)构建后端节点生成代码

(3)构建前端代码,封装成控件

script下的代码比较简单,直接看代码。

import { getAction } from '@api/manage'

export default {
  name: 'DictDeviceTypeTree',
  data() {
    return {
      treeData: [],
      componentHeight: document.documentElement.clientHeight - 185
    }
  },
  methods: {
    onLoadData(selectedNode) {
      let that = this

      let catalogId = 0
      if (selectedNode != null) {
        catalogId = selectedNode.dataRef.id
      }

      let params = new Object()
      params.catalogId = catalogId



      return new Promise(resolve => {
        getAction('/jeecg-product/dict.device_catalog_type/queryByCatalogId', params).then(function(res) {
          res.result.forEach(function(treeNode) {

            let node = new Object()

            node.key = treeNode.key
            node.title = treeNode.title
            node.isLeaf = treeNode.isLeaf
            node.id = treeNode.id
            node.pid = treeNode.pid
            node.icon = <a-icon type={treeNode.icon} />
            node.nodeType = treeNode.nodeType
            node.children = []


            if (selectedNode != null) {
              node.path = selectedNode.dataRef.path + '-' + node.title
            } else {
              node.path = node.title
            }
            if (selectedNode == null) {
              that.treeData.push(node)
            } else {
              selectedNode.dataRef.children.push(node)
            }
          })
        })
        resolve()
      })
    },
    onSelectNode(nodeId, e) {
      let param = new Object()
      param.node = e.node.dataRef
      param.id = e.node.dataRef.key
      param.path = e.node.dataRef.path
      param.title = e.node.dataRef.title
      param.nodeType = e.node.dataRef.nodeType
      this.$emit('SelectNode', param)
    }
  },
  created() {
    this.onLoadData()
  }
}

注意两个地方:

(1)节点的属性构建。可以构建任意树节点的非必须属性,通过dataRef进行访问

(2)广播事件时,可以将一些常用的信息打包在一个object中,方便复用。我的做法如下:

2、列表

 

Template的布局如下:

Script代码结构:

需要注意的地方:

(1)scopedSlots和slots(官网文档讲的不是很清,要看代码)

scopedSlots:插槽table的cell区域

slots:插槽table的title区域,使用了slots,column就不能有单独的title属性,否则slots失效。

(2)利用jeecg-boot封装好的前端控件,各种控件可看官网,也可直接到生成的vue文件下找。如本文例子用用到的,与表关联的dropdownlist:

<j-dict-select-tag type='list' dictCode='dict_device_item_type,item_type,id' v-model='record.itemTypeId' style='width:100%' />
<template>
  <a-row :gutter='16'>
    <a-col :span='4'>
      <DictDeviceTypeTree @SelectNode='nodeClick'></DictDeviceTypeTree>
    </a-col>
    <a-col :span='20'>
      <a-button type="primary" @click='saveData'>保存</a-button>
      <a-table :columns="columns" :data-source="data" :pagination='false' style='background: #fff'>
          <span slot="itemTypeId" slot-scope="text, record">
              <j-dict-select-tag type='list' dictCode='dict_device_item_type,item_type,id' v-model='record.itemTypeId' style='width:100%' />
          </span>
          <span slot="itemName" slot-scope="text, record">
              <a-input v-model='record.itemName' />
          </span>
          <span slot="dataShowingTypeId" slot-scope="text, record">
              <j-dict-select-tag type='list' dictCode='dict_data_showing_type,data_showing_type,id' v-model='record.dataShowingTypeId' style='width:100%' />
          </span>
          <span slot="defaultValue" slot-scope="text, record">
              <a-input v-model='record.defaultValue' />
          </span>
          <span slot="unit" slot-scope="text, record">
              <a-input v-model='record.unit' />
          </span>
          <span slot="plcPlace" slot-scope="text, record">
              <a-input v-model='record.plcPlace' />
          </span>
          <span slot="plcType" slot-scope="text, record">
              <a-input v-model='record.plcType' />
          </span>
          <span slot="isObservingItem" slot-scope="text, record">
              <a-switch checked-children="是" un-checked-children="否" v-model='record.isObservingItem' />
          </span>
          <span slot="isMaintainingItem" slot-scope="text, record">
              <a-switch checked-children="是" un-checked-children="否" v-model='record.isMaintainingItem' />
          </span>

          <span slot="operTitle">
            <a-button type="primary" @click='addRow'>+</a-button>
          </span>
          <span slot="oper" slot-scope="text, record">
              <a-button type="danger" @click='delRow(record.key)'>—</a-button>
          </span>
      </a-table>
    </a-col>
  </a-row>
</template>

<script>
import DictDeviceTypeTree from '@comp/product/DictDeviceTypeTree'
import { httpAction, getAction } from '@api/manage'

export default {
  name: 'test',
  components: {
    DictDeviceTypeTree
  },
  data(){
    return {
      columns:[
        {title: '指标类型', dataIndex: 'itemTypeId', key: 'itemTypeId', width: 80, scopedSlots:{customRender:'itemTypeId'}},
        {title: '指标名称', dataIndex: 'itemName', key: 'itemName', width:120,scopedSlots:{customRender:'itemName'}},
        {title: '显示类型', dataIndex: 'dataShowingTypeId', key: 'dataShowingTypeId', width:80,scopedSlots:{customRender:'dataShowingTypeId'}},
        {title: '默认值', dataIndex: 'defaultValue', key: 'defaultValue', width: 80,scopedSlots:{customRender:'defaultValue'}},
        {title: '单位', dataIndex: 'unit', key: 'unit', width: 80,scopedSlots:{customRender:'unit'}},
        {title: 'PLC地址', dataIndex: 'plcPlace', key: 'plcPlace', width: 80,scopedSlots:{customRender:'plcPlace'}},
        {title: 'PLC数据类型', dataIndex: 'plcType', key: 'plcType', width: 100,scopedSlots:{customRender:'plcType'}},
        {title: '是否重点观测', dataIndex: 'isObservingItem', key: 'isObservingItem', width: 80,scopedSlots:{customRender:'isObservingItem'}},
        {title: '是否维修监控', dataIndex: 'isMaintainingItem', key: 'isMaintainingItem', width: 80,scopedSlots:{customRender:'isMaintainingItem'}},
        {dataIndex: 'oper', key: 'oper', width: 80,scopedSlots:{customRender:'oper'},slots:{title:'operTitle'}},
      ],
      data:[],
      selectedDeviceTypeId:''
    }
  },
  methods: {
    nodeClick: function(selectedNode) {
      let that = this
      if(selectedNode.nodeType == "deviceType"){
        that.selectedDeviceTypeId = selectedNode.id;
        that.data = []
        let params  = new Object()

        params.DeviceTypeId = that.selectedDeviceTypeId

        getAction('/jeecg-product/dict.device_item/dictDeviceItem/queryDeviceTypeId', params).then(function(res) {
          res.forEach(function(item) {
            let deviceItem = new Object()
            deviceItem.deviceTypeId = that.selectedDeviceTypeId
            deviceItem.key = item.id
            deviceItem.itemTypeId = item.itemTypeId
            deviceItem.itemName = item.itemName
            deviceItem.dataShowingTypeId = item.dataShowingTypeId
            deviceItem.defaultValue = item.defaultValue
            deviceItem.unit = item.unit
            deviceItem.plcPlace = item.plcPlace
            deviceItem.plcType = item.plcType
            deviceItem.isObservingItem = item.isObservingItem
            deviceItem.isMaintainingItem = item.isMaintainingItem

            that.data.push(deviceItem)
          })
        })
      }
      else{
        this.selectedDeviceTypeId = ''
        this.$message.warning("请选择设备型号。")
      }
    },
    addRow:function(){
      if(this.selectedDeviceTypeId == ''){
        this.$message.warning("请选择设备型号。")
      }
      else{
        this.data.push(
          {
            key:this.guid(),
            deviceTypeId:this.selectedDeviceTypeId,
            itemTypeId:'',
            itemName:'',
            dataShowingTypeId:'',
            defaultValue:'',
            unit:'',
            plcPlace:'',
            plcType:'',
            isObservingItem:0,
            isMaintainingItem:0
          }
        )
      }

    },
    delRow:function(key){
      // alert(key)
      let that = this
      this.data.forEach(function(item, index) {
        if(item.key == key){
            that.data.splice(index,1)
        }
      })
    },
    saveData:function(){
      let that = this
      if(this.data.length == 0){
        let httpurl='/jeecg-product/dict.device_item/dictDeviceItem/delByDeviceTypeId'

        let params = new Object();
        params.deviceTypeId = that.selectedDeviceTypeId

        getAction(httpurl, params).then(function(res) {
          that.$message.success(res.message);
          that.$emit('ok');
        })

      }
      else{
        let httpurl='/jeecg-product/dict.device_item/dictDeviceItem/delAndSaveBatch'
        let method = 'post'

        this.data.forEach(function(item){
          item.isObservingItem = (item.isObservingItem==true?1:0)
          item.isMaintainingItem = (item.isMaintainingItem==true?1:0)
        })
        httpAction(httpurl,this.data,method).then((res)=>{
          if(res.success){
            that.$message.success(res.message);
            that.$emit('ok');
          }else{
            that.$message.warning(res.message);
          }
        }).finally(() => {
          that.confirmLoading = false;
        })
      }
    },
    guid:function(){
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
        return v.toString(16);
      })
    }
  }
}
</script>

<style scoped>

</style>

左树右表demo
weixin_43487876的博客
06-01 669
左树右表-数据demo 1. 后端出接口: 字段说明:(所有字段大小写敏感) 字段 是否必须 类型 默认值 说明 1. NAME Y String undefined 展示的节点名字 2. ID Y Number/String – 结点ID 3. PARENT_ID – Number/String – 指定父节点的ID 4. open N Boolean false 是否默认打开当前节点 2. 接口数据demo如下: { "code": 0, "data": [
Jeecg自定义树形表单
wudong
07-14 1515
有时候表单中会使用到树形表单,那么我们因该前端添加代码。 <t:datagrid name="zdxmMainList" pagination="false" isShowSearch="true" fit="true" fitColumns="true" actionUrl="url" idField="id" extendParams="view: detailview,detailFormatter:detailFormatterFun,onExpandRow: onExpandRowFun"
element ui 左树右表_JeeSite 4.x 实现树结构表(左树右表
weixin_39868959的博客
11-21 1343
在官方在线文档中找了半天,也没有找到明了的实现左树右表的方法,于是总结在本文当中1 MySql数据库中建立所需表1.1CREATE 1.2CREATE TABLE `intern_notice_tree` ( `tree_code` varchar(64) NOT NULL COMMENT '节点编码', `parent_code` varchar(64) NOT NULL COMMENT...
通过vue实现左侧树状右侧的组件
最新发布
weixin_51391923的博客
03-01 823
通过vue实现左侧树状右侧的组件
jeecg左右布局左树右表
chuanshang181的博客
07-31 6195
jeecg版本3.7.2 效果: 主要照抄jeecg demo里常用示例的树编辑。 数据库里建两个表,一个cfg_tree定义左边的树,一个cfg放右边的表单数据。 两个表直接用jeecg的在线开发online表单开发,创建表单再代码生成。 cfg表没啥特殊操作,就普通表单建。然后自己在cfg表里面加一个字段parentcfgid,作为上级配置项。parentcfgid的值就复制上...
左树右对话框
11-15
左树右对话框
jeecgboot 左树右表记录
qq_34629947的博客
06-02 1104
左树又表 格式
Jeecgboot:中国省市区树形数据生成
1111111111
02-20 1583
Jeecgboot的省市区数据来源于china-area-data组件,我们先利用框架自带的area.js生成具有pid和hasChild字段的表格数据。导入的时候每条记录的id是系统随机生成的,但是我们设置的pid是每个地点的code,并不是每条记录的id,这样导致页面只能看到省份,下面的子节点无法显示。Jeecgboot框架自带省市区下拉选项,但是我们的项目需要使用树形勾选,所以需要进行改造。打开csv文件,去掉所有空格,然后使用online表单的导入功能,将数据写入数据库。
jeecg-boot书写一个左右联动页面
qq_38215042的博客
11-02 893
目录标题1:最终效果图(红色框)1 1:最终效果图(红色框) 1
Vue.js知识点总结 (element框架混用 制作一个左树右表布局)
01-08
element是基于vue.js框架开发的快速搭建前端的UI框架。 因为有小伙伴做项目时不知道怎么去引入使用来布局,今天我就来教大家如何简单上手 首先要提的就是,你在做这个混用操作前,得会vue框架的单文件组件的模式操作...
entfrm-boot可视化开发平台-其他
06-12
代码生成:支持单表、树表、左树右表代码生成。5、API引擎应用管理:应用新增、修改、删除、查看。API设计:API在线设计、无代码开发,支持自定义。API文档与测试:API文档生成与自动化测试。API资源权限:API资源...
创建左树右表基础资料1
08-08
创建左树右表基础资料1
左侧树形菜单+右侧页面+sql2000
12-19
一个页面,左侧是树形菜单,菜单是三级的,右侧根据左侧菜单而响应不同的结果页面页面和SqlServer2000数据连接,实现了对数据库的插入操作。可以根据自己的需要扩展。
vue左侧菜单,树形图递归实现代码
10-18
主要介绍了vue左侧菜单,树形图递归实现代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
jeesite左树右表开发
一直在路上的JunGle
10-11 3767
**1、在上一篇文章介绍单表增删改查基础上,我们可以仿照系统原有的结构复制部分代码来实现,首先复制userindex.jsp到自己创建的jsl目录,跟form和list表一个 目录,修改名字以及内容,如下图:** **2、配置好系统的菜单,原理大致就是在jslMachineIndex.jsp的树结构上,点击节点就会把对应的节点的officeid传到后台自定义的jslMachineControll
EAS BOS 左树右表实现
jonny_deng
01-12 2377
1、创建左树右表形式的UI,为treeMain添加值改变事件保存并发布 为treeMain添加值改变事件: 2、对发布后生成的代码进行修改 package com.kingdee.eas.dj.test.client; import javax.swing.event.TreeSelectionEvent; import org.apache.log4j.Logger; impo...
antd vue tree table 左侧树 右侧表格 根据树选择筛选
xw245184020的专栏
06-25 1682
<template> <div> <div style=" display: flex; justify-content: space-between; height: 20rem; background: white; margin-bottom: 2rem; " > <a-tree row-key="index.
jeecg单表数据查询
qq_42799116的博客
09-28 2020
以医生表,通过名称查询医生信息为例 一、确定返回的字段信息 1、类名称 DoctorReqVo.java 2、位置 jeecg-boot-base-common/src/main/java/org.jeecg.common/modules/doctor/vo/ 3、类细节 package org.jeecg.common.modules.doctor.vo; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.
JEECG技术博文】JEECG表单配置-树形表单
fswhwd的博客
02-08 371
JEECG技术博文】JEECG表单配置-树形表单
element-ui实现左树右列表
10-11
要实现左树右列表的布局,可以使用 Element UI 的 Tree 和 Table 组件结合使用。以下是一个简单的示例: ```html <template> <div> <el-row :gutter="20"> <el-col :span="8"> <el-tree :data="treeData" node-key="id" default-expand-all @node-click="handleNodeClick" ></el-tree> </el-col> <el-col :span="16"> <el-table :data="listData" border> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> <el-table-column prop="gender" label="性别"></el-table-column> </el-table> </el-col> </el-row> </div> </template> <script> export default { data() { return { treeData: [ { id: 1, label: '分类1', children: [ { id: 11, label: '子分类1' }, { id: 12, label: '子分类2' }, ], }, { id: 2, label: '分类2', children: [ { id: 21, label: '子分类3' }, { id: 22, label: '子分类4' }, ], }, ], listData: [ { name: '张三', age: 20, gender: '男' }, { name: '李四', age: 25, gender: '女' }, { name: '王五', age: 30, gender: '男' }, ], }; }, methods: { handleNodeClick(data) { // 根据点击的树节点更新右侧列表数据 // 这里可以根据需要进行异步请求获取数据 // 然后更新 listData }, }, }; </script> ``` 在上面的示例中,使用了 `<el-tree>` 组件实现左侧的树状结构,通过 `treeData` 数据来渲染树节点。当点击树节点时,可以通过 `handleNodeClick` 方法来处理点击事件,例如根据点击的节点获取相关数据并更新右侧的列表数据。 在右侧使用了 `<el-table>` 组件来展示列表数据,通过 `listData` 数据来渲染表格内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 利用Emgu.CV实现人脸识别详解 (C#)--附源码 49916
  • Emgu.CV训练自己的hog特征,可实现任意物体的检测 13012
  • vue 2.x与ant-desing-vue的安装与版本兼容问题 5884
  • JEECG微服务架构配置和运行 4132
  • 《三国演义》与“项目管理”——从诸葛亮的锦囊妙计再谈团队管理 3520

分类专栏

  • .net/c# 5篇
  • 深度学习 4篇
  • VUE 11篇
  • JAVA 13篇
  • Jquery 3篇
  • 项目管理 5篇
  • 数据库 2篇
  • 生活杂记
  • 我做IT的这些年 1篇
  • 看《三国演义》 1篇
  • 悟管理之道 2篇

最新评论

  • 基于人体骨架序列的单步动作时序定位策略(原创)

    瀚岳-诸葛弩: 默认给一个尺度即可,我的默认设置是45帧

  • 基于人体骨架序列的单步动作时序定位策略(原创)

    Crossi: 楼主你好,实际推理的时候,这个探测器选择怎样的尺度呢?需要多尺度吗?还有这个代码主页无法打开

  • 在JEECG-boot代码生成的基础上修改list页面(结合自定义的组件)

    jc_chang: 按照这个配置后,父目录获得焦点后右边的表获取不到列表的值,只能获取到子目录的列表值,请教怎样处理?

  • Emgu.CV训练自己的hog特征,可实现任意物体的检测

    大菜比陈志成: region 里的进度里代码是什么啊

  • 基于JEECG-BOOT制作“左树右表”交互页面

    一个生活在底层的小小码农: Mark

最新文章

  • 基于可解释性特征矩阵与稀疏采样全局特征组合的人体行为识别
  • 面向零样本学习的人体行为识别深度网络模型
  • “数据中台、读写分离、表分区”解决MySQL 单表数据量、并放量双高的效率瓶颈
2023年2篇
2022年20篇
2021年3篇
2017年2篇
2016年4篇
2015年3篇
2013年7篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

深圳SEO优化公司伊春SEO按天扣费价格民治网站推广推荐玉溪高端网站设计哪家好乐山外贸网站建设庆阳模板制作多少钱岳阳网站改版公司贺州网站关键词优化哪家好忻州网站优化按天扣费固原模板推广价格宁德营销型网站建设公司通化网站推广推荐宜昌网页设计哪家好马鞍山阿里店铺托管多少钱镇江优化滁州百姓网标王推广坪地SEO按天收费哪家好铜仁百姓网标王公司厦门如何制作网站公司大芬网站优化按天计费达州关键词按天扣费价格潍坊网站关键词优化价格海西网站改版推荐伊春网站建设设计多少钱南阳网页制作推荐海东关键词排名公司临汾网站推广工具多少钱黄南网站制作公司太原建设网站广元关键词按天收费公司商洛外贸网站制作价格歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化