(el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
Ⅰ、Element-plus
提供的Select
选择器组件与想要目标情况的对比:
1、Element-plus
提供Select
组件情况:
其一、Element-ui
自提供的Select
代码情况为(示例的代码):
// Element-plus 提供的组件代码:
<template><div class="flex flex-wrap gap-4 items-center"><el-selectv-model="value"placeholder="Select"size="large"style="width: 240px"><el-optionv-for="item in options":key="item.value":label="item.label":value="item.value"/></el-select><el-select v-model="value" placeholder="Select" style="width: 240px"><el-optionv-for="item in options":key="item.value":label="item.label":value="item.value"/></el-select><el-selectv-model="value"placeholder="Select"size="small"style="width: 240px"><el-optionv-for="item in options":key="item.value":label="item.label":value="item.value"/></el-select></div>
</template><script lang="ts" setup>
import { ref } from 'vue'const value = ref('')const options = [{value: 'Option1',label: 'Option1',},{value: 'Option2',label: 'Option2',},{value: 'Option3',label: 'Option3',},{value: 'Option4',label: 'Option4',},{value: 'Option5',label: 'Option5',},
]
</script>
代码地址:https://element-plus.org/zh-CN/component/select.html
其二、页面的显示情况为:
Ⅱ、在项目中使用 Select
组件遇到的问题:
1、在 table
表格中选中配置操作后,属性值(即:Rpl Port
)中的 Select
组件的 options
选项动态展示的操作:
其一、需求描述:
在 Select
组件的 options
选项中,需要根据不同的 环ID
值来展示不同的 Rpl Port
属性的选项值;
因此此时需要涉及两个接口的问题,第一个接口来获取本页面所要展示的属性值,另一个接口来获取对应 环ID
值来展示的 Rpl Port
属性的选项值;
Step1、分别获取两个接口所对应的数据值:
A、获取第一个接口数据的代码:
// 因为此时的代码设置了后台返回的数据值,因此看起来比较冗余,但其实就是个获取页面数据的 get 请求;
// 一进入该页面就需要调用接口来拿到数据值,而此时的 (start, limit) 参数,是因为分页组件的原因,后面会提到;
// 而此时的 get_eastandwest_port(start, limit) 方法,是获取第二个接口数据的方法;// 获取页面数据操作
const get_erps_configuration = async (start, limit) => {get_eastandwest_port(start, limit)console.log('TODO: GET /api/erps/cfg')//按道理应该有的获取数据的格式,但是自己手动设置是不能用如下获取数据;// const resp = await axios.get('/api/erps/cfg', {// params: {// start: start,// limit: limit,// },// })const resp = {"total": 15,"data": [ {"ring_id": "1","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "2","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "3","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "4","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "5","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "6","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "7","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "8","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "9","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "10","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"}]}console.log(resp, 1111111)console.log(resp.data, 222222)console.log(resp.data.data, 33333333)// if (resp?.status === 200 && resp?.data?.data) {// tableData.value = resp.data.data// Total.value = resp.data.total// }if (resp?.data) {tableData.value = resp.dataTotal.value = resp.total}
}
B、获取第二个接口数据的代码:
// 此时会将第二个接口获得的数据放在页面已经定义的 eastAndWestData 变量中;// 获取东向端口及西向端口的页面数据操作:
const get_eastandwest_port = async (start, limit) => {console.log('TODO: GET /api/erps/ring/mgmt')//按道理应该有的获取数据的格式,但是自己手动设置是不能用如下获取数据;// const resp = await axios.get('/api/erps/ring/mgmt', {// params: {// start: start,// limit: limit,// },// })const resp = {"total": 15,"existing_rings": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],"data": [ {"del": false,"enable": false,"ring_id": "1","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "2","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "3","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "4","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "5","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "6","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "7","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "8","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "9","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "10","eport": "GigabitEthernet0/4","wport": "GigabitEthernet0/5","vlan": "1","ring_type": "major","sub_to_mjr": "0"}]}console.log(resp, 4444444)console.log(resp.data, 55555555)console.log(resp.data.data, 666666666)// if (resp?.status === 200 && resp?.data?.data) {// eastAndWestData.value = resp.data.data// }if (resp?.data) {eastAndWestData.value = resp.data}console.log(eastAndWestData.value, 7777777777) // eport、wportconsole.log(eastAndWestData.value[0], 888888888) // eport、wportconsole.log(eastAndWestData.value[0].eport, 88889999) // eport、wport
}
Step2、在点击配置操作后,动态获取 Rpl Port
属性的 options
值:
A、代码:
// 此时的 (index,row) 参数值是 table 表格中对应行的索引值和属性值;
// 此时的 allRplPortOptions 是在点击配置后,Rpl Port 可能存在的所有情况,以备下面做 Ring Type 属性与 Rpl Port 属性的联动操作;
// 此时的 rplPortOptions 值是 Rpl Port 属性的 options 的值,其会根据不同的 index 索引值来在 eastAndWestData(第二个接口获取的值) 中获取要展示的 options(即:rplPortOptions) 值;
// 此时也涉及联动的问题:在 Ring Type 属性值为 'non_rpl' 时,Rpl Port 属性默认展示为 0; 而在 Ring Type 属性值为其它时,Rpl Port 属性默认展示为从 eastAndWestData 值中拿到的要展示的 options(即:rplPortOptions) 值;// 即:此时就能动态展示 Select 组件的 options 值的需求;// 点击 table 表格中的配置所触发的操作:
const handleEdit = (index,row) => {console.log(index,1122334);console.log(row,5566778);console.log(row.ring_id,7788991);allRplPortOptions.value = [{value: '0',label: '0',},{value: eastAndWestData.value[index].eport,label: eastAndWestData.value[index].eport,},{value: eastAndWestData.value[index].wport,label: eastAndWestData.value[index].wport,}]if(row.ring_type === 'non_rpl') {rplPortOptions.value = [{value: '0',label: '0',},]} else {rplPortOptions.value = [{value: eastAndWestData.value[index].eport,label: eastAndWestData.value[index].eport,},{value: eastAndWestData.value[index].wport,label: eastAndWestData.value[index].wport,}]}erpsCfgDialogForm.value.ring_id = row.ring_id,erpsCfgDialogForm.value.revertive = row.revertiveerpsCfgDialogForm.value.tc_propgt = row.tc_propgterpsCfgDialogForm.value.version = row.versionerpsCfgDialogForm.value.ring_type = row.ring_typeerpsCfgDialogForm.value.rpl_port = row.rpl_porterpsCfgDialogForm.value.holdoff_timer = row.holdoff_timererpsCfgDialogForm.value.guard_timer = row.guard_timererpsCfgDialogForm.value.wtr_timer = row.wtr_timererpsCfgDialogVisible.value = true
}
B、效果展示为:
// 此时点击配置后的,在 Ring Type
属性默认为 Non RPL
(即:'non_rpl'
)时,Rpl Port
属性的默认值为 0
;
2、Rpl Port
属性与 Ring Type
属性的 Select
组件之间的联动操作:
其一、需求描述:
想让 Ring Type
属性与 Rpl Port
属性之间存在联动关系:
A、在 Ring Type
属性值切换为 Non RPL
时,使得 Rpl Port
属性值仅显示为0
;
B、在 Ring Type
属性值切换为 RPL Owner
或 RPL Neighbour
时,使得 Rpl Port
属性值显示为从 eastAndWestData
值中拿到的要展示的 options
值;
Step1、由上述已知(即:上述的动态展示):
在 table
中点击每一行的配置后,已经根据 Ring Type
的值,使得 Rpl Port
属性的值显示为 0
,还是显示为从 eastAndWestData
值中拿到的要展示的 options
值;
Step2、Ring Type
属性的联动操作:
A、代码为:
// @change="handleChange" 是 Select 组件提供的 change 方法;
// 此时的 allRplPortOptions 值是在 table 中点击每一行的配置后,所获得的所有的 Rpl Port 属性可能存在的值;
// 在切换 Ring Type 属性值时,且就会触发 handleChange 函数,然后根据 Ring Type 的值是 'non_rpl' 就使 Rpl Port 属性值展示为 0; 若 Ring Type 的值不是 'non_rpl' ,那么就使 Rpl Port 属性值展示为从 eastAndWestData 值中拿到的要展示的 options 值(即:也就是 allRplPortOptions.value.slice(1, 3) 存储的值);//切换 Ring Type 下拉框所触发的函数;
const handleChange = (val) => {console.log(val, 112233)if (val === 'non_rpl') {erpsCfgDialogForm.value.rpl_port = 0rplPortOptions.value = [{value: '0',label: '0',},]} else {erpsCfgDialogForm.value.rpl_port = ''rplPortOptions.value = allRplPortOptions.value.slice(1, 3)}
}
B、效果展示为:
// 在 Ring Type
属性值为 'non_rpl'
时,Rpl Port
属性值为 0
;
// 在 Ring Type
属性值不是 'non_rpl'
时,Rpl Port
属性值为两个端口值(即:就是从 eastAndWestData
值中拿到的要展示的 options
值(即:也就是 allRplPortOptions.value.slice(1, 3)
存储的值));
3、Rpl Port
属性的 Select
组件不能为空的校验规则:
其一、需求描述:
在提交整个配置的 form
表单之前,需要所有的校验都通过后,才能调用下发参数的接口;
而对于 Rpl Port
属性值的需求是,不能为空,否则下发有问题,因此需要对 Rpl Port
属性进行防空校验;
Step1、校验规则:
A、代码为:
// 此时的 holdoff_timer 属性、guard_timer 属性、wtr_timer 属性是对其它的校验规则;
// 而 rpl_port 属性是对 Rpl Port 属性值的校验,且此时触发 rpl_port 属性的方式是 change(即:Rpl Port 属性值发生改变后就会触发校验),在 Rpl Port 属性值为空时就会有提示,且在校验不通过的情况下不能调用接口和下发参数;// erpsCfg 的规则配置:
const erpsCfgRules = ref({holdoff_timer: [{ required: true, message: '此处不能为空', trigger: 'blur' }, // 此时是防空判断;{pattern:/^(([0-9])|([1-9][0-9])|([1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|10000))$/,message: '请填写0~10000的值',trigger: 'blur',},],guard_timer: [{ required: true, message: '此处不能为空', trigger: 'blur' }, // 此时是防空判断;{pattern: /^([1-9][0-9]|([1-9][0-9][0-9]|1[0-9][0-9][0-9]|2000))$/,message: '请填写10~2000的值',trigger: 'blur',},],wtr_timer: [{ required: true, message: '此处不能为空', trigger: 'blur' }, // 此时是防空判断;{pattern: /^([1-9]|(1[0-2]))$/,message: '请填写1~12的值',trigger: 'blur',},],rpl_port: [{ required: true, message: '此处不能为空', trigger: 'change' }, // 此时是防空判断],
})
B、结果为:
// 在 Rpl Port
属性值为空时,校验报错;
Ⅲ、解决在项目中遇到的其它问题:
1、分页组件的使用过程:
其一、代码为:
// 此时页面使用的 el-pagination 组件情况,Total 是从后台获取的,来决定总共有多少页;
// 此时的 @current-change="handleCurrentChange" 函数是切换第几页后触发的函数;
<div class="project_bottom"><el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :small="true" layout="prev, pager, next, jumper" :total="Total" @current-change="handleCurrentChange"/>
</div>
// 此时的 get_erps_configuration(pageSize.value * (currentPage.value - 1),pageSize.value) 中的两个参数,分别表示从哪个值开始(即:start 值),每次获取的值是多少条(即:limit);onMounted(() => {erps_configuration_refresh()
})// 刷新页面:
const erps_configuration_refresh = () => {get_erps_configuration(pageSize.value * (currentPage.value - 1),pageSize.value,)
}// 获取页面数据操作
const get_erps_configuration = async (start, limit) => {get_eastandwest_port(start, limit)console.log('TODO: GET /api/erps/cfg')//按道理应该有的获取数据的格式,但是自己手动设置是不能用如下获取数据;// const resp = await axios.get('/api/erps/cfg', {// params: {// start: start,// limit: limit,// },// })const resp = {"total": 15,"data": [ {"ring_id": "1","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "2","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "3","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "4","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "5","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "6","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "7","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "8","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "9","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "10","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"}]}console.log(resp, 1111111)console.log(resp.data, 222222)console.log(resp.data.data, 33333333)// if (resp?.status === 200 && resp?.data?.data) {// tableData.value = resp.data.data// Total.value = resp.data.total// }if (resp?.data) {tableData.value = resp.dataTotal.value = resp.total}
}
// 此时是调用 handleCurrentChange() 函数,且默认传值为 val,然后再调用想要页的数据值;// 实现页面的分页效果;
const handleCurrentChange = (val) => {get_erps_configuration(pageSize.value * (val - 1), pageSize.value)
}
其二、页面展示为:
2、去掉弹窗右上角的X
号样式的操作:
其一、代码为:
// 此时是修改 el-dialog 的样式代码;//去掉 dialog 右侧的 X 标记;
::v-deep(.el-dialog) {.el-dialog__header {.el-dialog__headerbtn {font-size: 30px;// display: none;.el-dialog__close {color: red;display: none; }} // .el-dialog__close {// color: red;// display: none; // }}// 修改操作按钮与整个 form 表单的距离;.el-dialog__footer {margin-top: -30px !important;}
}
其二、页面展示为:
// 修改样式后,此时的配置弹窗右侧就不再有X
号的样式;
Ⅳ、整体代码的面貌:
其一、整体代码为:
<script setup>
import axios from 'axios'
import { ref, onMounted, inject } from 'vue'
const rootapi = inject('rootapi')import { ElMessage } from 'element-plus'const currentPage = ref(1)
const pageSize = ref(10)
const Total = ref()
const tableData = ref([])
const eastAndWestData = ref([])
const erpsCfgDialogVisible = ref(false)
const erpsCfgDialogFormRef = ref(null)const erpsCfgLabelWidth = '135px'const versionOptions = ref([{value: 'v1',label: 'V1',},{value: 'v2',label: 'V2',},
])const ringTypeOptions = ref([{value: 'non_rpl',label: 'Non RPL',},{value: 'rpl_owner',label: 'RPL Owner',},{value: 'rpl_neighbour',label: 'RPL Neighbour',},
])const allRplPortOptions = ref([])const rplPortOptions = ref([])const erpsCfgDialogForm = ref({})// 设置表格每一行的背景色;
const tableRowClassName = (val) => {if (val.rowIndex % 2 === 0) {return 'success-row'} else {return 'warning-row'}
}onMounted(() => {erps_configuration_refresh()
})// 刷新页面:
const erps_configuration_refresh = () => {get_erps_configuration(pageSize.value * (currentPage.value - 1),pageSize.value,)
}// 实现页面的分页效果;
const handleCurrentChange = (val) => {get_erps_configuration(pageSize.value * (val - 1), pageSize.value)
}// 获取页面数据操作
const get_erps_configuration = async (start, limit) => {get_eastandwest_port(start, limit)console.log('TODO: GET /api/erps/cfg')//按道理应该有的获取数据的格式,但是自己手动设置是不能用如下获取数据;// const resp = await axios.get('/api/erps/cfg', {// params: {// start: start,// limit: limit,// },// })const resp = {"total": 15,"data": [ {"ring_id": "1","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "2","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "3","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "4","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "5","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "6","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "7","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "8","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "9","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"},{"ring_id": "10","revertive": true,"tc_propgt": false,"version": "v2","holdoff_timer": "0","guard_timer": "500","wtr_timer": "5","ring_type": "non_rpl","rpl_port": "0"}]}console.log(resp, 1111111)console.log(resp.data, 222222)console.log(resp.data.data, 33333333)// if (resp?.status === 200 && resp?.data?.data) {// tableData.value = resp.data.data// Total.value = resp.data.total// }if (resp?.data) {tableData.value = resp.dataTotal.value = resp.total}
}// 获取东向端口及西向端口的页面数据操作:
const get_eastandwest_port = async (start, limit) => {console.log('TODO: GET /api/erps/ring/mgmt')//按道理应该有的获取数据的格式,但是自己手动设置是不能用如下获取数据;// const resp = await axios.get('/api/erps/ring/mgmt', {// params: {// start: start,// limit: limit,// },// })const resp = {"total": 15,"existing_rings": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],"data": [ {"del": false,"enable": false,"ring_id": "1","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "2","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "3","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "4","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "5","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "6","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "7","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "8","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "9","eport": "GigabitEthernet0/1","wport": "GigabitEthernet0/2","vlan": "1","ring_type": "major","sub_to_mjr": "0"},{"del": false,"enable": false,"ring_id": "10","eport": "GigabitEthernet0/4","wport": "GigabitEthernet0/5","vlan": "1","ring_type": "major","sub_to_mjr": "0"}]}console.log(resp, 4444444)console.log(resp.data, 55555555)console.log(resp.data.data, 666666666)// if (resp?.status === 200 && resp?.data?.data) {// eastAndWestData.value = resp.data.data// }if (resp?.data) {eastAndWestData.value = resp.data}console.log(eastAndWestData.value, 7777777777) // eport、wportconsole.log(eastAndWestData.value[0], 888888888) // eport、wportconsole.log(eastAndWestData.value[0].eport, 88889999) // eport、wport
}// 点击 table 表格中的配置所触发的操作:
const handleEdit = (index, row) => {console.log(index, 1122334)console.log(row, 5566778)console.log(row.ring_id, 7788991)allRplPortOptions.value = [{value: '0',label: '0',},{value: eastAndWestData.value[index].eport,label: eastAndWestData.value[index].eport,},{value: eastAndWestData.value[index].wport,label: eastAndWestData.value[index].wport,},]if (row.ring_type === 'non_rpl') {rplPortOptions.value = [{value: '0',label: '0',},]} else {rplPortOptions.value = [{value: eastAndWestData.value[index].eport,label: eastAndWestData.value[index].eport,},{value: eastAndWestData.value[index].wport,label: eastAndWestData.value[index].wport,},]};(erpsCfgDialogForm.value.ring_id = row.ring_id),(erpsCfgDialogForm.value.revertive = row.revertive)erpsCfgDialogForm.value.tc_propgt = row.tc_propgterpsCfgDialogForm.value.version = row.versionerpsCfgDialogForm.value.ring_type = row.ring_typeerpsCfgDialogForm.value.rpl_port = row.rpl_porterpsCfgDialogForm.value.holdoff_timer = row.holdoff_timererpsCfgDialogForm.value.guard_timer = row.guard_timererpsCfgDialogForm.value.wtr_timer = row.wtr_timererpsCfgDialogVisible.value = true
}// erpsCfg 的规则配置:
const erpsCfgRules = ref({holdoff_timer: [{ required: true, message: '此处不能为空', trigger: 'blur' }, // 此时是防空判断;{pattern:/^(([0-9])|([1-9][0-9])|([1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|10000))$/,message: '请填写0~10000的值',trigger: 'blur',},],guard_timer: [{ required: true, message: '此处不能为空', trigger: 'blur' }, // 此时是防空判断;{pattern: /^([1-9][0-9]|([1-9][0-9][0-9]|1[0-9][0-9][0-9]|2000))$/,message: '请填写10~2000的值',trigger: 'blur',},],wtr_timer: [{ required: true, message: '此处不能为空', trigger: 'blur' }, // 此时是防空判断;{pattern: /^([1-9]|(1[0-2]))$/,message: '请填写1~12的值',trigger: 'blur',},],rpl_port: [{ required: true, message: '此处不能为空', trigger: 'change' }, // 此时是防空判断],
})//切换 Ring Type 下拉框所触发的函数;
const handleChange = (val) => {console.log(val, 112233)if (val === 'non_rpl') {erpsCfgDialogForm.value.rpl_port = 0rplPortOptions.value = [{value: '0',label: '0',},]} else {erpsCfgDialogForm.value.rpl_port = ''rplPortOptions.value = allRplPortOptions.value.slice(1, 3)}
}// QOS-Storm-Control 配置的提交操作;
const erpsCfgonSubmit = async () => {if (!erpsCfgDialogFormRef.value) returnerpsCfgDialogFormRef.value.validate(async (valid) => {if (valid) {try {let url = '/api/erps/cfg'let obj = erpsCfgDialogForm.valueconst res = await axios.post(url, new URLSearchParams(obj))if (res.status === 200) {ElMessage({ message: '添加成功!', type: 'success' })erpsCfgDialogVisible.value = false// 更新 ERPS 配置配置表;get_erps_configuration(pageSize.value * (currentPage.value - 1),pageSize.value,)erpsCfgCancle()} else if (res.status === 400) {ElMessage.error('添加失败!' + res.message)erpsCfgDialogVisible.value = false}} catch (err) {erpsCfgDialogVisible.value = falseif (err.response) {let resp = err.responserootapi.show_dialog('unexpected error for POST /api/erps/cfg:',resp.data,true,)} else {rootapi.show_dialog('unexpected frontend error:', err.message, true)}}}})
}// 表单的取消操作:
const erpsCfgCancle = () => {erpsCfgDialogVisible.value = falseif (!erpsCfgDialogFormRef.value) returnerpsCfgDialogFormRef.value.resetFields()
}
</script><template><div class="erps_cfg_layout"><div class="my_project"><div class="project_title">ERPS配置</div><el-table:data="tableData"style="width: 100%"min-height="439":row-class-name="tableRowClassName"><el-table-columnprop="ring_id"label="环ID"align="center"width="60"></el-table-column><el-table-column prop="revertive" label="Revertive" align="center" min-width="120"/><el-table-column prop="tc_propgt" label="TC Propagation" align="center" min-width="150"/><el-table-column prop="version" label="协议版本" align="center" min-width="120"/><el-table-column prop="ring_type" label="Ring Type" align="center" min-width="150"/><el-table-column prop="rpl_port" label="Rpl Port" align="center" min-width="150"/><el-table-column prop="holdoff_timer" label="Holdoff定时器" align="center" min-width="150"/><el-table-column prop="guard_timer" label="Guard定时器" align="center" min-width="150"/><el-table-column prop="wtr_timer" label="WTR定时器" align="center" min-width="150"/><el-table-column prop="option" label="操作" align="center" min-width="150"><template #default="scope"><el-button size="small" type="primary" @click="handleEdit(scope.$index,scope.row)"><el-icon :size="20" style="margin-right: 5px;"><Edit /></el-icon>配置</el-button></template></el-table-column></el-table><div class="project_bottom"><el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :small="true" layout="prev, pager, next, jumper" :total="Total" @current-change="handleCurrentChange"/></div></div><el-dialog v-model="erpsCfgDialogVisible" title="配置" width="30%" center :close-on-click-modal="false"><el-form :model="erpsCfgDialogForm" ref="erpsCfgDialogFormRef" :rules="erpsCfgRules" class="demo-ruleForm" status-icon><el-form-item label="环ID:" prop="ring_id" :label-width="erpsCfgLabelWidth"><el-input v-model="erpsCfgDialogForm.ring_id" disabled autocomplete="off"/></el-form-item><el-form-item label="Revertive:" prop="revertive" :label-width="erpsCfgLabelWidth"><el-switch v-model="erpsCfgDialogForm.revertive"/></el-form-item><el-form-item label="TC Propagation:" prop="tc_propgt" :label-width="erpsCfgLabelWidth"><el-switch v-model="erpsCfgDialogForm.tc_propgt"/></el-form-item><el-form-item label="协议版本:" prop="version" :label-width="erpsCfgLabelWidth"><el-select v-model="erpsCfgDialogForm.version" class="m-2" placeholder="Select"><el-option v-for="item in versionOptions" :key="item.value" :label="item.label" :value="item.value"/></el-select></el-form-item><el-form-item label="Ring Type:" prop="ring_type" :label-width="erpsCfgLabelWidth"><el-select v-model="erpsCfgDialogForm.ring_type" class="m-2" placeholder="Select" @change="handleChange"><el-option v-for="item in ringTypeOptions" :key="item.value" :label="item.label" :value="item.value"/></el-select></el-form-item><el-form-item label="Rpl Port:" prop="rpl_port" :label-width="erpsCfgLabelWidth"><el-select v-model="erpsCfgDialogForm.rpl_port" class="m-2" placeholder="Select"><el-option v-for="item in rplPortOptions" :key="item.value" :label="item.label" :value="item.value"/></el-select></el-form-item><el-form-item label="Holdoff定时器:" prop="holdoff_timer" :label-width="erpsCfgLabelWidth"><el-input v-model="erpsCfgDialogForm.holdoff_timer" autocomplete="off"/></el-form-item><el-form-item label="Guard定时器:" prop="guard_timer" :label-width="erpsCfgLabelWidth"><el-input v-model="erpsCfgDialogForm.guard_timer" autocomplete="off"/></el-form-item><el-form-item label="WTR定时器:" prop="wtr_timer" :label-width="erpsCfgLabelWidth"><el-input v-model="erpsCfgDialogForm.wtr_timer" autocomplete="off"/></el-form-item></el-form><template #footer><span class="dialog_footer"><el-button type="primary" @click="erpsCfgonSubmit"><el-icon :size="20" style="margin-right: 5px;"><CircleCheckFilled /></el-icon>提交</el-button><el-button @click="erpsCfgCancle(erpsCfgDialogFormRef)">取消</el-button></span></template></el-dialog></div>
</template><style lang="scss" scoped>
.erps_cfg_layout {margin: 30px auto;background-color: #e6f1f9;box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 40px 0px;// 表格表头的背景色;::v-deep(.el-table th) {// 设置的表头的背景颜色;// background-color: #96b6cc;background-color: #e6f1f9;}//将表格的每一行悬停的背景色都设置为:transparent;::v-deep(.el-table--enable-row-hover .el-table__body tr:hover > td) {background-color: #afc4d3;}::v-deep(.el-table) {// font-size: 12px; // 此时会设置整个 table 表格文字变得很小}// 表格表头的下边框;::v-deep(.el-table th.is-leaf) {border-bottom: 1px solid #557A95;font-weight: 700;// font-size: 14px; // 此时是设置表格头下边框的文字大小;color: black;}// 设置隔行的背景色::v-deep(.el-table .warning-row) {background-color: #d6e6f5;}::v-deep(.el-table .success-row) {background-color: #e6f1f9;}.my_project {margin: 20px;.project_title {text-align: center;font-weight: 700;margin-bottom: 20px;}.project_bottom {margin: 20px 0;display: flex;justify-content: center;align-items: center;::v-deep(.el-pagination) {.el-pager {.number {background-color: #e6f1f9;}.is-active { background-color: #e6f1f9;}.more {background-color: #e6f1f9;}}.btn-next,.btn-prev {background-color: #e6f1f9;}}}}
}//去掉 dialog 右侧的 X 标记;
::v-deep(.el-dialog) {.el-dialog__header {.el-dialog__headerbtn {font-size: 30px;// display: none;.el-dialog__close {color: red;display: none; }} // .el-dialog__close {// color: red;// display: none; // }}// 修改操作按钮与整个 form 表单的距离;.el-dialog__footer {margin-top: -30px !important;}
}
</style>
其二、整体页面的展示为:
Ⅴ、小结:
其一、哪里有不对或不合适的地方,还请大佬们多多指点和交流!
其二、若有转发或引用本文章内容,请注明本博客地址(直接点击下面 url 跳转
) https://blog.csdn.net/weixin_43405300,创作不易,且行且珍惜!
其三、有兴趣的话,可以多多关注这个专栏(Vue(Vue2+Vue3)面试必备专栏)(直接点击下面 url 跳转
):https://blog.csdn.net/weixin_43405300/category_11525646.html?spm=1001.2014.3001.5482
其四、再有兴趣的话,也可以多多关注这个专栏(Java)(直接点击下面 url 跳转
):https://blog.csdn.net/weixin_43405300/category_12654744.html?spm=1001.2014.3001.5482
相关文章:

(el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
Ⅰ、Element-plus 提供的Select选择器组件与想要目标情况的对比: 1、Element-plus 提供Select组件情况: 其一、Element-ui 自提供的Select代码情况为(示例的代码): // Element-plus 提供的组件代码: <template><div class"f…...
Java基础之Math与Array类与System
文章目录 一、Math.random()二、Arrays.binarySearch()三、asList()四、System tip:以下是正文部分 一、Math.random() a < num < b int num (int)(Math.random() * (b - a 1)) a二、…...

警告:Hydration attribute mismatch on Note: this mismatch is check-only.(水合不匹配)
vue3Nuxt3运行代码是提示如下警告 [Vue warn]: Hydration attribute mismatch on <ul id"sub_menu_5_$$_sub1-popup" class"ant-menu ant-menu-sub ant-menu-inline" data-menu-list"true" style"display:none;">…...

【机器学习】CART决策树算法的核心思想及其大数据时代银行贷款参考案例——机器认知外界的重要算法
目录 引言 概述 CART决策树的特点 核心思想 减少不确定性的指标 基尼系数(Gini Index) 分类错误率 熵 银行实例 背景 数据准备 模型构建 模型评估与优化 应用与结果 代码示例 ✈✈✈✈引言✈✈✈✈ CART算法既可以用于分类问题࿰…...
编程软件是由什么编程的
编程软件是由什么编程的 在数字化的世界里,编程软件作为构建数字生态的基石,其背后所蕴含的奥秘往往令人感到困惑。那么,这些编程软件究竟是由什么编程的呢?这背后隐藏着怎样的逻辑与技术?接下来,我们将从…...

如何查看自己本地ip
1.winR 2.cmd 3.ipconfig...

高考分数限制下,选好专业还是选好学校?
高考分数限制下,选好专业还是选好学校? 高考作为每年一度的盛大考试,不仅关乎学生们的未来,更承载了家庭的期望。2004年高考刚刚结束,许多考生和家长已经开始为填报志愿而焦虑。选好学校和专业,直接关系到…...
Django学习(2)项目实战
1、环境及简介 前端开发:HTML、CSS、JavaScript 后端开发:Java、PHP、Python、GO 数据库:MySQL、MSSQL、Oracle、Redis 安装Django pip install Django 或 下载.whl后 pip install D:\xxx.whl 创建Django项目 File--New Projec…...

pdf格式转成jpg图片,pdf格式如何转jpg
pdf转图片的方法,对于许多人来说可能是一个稍显陌生的操作。然而,在日常生活和工作中,我们有时确实需要将pdf文件转换为图片格式,以便于在特定的场合或平台上进行分享、展示或编辑。以下,我们将详细介绍一个pdf转成图片…...

Java的三个接口Comparable,Comparator,Cloneable(浅拷贝与深拷贝)
Comparable 当我们要进行对象的比较的时候,我们是不能直接用>、< 这些符号直接进行比较的。 由于这是引用类型变量也是自定义类型变量,直接进行比较的时候,我们是通过对象的地址进行比较的,我们可以使用、! 进行两个对象的…...

pytorch学习笔记7
getitem在进行索引取值的时候自动调用,也是一个魔法方法,就像列表索引取值那样,一个意思 import torchvision from torch.utils.data import DataLoaderdata_transformtorchvision.transforms.Compose([torchvision.transforms.ToTensor()] ) test_datatorchvision.datasets.C…...
LeetCode热题3.无重复的最长字串
前言: 经过前序的一系列数据结构和算法学习后,开始用leetCode热题练练手。 . - 力扣(LeetCode) 给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为…...

Python武器库开发-武器库篇之SQL注入扫描器(五十九)
Python武器库开发-武器库篇之SQL注入扫描器(五十九) SQL注入漏洞简介以及危害 SQL注入漏洞是一种常见的Web应用程序漏洞,攻击者可以利用该漏洞在应用程序的数据库中执行恶意的SQL查询或指令。这可能导致数据泄露、数据损坏、应用程序崩溃或未经授权的访问。 SQL注…...

图说设计模式:单例模式
更多C学习笔记,关注 wx公众号:cpp读书笔记 5. 单例模式 单例模式 模式动机模式定义模式结构时序图代码分析模式分析实例优点缺点适用环境模式应用模式扩展总结 5.1. 模式动机 对于系统中的某些类来说,只有一个实例很重要,例如…...

探索设计模式——单例模式详解
前言:设计模式的作用主要是为了——利用设计方式的重用来自动地提高代码的重新利用、提高代码的灵活性、节省时间, 提高开发效率、低耦合,封装特性显著, 接口预留有利于扩展。 设计模式的种类有很多种,本篇内容主要讲解…...

建筑垃圾/城市固废倾倒转移乱象:EasyCVR+AI智能视频监控方案助力城市环保监管
近日有新闻记者报道,中央生态环境保护督察组在上海、浙江、江西、湖北、湖南、重庆、云南7省市督察发现,一些地方建筑垃圾处置工作存在明显短板,乱堆乱倒问题时有发生,比如,江西湘东区在杨家田地块违规设置弃土场&…...

C的I/O操作
目录 引言 一、文件与目录操作 1. 打开与关闭文件 2. 文件读写操作 3. 文件定位与错误处理 二、字符流与字节流 1. 字符流处理 2. 字节流处理 三、序列化与反序列化 1. 序列化 2. 反序列化 四、新的I/O(NIO) 表格总结 文件与目录操作 字符…...
Android Audio实战——声道信息回调(五)
在前面的 AudioTrack 构造中,我们传入了音频的声道信息,这一节我们就来详细介绍一下声道的配置信息。 一、声道介绍 音频中的声道配置从单声道到双声道(立体声)、再到多声道系统(如5.1和7.1),代表了声音录制和回放技术的发展,旨在提供越来越丰富和沉浸式的听觉体验。 …...
ThreeJS给模型添加介绍文字(贴在模型上 不会一直面向我们)
使用到 FontLoader跟 TextGeometry 引包 import {TextGeometry} from "three/examples/jsm/geometries/TextGeometry"; import {FontLoader} from "three/examples/jsm/loaders/FontLoader";使用 // 创建字体加载器并加载字体 const fontLoader new Fo…...

[Qt] Qt Creator 以及 Qt 在线安装教程
一、Qt Creator 下载及安装 1、从以下镜像源下载安装包常规安装即可 Qt Creator 也可以在第二步Qt 在线安装时一次性勾选安装,见后文 Qt Creator 中科大源下载地址 二、Qt 在线安装 1、根据所在平台选择对应的安装器下载 Qt 在线安装器下载 2、可能的安装报错…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...