当前位置:网站首页>基于JEECG-BOOT制作“左树右表”交互页面
基于JEECG-BOOT制作“左树右表”交互页面
2022-07-06 06:19:00 【瀚岳-诸葛弩】
前置知识:
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>
边栏推荐
猜你喜欢
The latest 2022 review of "graph classification research"
Manage configuration using Nacos
GTSAM中李群的運用
Basic knowledge of error
[wechat applet] build a development tool environment
G - Supermarket
Nodejs realizes the third-party login of Weibo
selenium源码通读·9 |DesiredCapabilities类分析
全链路压测:构建三大模型
【微信小程序】搭建开发工具环境
随机推荐
Simulation volume leetcode [general] 1109 Flight reservation statistics
Overview of three core areas of Mathematics: geometry
Cannot create PoolableConnectionFactory (Could not create connection to database server. 错误
Hypothesis testing learning notes
一文揭开,测试外包公司的真 相
B - The Suspects
Isam2 and incrementalfixedlagsmooth instructions in gtsam
自定义指定路由上的Gateway过滤器工厂
【eolink】PC客户端安装
黑猫带你学UFS协议第4篇:UFS协议栈详解
Construction and integration of Zipkin and sleuth for call chain monitoring
10m25dcf484c8g (FPGA) amy-6m-0002 BGA GPS module
ESP32 ESP-IDF看门狗TWDT
G - Supermarket
Manhattan distance and Manhattan rectangle - print back font matrix
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
MySQL之数据类型
调用链监控Zipkin、sleuth搭建与整合
【Postman】Collections配置运行过程
PAT(乙级)2022年夏季考试