当前位置:网站首页>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>
边栏推荐
- Simulation volume leetcode [general] 1296 Divide an array into a set of consecutive numbers
- 黑猫带你学UFS协议第4篇:UFS协议栈详解
- Simulation volume leetcode [general] 1249 Remove invalid parentheses
- 二维码的前世今生 与 六大测试点梳理
- Redis core technology and basic architecture of actual combat: what does a key value database contain?
- Engineering organisms containing artificial metalloenzymes perform unnatural biosynthesis
- E - 食物链
- MySQL之数据类型
- E - food chain
- G - Supermarket
猜你喜欢
职场进阶指南:大厂人必看书籍推荐
On weak network test of special test
调用链监控Zipkin、sleuth搭建与整合
Engineering organisms containing artificial metalloenzymes perform unnatural biosynthesis
Customize the gateway filter factory on the specified route
Oscp raven2 target penetration process
B - The Suspects
How to extract login cookies when JMeter performs interface testing
Pat (Grade B) 2022 summer exam
JWT-JSON WEB TOKEN
随机推荐
Defense (greed), FBI tree (binary tree)
Redis core technology and basic architecture of actual combat: what does a key value database contain?
LeetCode 739. Daily temperature
D - How Many Answers Are Wrong
联合索引的左匹配原则
Thoughts on data security (Reprint)
Avtiviti创建表时报错:Error getting a new connection. Cause: org.apache.commons.dbcp.SQLNestedException
Drug disease association prediction based on multi-scale heterogeneous network topology information and multiple attributes
[postman] the monitors monitoring API can run periodically
浅谈专项测试之弱网络测试
[eolink] PC client installation
Luogu p2141 abacus mental arithmetic test
Left matching principle of joint index
Database isolation level
MFC 动态创建的对话框及改变控件的大小和位置
keil MDK中删除添加到watch1中的变量
测试周期被压缩?教你9个方法去应对
Simulation volume leetcode [general] 1143 Longest common subsequence
模拟卷Leetcode【普通】1062. 最长重复子串
Web界面元素的测试