当前位置:网站首页>Making interactive page of "left tree and right table" based on jeecg-boot
Making interactive page of "left tree and right table" based on jeecg-boot
2022-07-06 06:25:00 【Hanyue Zhuge crossbow】
Pre knowledge :
1、ant-design-vue
2、vue Of slot Concept
Demand effect :

As shown in the above interface .
Back end unchanged , be based on jeecg-boot Generated code , Front end customization , Divided into left and right pieces , Typical “ Left tree, right table ” structure . Achieve the goal :
1、 The tree structure on the left is generated from two tables , And encapsulated into a control , Convenient for repeated calls later ;
2、 List on the right , By default, the associated data of the clicked leaf node is displayed , After clicking save , Save the final result ;
3、 adopt ant-design-vue Unified UI style
Specific development :
1、 Encapsulation of tree control
(1) Back end code : Get the node data of the tree structure to be generated from the database ;
First , Define tree structure properties . here , Defines a general class , according to jeecg-boot recommend , Establish directories and files according to specifications

(2) Build the back-end node to generate code


(3) Build the front-end code , Encapsulated as a control

script The code under is relatively simple , Look directly at the code .
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()
}
}Pay attention to two places :
(1) Attribute construction of nodes . You can build non essential attributes of any tree node , adopt dataRef Visit
(2) When broadcasting events , You can package some commonly used information in one object in , Convenient reuse . My approach is as follows :

2、 list
Template The layout is as follows :

Script The code structure :

What to pay attention to :
(1)scopedSlots and slots( The official website documents are not very clear , It depends on the code )
scopedSlots: slot table Of cell Area
slots: slot table Of title Area , Used slots,column There can be no single title attribute , otherwise slots invalid .

(2) utilize jeecg-boot Encapsulated front-end controls , Various controls can be found on the official website , You can also go directly to the generated vue Find under file . As used in this example , Associated with the table 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'> preservation </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=" yes " un-checked-children=" no " v-model='record.isObservingItem' />
</span>
<span slot="isMaintainingItem" slot-scope="text, record">
<a-switch checked-children=" yes " un-checked-children=" no " 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: ' The index type ', dataIndex: 'itemTypeId', key: 'itemTypeId', width: 80, scopedSlots:{customRender:'itemTypeId'}},
{title: ' Index name ', dataIndex: 'itemName', key: 'itemName', width:120,scopedSlots:{customRender:'itemName'}},
{title: ' Display type ', dataIndex: 'dataShowingTypeId', key: 'dataShowingTypeId', width:80,scopedSlots:{customRender:'dataShowingTypeId'}},
{title: ' The default value is ', dataIndex: 'defaultValue', key: 'defaultValue', width: 80,scopedSlots:{customRender:'defaultValue'}},
{title: ' Company ', dataIndex: 'unit', key: 'unit', width: 80,scopedSlots:{customRender:'unit'}},
{title: 'PLC Address ', dataIndex: 'plcPlace', key: 'plcPlace', width: 80,scopedSlots:{customRender:'plcPlace'}},
{title: 'PLC data type ', dataIndex: 'plcType', key: 'plcType', width: 100,scopedSlots:{customRender:'plcType'}},
{title: ' Whether to focus on observation ', dataIndex: 'isObservingItem', key: 'isObservingItem', width: 80,scopedSlots:{customRender:'isObservingItem'}},
{title: ' Whether maintenance monitoring ', 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(" Please select the equipment model .")
}
},
addRow:function(){
if(this.selectedDeviceTypeId == ''){
this.$message.warning(" Please select the equipment model .")
}
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>边栏推荐
- 自定义指定路由上的Gateway过滤器工厂
- 黑猫带你学UFS协议第4篇:UFS协议栈详解
- 测试周期被压缩?教你9个方法去应对
- 模拟卷Leetcode【普通】1296. 划分数组为连续数字的集合
- LeetCode 729. My schedule I
- JDBC requset corresponding content and function introduction
- 联合索引的左匹配原则
- Simulation volume leetcode [general] 1414 The minimum number of Fibonacci numbers with a sum of K
- Past and present lives of QR code and sorting out six test points
- Basic knowledge of MySQL
猜你喜欢

E - food chain

keil MDK中删除添加到watch1中的变量

联合索引的左匹配原则

win10无法操作(删除、剪切)文件

Apple has open source, but what about it?

E - 食物链

Database - current read and snapshot read

org. activiti. bpmn. exceptions. XMLException: cvc-complex-type. 2.4. a: Invalid content beginning with element 'outgoing' was found
![[web security] nodejs prototype chain pollution analysis](/img/b6/8eddc9cbe343f2439da92bf342b0dc.jpg)
[web security] nodejs prototype chain pollution analysis

Customize the gateway filter factory on the specified route
随机推荐
Data type of MySQL
如何将flv文件转为mp4文件?一个简单的解决办法
Understanding of processes and threads
Black cat takes you to learn EMMC Protocol Part 10: EMMC read and write operation details (read & write)
Aike AI frontier promotion (2.13)
Properties file
selenium源码通读·9 |DesiredCapabilities类分析
还在为如何编写Web自动化测试用例而烦恼嘛?资深测试工程师手把手教你Selenium 测试用例编写
Delete the variables added to watch1 in keil MDK
技术分享 | 常见接口协议解析
Isam2 operation process
Engineering organisms containing artificial metalloenzymes perform unnatural biosynthesis
职场进阶指南:大厂人必看书籍推荐
Left matching principle of joint index
Esp32 esp-idf watchdog twdt
Isam2 and incrementalfixedlagsmooth instructions in gtsam
LeetCode 732. My schedule III
php使用redis实现分布式锁
模拟卷Leetcode【普通】1109. 航班预订统计
黑猫带你学UFS协议第4篇:UFS协议栈详解