Ⅰ、Element-plus
提供的Transfer
树形控件组件与想要目标情况的对比:
1、Element-plus
提供Transfer
组件情况:
其一、Element-ui
自提供的Transfer
代码情况为(示例的代码):
<template>
<p style="text-align: center; margin: 0 0 20px">
Customize data items using render-content
</p>
<div style="text-align: center">
<el-transfer
v-model="leftValue"
style="text-align: left; display: inline-block"
filterable
:left-default-checked="[2, 3]"
:right-default-checked="[1]"
:titles="['Source', 'Target']"
:button-texts="['To left', 'To right']"
:format="{
noChecked: '${total}',
hasChecked: '${checked}/${total}',
}"
:data="data"
@change="handleChange"
>
<template #left-footer>
<el-button class="transfer-footer" size="small">Operation</el-button>
</template>
<template #right-footer>
<el-button class="transfer-footer" size="small">Operation</el-button>
</template>
</el-transfer>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const generateData = () => {
const data = []
for (let i = 1; i <= 15; i++) {
data.push({
key: i,
label: `Option ${i}`,
disabled: i % 4 === 0,
})
}
return data
}
const data = ref(generateData())
const leftValue = ref([1])
</script>
<style>
.transfer-footer {
margin-left: 15px;
padding: 6px 5px;
}
</style>
代码地址:https://element-plus.gitee.io/zh-CN/component/transfer.html
其二、页面的显示情况为:
Ⅱ、在项目中使用 Transfer
组件遇到的问题:
1、在 table
表格中选中值后,并调用 transfer
后右侧的已选端口值不展示:
其一、代码:
// 此下的有些代码是默认不展示的:
<script setup>
import axios from 'axios';
const rootapi = inject("rootapi");
import { ref,inject,onMounted,reactive } from 'vue'
import { ElMessage } from 'element-plus'
const addFormRef = ref(null)
const aggrEditFormRef = ref(null)
const aggrEditDialogVisible = ref(false)
const aggrLabelWidth = '100px'
const edit_table_data = ref([])
const aggrEditForm = ref({})
const multipleTable = ref('')
const value = ref([])
const checkedArray = ref([])
const rightPorts = ref([])
// const configurationForm = ref({
// lag_mode: "hash_mac"
// })
const addForm = ref({
lag_id: ''
})
const tableData = ref([])
// 生成有效端口值;
const generateData = () => {
const data = []
for (let i = 1; i <= 28; i++) {
data.push({
key: i,
// key: `${i}`,
label: `GigabitEthernet0/${i}`
})
}
return data
}
// 注意:此时 generateData() 函数一定要在定义 data 数据前,才不会报错;
const data = ref(generateData())
const tableRowClassName = (val) => {
if(val.rowIndex %2 === 0) {
return 'success-row'
} else {
return 'warning-row'
}
}
// 添加 LAG 的校验;
const checkAggrLag = (rule, value, callback) => {
if (!value) {
return callback(new Error('此处不能为空'))
}
setTimeout(() => {
if(/^([1-9]|(1[0-6]))$/.test(value)) {
callback()
} else {
callback(new Error('请填写 1~16 的值'))
}
}, 10)
}
// 添加 LAG 聚合表组的校验;
const addRules = ref({
lag_id: [
{required: true, validator: checkAggrLag, trigger: 'blur' }
]
})
// 聚合组表的单选操作(之前仅存在第一次进入右侧没数据的代码);
const changeSelect = (val) => {
// edit_table_data.value = val
// console.log(edit_table_data.value,111111);
let res = val.map((item) => {
let obj = {
lag_id: item.lag_id,
member_ports: item.member_ports.map(item => {
return item.split('/')[1]
})
}
return obj
})
// rightPorts.value=res
edit_table_data.value = res
handleRightChange()
console.log(edit_table_data.value,1111111);
// select_table_data.value = res
}
// 聚合组表的多选操作;
const changeAllSelect = (val) => {
// edit_table_data.value = val
// console.log(edit_table_data.value,111111);
let res = val.map((item) => {
let obj = {
lag_id: item.lag_id,
member_ports: item.member_ports.map(item => {
return item.split('/')[1]
})
}
return obj
})
edit_table_data.value = res
console.log(edit_table_data.value,1111111);
// select_table_data.value = res
}
// 聚合组表的修改操作(之前仅存在第一次进入右侧没数据的代码);
const handleAggrEdit = () => {
if(edit_table_data.value.length === 1) {
aggrEditDialogVisible.value = true
aggrEditForm.value = edit_table_data.value[0]
// aggrEditForm.value = edit_table_data.value[0]
// aggrEditForm.value.lag_id = edit_table_data.value[0].lag_id
// aggrEditForm.value.member_ports = edit_table_data.value[0].member_ports.map(item => 'GigabitEthernet0/'+item)
// rightPorts.value = edit_table_data.value[0].member_ports
// aggrEditForm.value.member_ports = edit_table_data.value[0].member_ports
console.log(edit_table_data.value,666666666);
console.log(edit_table_data.value[0],7777777777);
console.log(aggrEditForm.value,8888888888888);
console.log(aggrEditForm.value.member_ports,89898989898);
// console.log(tableData.value,123);
// 重新调用生成端口的函数,防止某些值被清理;
generateData()
// 选中所有表中所有的 member 值(此时才没有问题);
let seletedArray1 = []
tableData.value.forEach(item => item.member_ports.forEach(it => seletedArray1.push(it.split('/')[1])))
checkedArray.value = seletedArray1
seletedArray1 = []
// let disableArray = edit_table_data.value[0].member_ports.map(item => 'GigabitEthernet0/'+item)
// console.log(disableArray,1111111111111111);
console.log(edit_table_data.value[0].member_ports,1111111111111111);
console.log(checkedArray.value,222222222222);
// 去除待选择的 member 值(即:从一个数组中去除另一个数组中存在数据的操作);
checkedArray.value = checkedArray.value.filter(item => !edit_table_data.value[0].member_ports.includes(item));
data.value = data.value.filter(item => item.label = item.label.split('/')[1])
console.log(checkedArray.value,123);
console.log(data.value,456);
// 有效端口的禁选操作;
let res = data.value.map(item => {
// 此时返回值 flag 是数值,而不是布尔值;
let flag = checkedArray.value.find(it => it === item.label)
let obj
if(flag) {
obj = {
key: flag,
label: `GigabitEthernet0/${flag}`,
disabled: true
}
} else {
obj = {
key: item.key,
// key: `${item.key}`,
label: `GigabitEthernet0/${item.key}`,
}
}
return obj
})
// 另一种解决方案:
// let res = data.value.filter(item => {
// let flag = checkedArray.value.find(it => it === item.key)
// return item.key !== flag
// })
// console.log(res,123456);
data.value = res
console.log(data.value,789);
} else if(edit_table_data.value.length === 0 ) {
ElMessage({ message: '请选择一个来修改!',type: 'warning'})
} else {
ElMessage.error('只能选择一个来修改!')
}
}
const aggrOnCancle = () => {
toggleSelection()
// 此时是取消:修改和删除的记忆功能(即:取消后,不能直接点击修改或删除按钮);
edit_table_data.value = []
aggrEditDialogVisible.value = false
}
// 清除 Table 清空用户选择的操作;
const toggleSelection = (rows) => {
if (rows) {
rows.forEach((row) => {
multipleTable.value.toggleRowSelection(row, undefined)
})
} else {
multipleTable.value.clearSelection()
}
}
onMounted(() => {
getAggrGroupTable()
})
// 组合组配置的应用操作;
// const handleAggrApply = async() => {
// try {
// // (后面需要放开的二次认证)
// // let result = await rootapi.post_crit_auth(url, {dummy: "dummy"}, count);
// // if (!result) return;
// let url = "api/lag/config"
// const respond = await axios.post(url, new URLSearchParams({lag_mode: configurationForm.value.lag_mode}));
// if(respond.status === 200) {
// ElMessage({ message: '应用成功!',type: 'success',})
// getAggrGroupTable()
// } else if (respond.status === 400) {
// ElMessage.error('应用失败!'+ respond.message)
// }
// } catch(err) {
// if (err.response) {
// let resp = err.response;
// rootapi.show_dialog("unexpected error for POST api/lag/config:", resp.data, true);
// }
// else {
// rootapi.show_dialog("unexpected frontend error:", err.message, true);
// }
// }
// }
// 添加 LAG 得操作;
const handleAddAggr = async() => {
if(!addFormRef.value) return
addFormRef.value.validate(async (valid) => {
if(valid) {
try {
let url = "api/lag/add"
const res = await axios.post(url, new URLSearchParams({lag_id: addForm.value.lag_id}))
if(res.status === 200) {
ElMessage({ message: '添加成功!',type: 'success',})
getAggrGroupTable()
addForm.value.lag_id = ''
} else if (res.status === 400) {
ElMessage.error('添加失败!'+ res.message)
}
} catch(err) {
if (err.response) {
let resp = err.response;
rootapi.show_dialog("unexpected error for POST /api/lag/add:", resp.data, true);
}
else {
rootapi.show_dialog("unexpected frontend error:", err.message, true);
}
}
}
})
}
// 获取聚合组表的数据的操作;
const getAggrGroupTable = async() => {
// const resp = await axios.get("/api/lag/config");
const resp = {
"data": [
{
"lag_id": 9,
"member_ports": [1,2,3,4,5,7,8,11],
"efficient_members": []}
,
{
"lag_id": 10,
"member_ports": [6],
"efficient_members": []
}
]
,
"lag_mode": "src-dst-mac"
,
"totol": 2
}
// if(resp?.status === 200 && resp?.data?.lag_mode && resp?.data?.data) {
if( resp?.lag_mode && resp?.data) {
// configurationForm.value.lag_mode = resp.lag_mode
tableData.value = resp.data
let intermediateArray = []
resp.data.forEach(item => {
let lag_id = item.lag_id
let efficient_members = item.efficient_members
let member_ports = item.member_ports.map(item => 'GigabitEthernet0/' + item)
let res = {}
res.lag_id = lag_id
res.efficient_members = efficient_members
res.member_ports = member_ports
intermediateArray.push(res)
})
tableData.value = intermediateArray
intermediateArray = []
}
}
// 删除数据的操作:
const handleAggrDelete = async() => {
try {
// (后面需要放开的二次认证)
// let result = await rootapi.post_crit_auth(url, {dummy: "dummy"}, count);
// if (!result) return;
if(edit_table_data.value.length) {
let url = "api/lag/del"
let count = edit_table_data.value.length;
for (let i = 0; i < count; i++) {
let param = {...edit_table_data.value[i]};
const res = await axios.post(url, new URLSearchParams(param));
if(res.status === 200 && i === count-1) {
ElMessage({ message: '删除成功!',type: 'success',})
getAggrGroupTable()
} else if (res.status === 400) {
ElMessage.error('删除失败!'+ res.message)
}
}
} else {
ElMessage({ message: '请至少选择一个来删除!',type: 'warning'})
}
} catch(err) {
if (err.response) {
let resp = err.response;
rootapi.show_dialog("unexpected error for POST api/lag/del:", resp.data, true);
}
else {
rootapi.show_dialog("unexpected frontend error:", err.message, true);
}
}
}
// 修改链路聚合组的应用操作;
const aggrOnSubmit = async() => {
try {
// (后面需要放开的二次认证)
// let result = await rootapi.post_crit_auth(url, {dummy: "dummy"}, count);
// if (!result) return;
let url = "/api/lag/bind"
let outparam
if (aggrEditForm.value.member_ports.length) {
outparam = {
lag_id : aggrEditForm.value.lag_id,
member_ports: [...aggrEditForm.value.member_ports]
}
} else {
outparam = {
lag_id : aggrEditForm.value.lag_id,
member_ports: 0
}
}
console.log(aggrEditForm.value.member_ports,111111);
console.log(outparam,222222222);
// const respond = await axios.post(url, outparam);
const respond = await axios.post(url, new URLSearchParams(outparam));
if(respond.status === 200) {
ElMessage({ message: '应用成功!',type: 'success',})
getAggrGroupTable()
aggrEditDialogVisible.value = false
} else if (respond.status === 400) {
ElMessage.error('应用失败!'+ respond.message)
}
} catch(err) {
aggrEditDialogVisible.value = false
if (err.response) {
let resp = err.response;
rootapi.show_dialog("unexpected error for POST /api/lag/bind:", resp.data, true);
}
else {
rootapi.show_dialog("unexpected frontend error:", err.message, true);
}
}
}
// 右边穿梭框变化触发的函数;
const handleRightChange = (val) => {
if(val.length > 8) {
ElMessage({ message: '注意:最多 8 个成员!',type: 'warning',})
}
}
</script>
<template>
<div class="aggr_group_layout">
<div class="my_project">
<!-- <div class="add_configuration">
<div class="configuration_title"> 聚合组配置 </div>
<el-form>
<el-form-item label="负载分担策略:">
<el-radio-group class='radioDiv' v-model="configurationForm.lag_mode">
<div><el-radio label="src-dst-ip">源和目的IP地址</el-radio></div>
<div><el-radio label="src-dst-mac">源和目的MAC地址</el-radio></div>
<div><el-radio label="dst-ip">目的IP地址</el-radio></div>
<div><el-radio label="dst-mac">目的MAC地址</el-radio></div>
<div><el-radio label="src-ip">源IP地址</el-radio></div>
<div><el-radio label="src-mac">源MAC地址</el-radio></div>
</el-radio-group>
</el-form-item>
</el-form>
<div class="configuration_footer" style="margin-top: 20px">
<el-button type="primary" @click="handleAggrApply">提交</el-button>
</div>
</div> -->
<div class="aggr_group_display">
<!-- <div class="display_title"> 聚合组表 </div> -->
<div class="display_title"> 11223344 </div>
<div class="display_add">
<el-form :model="addForm" label-width="52px" ref="addFormRef" :rules="addRules" class="demo-ruleForm" status-icon>
<el-form-item label="LAG:" prop="lag_id">
<div><el-input v-model="addForm.lag_id" /></div>
</el-form-item>
</el-form>
<div class="add_footer" style="margin-top: 20px">
<el-button type="primary" @click="handleAddAggr">添加</el-button>
</div>
</div>
<el-table :data="tableData" style="width: 100%" ref="multipleTable" :row-class-name="tableRowClassName" @select="changeSelect" @select-all="changeAllSelect" max-height="342px">
<el-table-column type="selection" width="80" align="center"/>
<el-table-column prop="lag_id" label="LAG" max-width="50" align="center"/>
<el-table-column prop="efficient_members" label="生效端口" min-width="100" align="center"/>
<el-table-column prop="member_ports" label="成员" min-width="295" align="center"/>
</el-table>
<div class="display_footer" style="margin-top: 20px">
<el-button type="primary" @click="handleAggrEdit">修改</el-button>
<el-button type="primary" @click="handleAggrDelete">删除</el-button>
<el-button type="primary" @click="getAggrGroupTable"><el-icon :size="20" style="margin-right: 5px;"><Refresh /></el-icon></el-button>
</div>
</div>
</div>
<el-dialog v-model="aggrEditDialogVisible" title="修改链路聚合组" width="712" center :close-on-click-modal="false">
<el-form :model="aggrEditForm" ref="aggrEditFormRef">
<el-form-item label="LAG:" :label-width="aggrLabelWidth">
{{ aggrEditForm.lag_id }}
</el-form-item>
<el-form-item label-width="56px">
<el-transfer v-model="aggrEditForm.member_ports" :data="data" :titles="['有效端口','已选端口']" @change="handleRightChange" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="aggrOnSubmit">提交</el-button>
<el-button @click="aggrOnCancle(aggrEditFormRef)">取消</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
.aggr_group_layout {
margin: 30px auto;
background-color: #e6f1f9;
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 40px 0px;
.my_project {
min-width: 500px;
padding: 30px 30px 10px;
.add_configuration {
.configuration_title {
text-align: center;
font-weight: 700;
margin-bottom: 20px;
}
.configuration_footer {
margin: -5px 0 20px !important;
text-align: left;
}
.radioDiv {
display: table;
div {
margin-bottom: -17px;
}
}
.el-form-item {
// 此时是修改 el-form-item 上下的距离,因此并不起作用;
// margin-bottom: 1px !important;
::v-deep(.el-form-item__label){
// margin-top: 22px !important;
font-weight: 500;
}
}
}
.aggr_group_display {
.display_title {
text-align: center;
font-weight: 700;
margin-bottom: 20px;
}
// 表格表头的背景色;
::v-deep(.el-table th) {
background-color: #e6f1f9;
}
// 表格表头的下边框;
::v-deep(.el-table th.is-leaf) {
border-bottom: 1px solid #557A95;
font-weight: 700;
font-size: 16px;
color: black;
}
// 表格(除表头)的背景色;
::v-deep(.el-table tr) {
font-weight: 500;
}
::v-deep(.el-table--enable-row-hover .el-table__body tr:hover > td) {
background-color: #afc4d3;
}
::v-deep(.el-table .warning-row) {
background-color: #d6e6f5;
}
::v-deep(.el-table .success-row) {
background-color: #e6f1f9;
}
.display_add {
.add_footer {
margin: -5px 0 20px !important;
text-align: left;
}
}
.display_footer {
margin: 20px 0 10px;
text-align: center;
}
}
}
}
// 修改多选框的样式(即:修改多选框的大小);
// .el-table {
// ::v-deep(.el-checkbox__inner){
// --el-checkbox-input-height: 21px !important;
// --el-checkbox-input-width: 20px !important;
// &:after {
// top: 5px;
// left: 7px;
// }
// }
// }
//去掉 dialog 右侧的 X 标记;
::v-deep(.el-dialog) {
.el-dialog__header {
.el-dialog__headerbtn {
font-size: 30px;
.el-dialog__close {
color: red;
display: none;
}
}
}
}
.el-transfer {
// 去掉穿梭框标题全选框;
::v-deep(.el-transfer-panel__header) {
.el-checkbox {
.el-checkbox__input {
display: none;
}
}
}
// 设置穿梭框左右两边的宽度值(注意:一定不能去掉 !important 否则会出问题)
--el-transfer-panel-width: 222px !important
}
</style>
其二、页面展示:
// 整体功能模块的展示情况:
// 选中 table 表格中第一个数据后,右侧的已选端口,应该展示成员值:
// 即:上述的已选端口要和 table 中第一个成员的值,一一对应;
2、问题分析:
其一、经操作后发现:
发现 transfer
的有效端口
的值是按照要求的数组(即:按道理说应该展示没问题),且右侧已选端口
的值也是按照要求的数组值(即:按道理说应该展示没问题),但是右边的已选端口
的值就是展示不出来;
其二、但是切换后,右侧的已选端口的值能成功展示:
// 此时 transfer
组件就又能展示已选端口
的值,且此时右侧展示的值就是项目想要的结果,但是第一次进来后页面并没有展示;
// 第一次进入,在 transfer
组件中的已选端口
并没有数据,但是这种展示是不正常的,因为在 table 中已经选择了第一行的数据,且数据中的成员是有值的;
// 此时在切换 table
的第二行后,再切换回来,在 transfer
组件中的已选端口
中就有了数据;
// 这样展示没有问题,就是想要的结果,但是第一次进入右侧的已选端口
没有数据是不正常的;
其三、猜测原因:
// 应该是数据在哪里出了问题;
Ⅲ、解决在项目中使用 Transfer
组件遇到的问题:
1、问题原因:
其一、后台返回的数据情况为:
// 虽然此时的展示 "member_ports": [1,2,3,4,5,7,8,11]
是数组类型,但是在使用 transfer
的时候,右侧已选端口
绑定的值是字符串类型的,如"member_ports": ['1','2','3','4','5','7','8','11']
,因此出现了右侧已选端口
在第一次加载时页面不显示的情况;
其二、解决方案为:
// 只需要将左侧最后生成 data
值里的 key
值换成字符串的 key
即可;
// 因为从设置的数据可知,第一次拿到的返回值是字符串类型,而有效端口
的值也是字符串类型,这样已选端口
的值才能显示出来;
2、没有问题的代码:
// 即:第一次进入 transfer 组件,右侧的已选端口就成功展示了想要展示的值;
<script setup>
import axios from 'axios';
const rootapi = inject("rootapi");
import { ref,inject,onMounted,reactive } from 'vue'
import { ElMessage } from 'element-plus'
const addFormRef = ref(null)
const aggrEditFormRef = ref(null)
const aggrEditDialogVisible = ref(false)
const aggrLabelWidth = '100px'
const edit_table_data = ref([])
const aggrEditForm = ref({})
const multipleTable = ref('')
const value = ref([])
const checkedArray = ref([])
const rightPorts = ref([])
// const configurationForm = ref({
// lag_mode: "hash_mac"
// })
const addForm = ref({
lag_id: ''
})
const tableData = ref([])
// 生成有效端口值;
const generateData = () => {
const data = []
for (let i = 1; i <= 28; i++) {
data.push({
key: `${i}`,
label: `GigabitEthernet0/${i}`
})
}
return data
}
// 注意:此时 generateData() 函数一定要在定义 data 数据前,才不会报错;
const data = ref(generateData())
const tableRowClassName = (val) => {
if(val.rowIndex %2 === 0) {
return 'success-row'
} else {
return 'warning-row'
}
}
// 添加 LAG 的校验;
const checkAggrLag = (rule, value, callback) => {
if (!value) {
return callback(new Error('此处不能为空'))
}
setTimeout(() => {
if(/^([1-9]|(1[0-6]))$/.test(value)) {
callback()
} else {
callback(new Error('请填写 1~16 的值'))
}
}, 10)
}
// 添加 LAG 聚合表组的校验;
const addRules = ref({
lag_id: [
{required: true, validator: checkAggrLag, trigger: 'blur' }
]
})
// 聚合组表的单选操作(之前仅存在第一次进入右侧没数据的代码);
const changeSelect = (val) => {
// edit_table_data.value = val
// console.log(edit_table_data.value,111111);
let res = val.map((item) => {
let obj = {
lag_id: item.lag_id,
member_ports: item.member_ports.map(item => {
return item.split('/')[1]
})
}
return obj
})
// rightPorts.value=res
edit_table_data.value = res
handleRightChange()
console.log(edit_table_data.value,1111111);
// select_table_data.value = res
}
// 聚合组表的多选操作;
const changeAllSelect = (val) => {
// edit_table_data.value = val
// console.log(edit_table_data.value,111111);
let res = val.map((item) => {
let obj = {
lag_id: item.lag_id,
member_ports: item.member_ports.map(item => {
return item.split('/')[1]
})
}
return obj
})
edit_table_data.value = res
console.log(edit_table_data.value,1111111);
// select_table_data.value = res
}
// 聚合组表的修改操作(之前仅存在第一次进入右侧没数据的代码);
const handleAggrEdit = () => {
if(edit_table_data.value.length === 1) {
aggrEditDialogVisible.value = true
aggrEditForm.value = edit_table_data.value[0]
// aggrEditForm.value = edit_table_data.value[0]
// aggrEditForm.value.lag_id = edit_table_data.value[0].lag_id
// aggrEditForm.value.member_ports = edit_table_data.value[0].member_ports.map(item => 'GigabitEthernet0/'+item)
// rightPorts.value = edit_table_data.value[0].member_ports
// aggrEditForm.value.member_ports = edit_table_data.value[0].member_ports
console.log(edit_table_data.value,666666666);
console.log(edit_table_data.value[0],7777777777);
console.log(aggrEditForm.value,8888888888888);
console.log(aggrEditForm.value.member_ports,89898989898);
// console.log(tableData.value,123);
// 重新调用生成端口的函数,防止某些值被清理;
generateData()
// 选中所有表中所有的 member 值(此时才没有问题);
let seletedArray1 = []
tableData.value.forEach(item => item.member_ports.forEach(it => seletedArray1.push(it.split('/')[1])))
checkedArray.value = seletedArray1
seletedArray1 = []
// let disableArray = edit_table_data.value[0].member_ports.map(item => 'GigabitEthernet0/'+item)
// console.log(disableArray,1111111111111111);
console.log(edit_table_data.value[0].member_ports,1111111111111111);
console.log(checkedArray.value,222222222222);
// 去除待选择的 member 值(即:从一个数组中去除另一个数组中存在数据的操作);
checkedArray.value = checkedArray.value.filter(item => !edit_table_data.value[0].member_ports.includes(item));
data.value = data.value.filter(item => item.label = item.label.split('/')[1])
console.log(checkedArray.value,123);
console.log(data.value,456);
// 有效端口的禁选操作;
let res = data.value.map(item => {
// 此时返回值 flag 是数值,而不是布尔值;
let flag = checkedArray.value.find(it => it === item.label)
let obj
if(flag) {
obj = {
key: flag,
label: `GigabitEthernet0/${flag}`,
disabled: true
}
} else {
obj = {
key: `${item.key}`,
label: `GigabitEthernet0/${item.key}`,
}
}
return obj
})
// 另一种解决方案:
// let res = data.value.filter(item => {
// let flag = checkedArray.value.find(it => it === item.key)
// return item.key !== flag
// })
// console.log(res,123456);
data.value = res
console.log(data.value,789);
} else if(edit_table_data.value.length === 0 ) {
ElMessage({ message: '请选择一个来修改!',type: 'warning'})
} else {
ElMessage.error('只能选择一个来修改!')
}
}
const aggrOnCancle = () => {
toggleSelection()
// 此时是取消:修改和删除的记忆功能(即:取消后,不能直接点击修改或删除按钮);
edit_table_data.value = []
aggrEditDialogVisible.value = false
}
// 清除 Table 清空用户选择的操作;
const toggleSelection = (rows) => {
if (rows) {
rows.forEach((row) => {
multipleTable.value.toggleRowSelection(row, undefined)
})
} else {
multipleTable.value.clearSelection()
}
}
onMounted(() => {
getAggrGroupTable()
})
// 组合组配置的应用操作;
// const handleAggrApply = async() => {
// try {
// // (后面需要放开的二次认证)
// // let result = await rootapi.post_crit_auth(url, {dummy: "dummy"}, count);
// // if (!result) return;
// let url = "api/lag/config"
// const respond = await axios.post(url, new URLSearchParams({lag_mode: configurationForm.value.lag_mode}));
// if(respond.status === 200) {
// ElMessage({ message: '应用成功!',type: 'success',})
// getAggrGroupTable()
// } else if (respond.status === 400) {
// ElMessage.error('应用失败!'+ respond.message)
// }
// } catch(err) {
// if (err.response) {
// let resp = err.response;
// rootapi.show_dialog("unexpected error for POST api/lag/config:", resp.data, true);
// }
// else {
// rootapi.show_dialog("unexpected frontend error:", err.message, true);
// }
// }
// }
// 添加 LAG 得操作;
const handleAddAggr = async() => {
if(!addFormRef.value) return
addFormRef.value.validate(async (valid) => {
if(valid) {
try {
let url = "api/lag/add"
const res = await axios.post(url, new URLSearchParams({lag_id: addForm.value.lag_id}))
if(res.status === 200) {
ElMessage({ message: '添加成功!',type: 'success',})
getAggrGroupTable()
addForm.value.lag_id = ''
} else if (res.status === 400) {
ElMessage.error('添加失败!'+ res.message)
}
} catch(err) {
if (err.response) {
let resp = err.response;
rootapi.show_dialog("unexpected error for POST /api/lag/add:", resp.data, true);
}
else {
rootapi.show_dialog("unexpected frontend error:", err.message, true);
}
}
}
})
}
// 获取聚合组表的数据的操作;
const getAggrGroupTable = async() => {
// const resp = await axios.get("/api/lag/config");
const resp = {
"data": [
{
"lag_id": 9,
"member_ports": [1,2,3,4,5,7,8,11],
"efficient_members": []}
,
{
"lag_id": 10,
"member_ports": [6],
"efficient_members": []
}
]
,
"lag_mode": "src-dst-mac"
,
"totol": 2
}
// if(resp?.status === 200 && resp?.data?.lag_mode && resp?.data?.data) {
if( resp?.lag_mode && resp?.data) {
// configurationForm.value.lag_mode = resp.lag_mode
tableData.value = resp.data
let intermediateArray = []
resp.data.forEach(item => {
let lag_id = item.lag_id
let efficient_members = item.efficient_members
let member_ports = item.member_ports.map(item => 'GigabitEthernet0/' + item)
let res = {}
res.lag_id = lag_id
res.efficient_members = efficient_members
res.member_ports = member_ports
intermediateArray.push(res)
})
tableData.value = intermediateArray
intermediateArray = []
}
}
// 删除数据的操作:
const handleAggrDelete = async() => {
try {
// (后面需要放开的二次认证)
// let result = await rootapi.post_crit_auth(url, {dummy: "dummy"}, count);
// if (!result) return;
if(edit_table_data.value.length) {
let url = "api/lag/del"
let count = edit_table_data.value.length;
for (let i = 0; i < count; i++) {
let param = {...edit_table_data.value[i]};
const res = await axios.post(url, new URLSearchParams(param));
if(res.status === 200 && i === count-1) {
ElMessage({ message: '删除成功!',type: 'success',})
getAggrGroupTable()
} else if (res.status === 400) {
ElMessage.error('删除失败!'+ res.message)
}
}
} else {
ElMessage({ message: '请至少选择一个来删除!',type: 'warning'})
}
} catch(err) {
if (err.response) {
let resp = err.response;
rootapi.show_dialog("unexpected error for POST api/lag/del:", resp.data, true);
}
else {
rootapi.show_dialog("unexpected frontend error:", err.message, true);
}
}
}
// 修改链路聚合组的应用操作;
const aggrOnSubmit = async() => {
try {
// (后面需要放开的二次认证)
// let result = await rootapi.post_crit_auth(url, {dummy: "dummy"}, count);
// if (!result) return;
let url = "/api/lag/bind"
let outparam
if (aggrEditForm.value.member_ports.length) {
outparam = {
lag_id : aggrEditForm.value.lag_id,
member_ports: [...aggrEditForm.value.member_ports]
}
} else {
outparam = {
lag_id : aggrEditForm.value.lag_id,
member_ports: 0
}
}
console.log(aggrEditForm.value.member_ports,111111);
console.log(outparam,222222222);
// const respond = await axios.post(url, outparam);
const respond = await axios.post(url, new URLSearchParams(outparam));
if(respond.status === 200) {
ElMessage({ message: '应用成功!',type: 'success',})
getAggrGroupTable()
aggrEditDialogVisible.value = false
} else if (respond.status === 400) {
ElMessage.error('应用失败!'+ respond.message)
}
} catch(err) {
aggrEditDialogVisible.value = false
if (err.response) {
let resp = err.response;
rootapi.show_dialog("unexpected error for POST /api/lag/bind:", resp.data, true);
}
else {
rootapi.show_dialog("unexpected frontend error:", err.message, true);
}
}
}
// 右边穿梭框变化触发的函数;
const handleRightChange = (val) => {
if(val.length > 8) {
ElMessage({ message: '注意:最多 8 个成员!',type: 'warning',})
}
}
</script>
<template>
<div class="aggr_group_layout">
<div class="my_project">
<!-- <div class="add_configuration">
<div class="configuration_title"> 聚合组配置 </div>
<el-form>
<el-form-item label="负载分担策略:">
<el-radio-group class='radioDiv' v-model="configurationForm.lag_mode">
<div><el-radio label="src-dst-ip">源和目的IP地址</el-radio></div>
<div><el-radio label="src-dst-mac">源和目的MAC地址</el-radio></div>
<div><el-radio label="dst-ip">目的IP地址</el-radio></div>
<div><el-radio label="dst-mac">目的MAC地址</el-radio></div>
<div><el-radio label="src-ip">源IP地址</el-radio></div>
<div><el-radio label="src-mac">源MAC地址</el-radio></div>
</el-radio-group>
</el-form-item>
</el-form>
<div class="configuration_footer" style="margin-top: 20px">
<el-button type="primary" @click="handleAggrApply">提交</el-button>
</div>
</div> -->
<div class="aggr_group_display">
<!-- <div class="display_title"> 聚合组表 </div> -->
<div class="display_title"> 11223344 </div>
<div class="display_add">
<el-form :model="addForm" label-width="52px" ref="addFormRef" :rules="addRules" class="demo-ruleForm" status-icon>
<el-form-item label="LAG:" prop="lag_id">
<div><el-input v-model="addForm.lag_id" /></div>
</el-form-item>
</el-form>
<div class="add_footer" style="margin-top: 20px">
<el-button type="primary" @click="handleAddAggr">添加</el-button>
</div>
</div>
<el-table :data="tableData" style="width: 100%" ref="multipleTable" :row-class-name="tableRowClassName" @select="changeSelect" @select-all="changeAllSelect" max-height="342px">
<el-table-column type="selection" width="80" align="center"/>
<el-table-column prop="lag_id" label="LAG" max-width="50" align="center"/>
<el-table-column prop="efficient_members" label="生效端口" min-width="100" align="center"/>
<el-table-column prop="member_ports" label="成员" min-width="295" align="center"/>
</el-table>
<div class="display_footer" style="margin-top: 20px">
<el-button type="primary" @click="handleAggrEdit">修改</el-button>
<el-button type="primary" @click="handleAggrDelete">删除</el-button>
<el-button type="primary" @click="getAggrGroupTable"><el-icon :size="20" style="margin-right: 5px;"><Refresh /></el-icon></el-button>
</div>
</div>
</div>
<el-dialog v-model="aggrEditDialogVisible" title="修改链路聚合组" width="712" center :close-on-click-modal="false">
<el-form :model="aggrEditForm" ref="aggrEditFormRef">
<el-form-item label="LAG:" :label-width="aggrLabelWidth">
{{ aggrEditForm.lag_id }}
</el-form-item>
<el-form-item label-width="56px">
<el-transfer v-model="aggrEditForm.member_ports" :data="data" :titles="['有效端口','已选端口']" @change="handleRightChange" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="aggrOnSubmit">提交</el-button>
<el-button @click="aggrOnCancle(aggrEditFormRef)">取消</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
.aggr_group_layout {
margin: 30px auto;
background-color: #e6f1f9;
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 40px 0px;
.my_project {
min-width: 500px;
padding: 30px 30px 10px;
.add_configuration {
.configuration_title {
text-align: center;
font-weight: 700;
margin-bottom: 20px;
}
.configuration_footer {
margin: -5px 0 20px !important;
text-align: left;
}
.radioDiv {
display: table;
div {
margin-bottom: -17px;
}
}
.el-form-item {
// 此时是修改 el-form-item 上下的距离,因此并不起作用;
// margin-bottom: 1px !important;
::v-deep(.el-form-item__label){
// margin-top: 22px !important;
font-weight: 500;
}
}
}
.aggr_group_display {
.display_title {
text-align: center;
font-weight: 700;
margin-bottom: 20px;
}
// 表格表头的背景色;
::v-deep(.el-table th) {
background-color: #e6f1f9;
}
// 表格表头的下边框;
::v-deep(.el-table th.is-leaf) {
border-bottom: 1px solid #557A95;
font-weight: 700;
font-size: 16px;
color: black;
}
// 表格(除表头)的背景色;
::v-deep(.el-table tr) {
font-weight: 500;
}
::v-deep(.el-table--enable-row-hover .el-table__body tr:hover > td) {
background-color: #afc4d3;
}
::v-deep(.el-table .warning-row) {
background-color: #d6e6f5;
}
::v-deep(.el-table .success-row) {
background-color: #e6f1f9;
}
.display_add {
.add_footer {
margin: -5px 0 20px !important;
text-align: left;
}
}
.display_footer {
margin: 20px 0 10px;
text-align: center;
}
}
}
}
// 修改多选框的样式(即:修改多选框的大小);
// .el-table {
// ::v-deep(.el-checkbox__inner){
// --el-checkbox-input-height: 21px !important;
// --el-checkbox-input-width: 20px !important;
// &:after {
// top: 5px;
// left: 7px;
// }
// }
// }
//去掉 dialog 右侧的 X 标记;
::v-deep(.el-dialog) {
.el-dialog__header {
.el-dialog__headerbtn {
font-size: 30px;
.el-dialog__close {
color: red;
display: none;
}
}
}
}
.el-transfer {
// 去掉穿梭框标题全选框;
::v-deep(.el-transfer-panel__header) {
.el-checkbox {
.el-checkbox__input {
display: none;
}
}
}
// 设置穿梭框左右两边的宽度值(注意:一定不能去掉 !important 否则会出问题)
--el-transfer-panel-width: 222px !important
}
</style>
3、没有问题的页面展示:
Ⅳ、整体代码的面貌:
其一、整体代码为:
<script setup>
import axios from 'axios';
const rootapi = inject("rootapi");
import { ref,inject,onMounted,reactive } from 'vue'
import { ElMessage } from 'element-plus'
const addFormRef = ref(null)
const aggrEditFormRef = ref(null)
const aggrEditDialogVisible = ref(false)
const aggrLabelWidth = '100px'
const edit_table_data = ref([])
const aggrEditForm = ref({})
const multipleTable = ref('')
const value = ref([])
const checkedArray = ref([])
const rightPorts = ref([])
const configurationForm = ref({
lag_mode: "hash_mac"
})
const addForm = ref({
lag_id: ''
})
const tableData = ref([])
// 生成有效端口值;
const generateData = () => {
const data = []
for (let i = 1; i <= 28; i++) {
data.push({
key: `${i}`,
label: `GigabitEthernet0/${i}`
})
}
return data
}
// 注意:此时 generateData() 函数一定要在定义 data 数据前,才不会报错;
const data = ref(generateData())
const tableRowClassName = (val) => {
if(val.rowIndex %2 === 0) {
return 'success-row'
} else {
return 'warning-row'
}
}
// 添加 LAG 的校验;
const checkAggrLag = (rule, value, callback) => {
if (!value) {
return callback(new Error('此处不能为空'))
}
setTimeout(() => {
if(/^([1-9]|(1[0-6]))$/.test(value)) {
callback()
} else {
callback(new Error('请填写 1~16 的值'))
}
}, 10)
}
// 添加 LAG 聚合表组的校验;
const addRules = ref({
lag_id: [
{required: true, validator: checkAggrLag, trigger: 'blur' }
]
})
// 聚合组表的单选操作(之前仅存在第一次进入右侧没数据的代码);
const changeSelect = (val) => {
// edit_table_data.value = val
// console.log(edit_table_data.value,111111);
let res = val.map((item) => {
let obj = {
lag_id: item.lag_id,
member_ports: item.member_ports.map(item => {
return item.split('/')[1]
})
}
return obj
})
// rightPorts.value=res
edit_table_data.value = res
handleRightChange()
console.log(edit_table_data.value,1111111);
// select_table_data.value = res
}
// 聚合组表的多选操作;
const changeAllSelect = (val) => {
// edit_table_data.value = val
// console.log(edit_table_data.value,111111);
let res = val.map((item) => {
let obj = {
lag_id: item.lag_id,
member_ports: item.member_ports.map(item => {
return item.split('/')[1]
})
}
return obj
})
edit_table_data.value = res
console.log(edit_table_data.value,1111111);
// select_table_data.value = res
}
// 聚合组表的修改操作(之前仅存在第一次进入右侧没数据的代码);
const handleAggrEdit = () => {
if(edit_table_data.value.length === 1) {
aggrEditDialogVisible.value = true
aggrEditForm.value = edit_table_data.value[0]
// aggrEditForm.value = edit_table_data.value[0]
// aggrEditForm.value.lag_id = edit_table_data.value[0].lag_id
// aggrEditForm.value.member_ports = edit_table_data.value[0].member_ports.map(item => 'GigabitEthernet0/'+item)
// rightPorts.value = edit_table_data.value[0].member_ports
// aggrEditForm.value.member_ports = edit_table_data.value[0].member_ports
console.log(edit_table_data.value,666666666);
console.log(edit_table_data.value[0],7777777777);
console.log(aggrEditForm.value,8888888888888);
console.log(aggrEditForm.value.member_ports,89898989898);
// console.log(tableData.value,123);
// 重新调用生成端口的函数,防止某些值被清理;
generateData()
// 选中所有表中所有的 member 值(此时才没有问题);
let seletedArray1 = []
tableData.value.forEach(item => item.member_ports.forEach(it => seletedArray1.push(it.split('/')[1])))
checkedArray.value = seletedArray1
seletedArray1 = []
// let disableArray = edit_table_data.value[0].member_ports.map(item => 'GigabitEthernet0/'+item)
// console.log(disableArray,1111111111111111);
console.log(edit_table_data.value[0].member_ports,1111111111111111);
console.log(checkedArray.value,222222222222);
// 去除待选择的 member 值(即:从一个数组中去除另一个数组中存在数据的操作);
checkedArray.value = checkedArray.value.filter(item => !edit_table_data.value[0].member_ports.includes(item));
data.value = data.value.filter(item => item.label = item.label.split('/')[1])
console.log(checkedArray.value,123);
console.log(data.value,456);
// 有效端口的禁选操作;
let res = data.value.map(item => {
// 此时返回值 flag 是数值,而不是布尔值;
let flag = checkedArray.value.find(it => it === item.label)
let obj
if(flag) {
obj = {
key: flag,
label: `GigabitEthernet0/${flag}`,
disabled: true
}
} else {
obj = {
key: `${item.key}`,
label: `GigabitEthernet0/${item.key}`,
}
}
return obj
})
// 另一种解决方案:
// let res = data.value.filter(item => {
// let flag = checkedArray.value.find(it => it === item.key)
// return item.key !== flag
// })
// console.log(res,123456);
data.value = res
console.log(data.value,789);
} else if(edit_table_data.value.length === 0 ) {
ElMessage({ message: '请选择一个来修改!',type: 'warning'})
} else {
ElMessage.error('只能选择一个来修改!')
}
}
const aggrOnCancle = () => {
toggleSelection()
// 此时是取消:修改和删除的记忆功能(即:取消后,不能直接点击修改或删除按钮);
edit_table_data.value = []
aggrEditDialogVisible.value = false
}
// 清除 Table 清空用户选择的操作;
const toggleSelection = (rows) => {
if (rows) {
rows.forEach((row) => {
multipleTable.value.toggleRowSelection(row, undefined)
})
} else {
multipleTable.value.clearSelection()
}
}
onMounted(() => {
getAggrGroupTable()
})
// 组合组配置的应用操作;
const handleAggrApply = async() => {
try {
// (后面需要放开的二次认证)
// let result = await rootapi.post_crit_auth(url, {dummy: "dummy"}, count);
// if (!result) return;
let url = "api/lag/config"
const respond = await axios.post(url, new URLSearchParams({lag_mode: configurationForm.value.lag_mode}));
if(respond.status === 200) {
ElMessage({ message: '应用成功!',type: 'success',})
getAggrGroupTable()
} else if (respond.status === 400) {
ElMessage.error('应用失败!'+ respond.message)
}
} catch(err) {
if (err.response) {
let resp = err.response;
rootapi.show_dialog("unexpected error for POST api/lag/config:", resp.data, true);
}
else {
rootapi.show_dialog("unexpected frontend error:", err.message, true);
}
}
}
// 添加 LAG 得操作;
const handleAddAggr = async() => {
if(!addFormRef.value) return
addFormRef.value.validate(async (valid) => {
if(valid) {
try {
let url = "api/lag/add"
const res = await axios.post(url, new URLSearchParams({lag_id: addForm.value.lag_id}))
if(res.status === 200) {
ElMessage({ message: '添加成功!',type: 'success',})
getAggrGroupTable()
addForm.value.lag_id = ''
} else if (res.status === 400) {
ElMessage.error('添加失败!'+ res.message)
}
} catch(err) {
if (err.response) {
let resp = err.response;
rootapi.show_dialog("unexpected error for POST /api/lag/add:", resp.data, true);
}
else {
rootapi.show_dialog("unexpected frontend error:", err.message, true);
}
}
}
})
}
// 获取聚合组表的数据的操作;
const getAggrGroupTable = async() => {
// const resp = await axios.get("/api/lag/config");
const resp = {
"data": [
{
"lag_id": 9,
"member_ports": [1,2,3,4,5,7,8,11],
"efficient_members": []}
,
{
"lag_id": 10,
"member_ports": [6],
"efficient_members": []
}
]
,
"lag_mode": "src-dst-mac"
,
"totol": 2
}
// if(resp?.status === 200 && resp?.data?.lag_mode && resp?.data?.data) {
if( resp?.lag_mode && resp?.data) {
configurationForm.value.lag_mode = resp.lag_mode
tableData.value = resp.data
let intermediateArray = []
resp.data.forEach(item => {
let lag_id = item.lag_id
let efficient_members = item.efficient_members
let member_ports = item.member_ports.map(item => 'GigabitEthernet0/' + item)
let res = {}
res.lag_id = lag_id
res.efficient_members = efficient_members
res.member_ports = member_ports
intermediateArray.push(res)
})
tableData.value = intermediateArray
intermediateArray = []
}
}
// 删除数据的操作:
const handleAggrDelete = async() => {
try {
// (后面需要放开的二次认证)
// let result = await rootapi.post_crit_auth(url, {dummy: "dummy"}, count);
// if (!result) return;
if(edit_table_data.value.length) {
let url = "api/lag/del"
let count = edit_table_data.value.length;
for (let i = 0; i < count; i++) {
let param = {...edit_table_data.value[i]};
const res = await axios.post(url, new URLSearchParams(param));
if(res.status === 200 && i === count-1) {
ElMessage({ message: '删除成功!',type: 'success',})
getAggrGroupTable()
} else if (res.status === 400) {
ElMessage.error('删除失败!'+ res.message)
}
}
} else {
ElMessage({ message: '请至少选择一个来删除!',type: 'warning'})
}
} catch(err) {
if (err.response) {
let resp = err.response;
rootapi.show_dialog("unexpected error for POST api/lag/del:", resp.data, true);
}
else {
rootapi.show_dialog("unexpected frontend error:", err.message, true);
}
}
}
// 修改链路聚合组的应用操作;
const aggrOnSubmit = async() => {
try {
// (后面需要放开的二次认证)
// let result = await rootapi.post_crit_auth(url, {dummy: "dummy"}, count);
// if (!result) return;
let url = "/api/lag/bind"
let outparam
if (aggrEditForm.value.member_ports.length) {
outparam = {
lag_id : aggrEditForm.value.lag_id,
member_ports: [...aggrEditForm.value.member_ports]
}
} else {
outparam = {
lag_id : aggrEditForm.value.lag_id,
member_ports: 0
}
}
console.log(aggrEditForm.value.member_ports,111111);
console.log(outparam,222222222);
// const respond = await axios.post(url, outparam);
const respond = await axios.post(url, new URLSearchParams(outparam));
if(respond.status === 200) {
ElMessage({ message: '应用成功!',type: 'success',})
getAggrGroupTable()
aggrEditDialogVisible.value = false
} else if (respond.status === 400) {
ElMessage.error('应用失败!'+ respond.message)
}
} catch(err) {
aggrEditDialogVisible.value = false
if (err.response) {
let resp = err.response;
rootapi.show_dialog("unexpected error for POST /api/lag/bind:", resp.data, true);
}
else {
rootapi.show_dialog("unexpected frontend error:", err.message, true);
}
}
}
// 右边穿梭框变化触发的函数;
const handleRightChange = (val) => {
if(val.length > 8) {
ElMessage({ message: '注意:最多 8 个成员!',type: 'warning',})
}
}
</script>
<template>
<div class="aggr_group_layout">
<div class="my_project">
<div class="add_configuration">
<div class="configuration_title"> 聚合组配置 </div>
<el-form>
<el-form-item label="负载分担策略:">
<el-radio-group class='radioDiv' v-model="configurationForm.lag_mode">
<div><el-radio label="src-dst-ip">源和目的IP地址</el-radio></div>
<div><el-radio label="src-dst-mac">源和目的MAC地址</el-radio></div>
<div><el-radio label="dst-ip">目的IP地址</el-radio></div>
<div><el-radio label="dst-mac">目的MAC地址</el-radio></div>
<div><el-radio label="src-ip">源IP地址</el-radio></div>
<div><el-radio label="src-mac">源MAC地址</el-radio></div>
</el-radio-group>
</el-form-item>
</el-form>
<div class="configuration_footer" style="margin-top: 20px">
<el-button type="primary" @click="handleAggrApply">提交</el-button>
</div>
</div>
<div class="aggr_group_display">
<!-- <div class="display_title"> 聚合组表 </div> -->
<div class="display_title"> 11223344 </div>
<div class="display_add">
<el-form :model="addForm" label-width="52px" ref="addFormRef" :rules="addRules" class="demo-ruleForm" status-icon>
<el-form-item label="LAG:" prop="lag_id">
<div><el-input v-model="addForm.lag_id" /></div>
</el-form-item>
</el-form>
<div class="add_footer" style="margin-top: 20px">
<el-button type="primary" @click="handleAddAggr">添加</el-button>
</div>
</div>
<el-table :data="tableData" style="width: 100%" ref="multipleTable" :row-class-name="tableRowClassName" @select="changeSelect" @select-all="changeAllSelect" max-height="342px">
<el-table-column type="selection" width="80" align="center"/>
<el-table-column prop="lag_id" label="LAG" max-width="50" align="center"/>
<el-table-column prop="efficient_members" label="生效端口" min-width="100" align="center"/>
<el-table-column prop="member_ports" label="成员" min-width="295" align="center"/>
</el-table>
<div class="display_footer" style="margin-top: 20px">
<el-button type="primary" @click="handleAggrEdit">修改</el-button>
<el-button type="primary" @click="handleAggrDelete">删除</el-button>
<el-button type="primary" @click="getAggrGroupTable"><el-icon :size="20" style="margin-right: 5px;"><Refresh /></el-icon></el-button>
</div>
</div>
</div>
<el-dialog v-model="aggrEditDialogVisible" title="修改链路聚合组" width="712" center :close-on-click-modal="false">
<el-form :model="aggrEditForm" ref="aggrEditFormRef">
<el-form-item label="LAG:" :label-width="aggrLabelWidth">
{{ aggrEditForm.lag_id }}
</el-form-item>
<el-form-item label-width="56px">
<el-transfer v-model="aggrEditForm.member_ports" :data="data" :titles="['有效端口','已选端口']" @change="handleRightChange" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="aggrOnSubmit">提交</el-button>
<el-button @click="aggrOnCancle(aggrEditFormRef)">取消</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
.aggr_group_layout {
margin: 30px auto;
background-color: #e6f1f9;
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 40px 0px;
.my_project {
min-width: 500px;
padding: 30px 30px 10px;
.add_configuration {
.configuration_title {
text-align: center;
font-weight: 700;
margin-bottom: 20px;
}
.configuration_footer {
margin: -5px 0 20px !important;
text-align: left;
}
.radioDiv {
display: table;
div {
margin-bottom: -17px;
}
}
.el-form-item {
// 此时是修改 el-form-item 上下的距离,因此并不起作用;
// margin-bottom: 1px !important;
::v-deep(.el-form-item__label){
// margin-top: 22px !important;
font-weight: 500;
}
}
}
.aggr_group_display {
.display_title {
text-align: center;
font-weight: 700;
margin-bottom: 20px;
}
// 表格表头的背景色;
::v-deep(.el-table th) {
background-color: #e6f1f9;
}
// 表格表头的下边框;
::v-deep(.el-table th.is-leaf) {
border-bottom: 1px solid #557A95;
font-weight: 700;
font-size: 16px;
color: black;
}
// 表格(除表头)的背景色;
::v-deep(.el-table tr) {
font-weight: 500;
}
::v-deep(.el-table--enable-row-hover .el-table__body tr:hover > td) {
background-color: #afc4d3;
}
::v-deep(.el-table .warning-row) {
background-color: #d6e6f5;
}
::v-deep(.el-table .success-row) {
background-color: #e6f1f9;
}
.display_add {
.add_footer {
margin: -5px 0 20px !important;
text-align: left;
}
}
.display_footer {
margin: 20px 0 10px;
text-align: center;
}
}
}
}
// 修改多选框的样式(即:修改多选框的大小);
// .el-table {
// ::v-deep(.el-checkbox__inner){
// --el-checkbox-input-height: 21px !important;
// --el-checkbox-input-width: 20px !important;
// &:after {
// top: 5px;
// left: 7px;
// }
// }
// }
//去掉 dialog 右侧的 X 标记;
::v-deep(.el-dialog) {
.el-dialog__header {
.el-dialog__headerbtn {
font-size: 30px;
.el-dialog__close {
color: red;
display: none;
}
}
}
}
.el-transfer {
// 去掉穿梭框标题全选框;
::v-deep(.el-transfer-panel__header) {
.el-checkbox {
.el-checkbox__input {
display: none;
}
}
}
// 设置穿梭框左右两边的宽度值(注意:一定不能去掉 !important 否则会出问题)
--el-transfer-panel-width: 222px !important
}
</style>
其二、整体页面为:
Ⅴ、小结:
其一、哪里有不对或不合适的地方,还请大佬们多多指点和交流!
其二、有兴趣的话,可以多多关注这个专栏(Vue(Vue2+Vue3)面试必备专栏):https://blog.csdn.net/weixin_43405300/category_11525646.html?spm=1001.2014.3001.5482