Vue3 频率范围输入失焦自动校验实现
@[toc]
一、背景介绍
需求描述:
在Vue3项目中使用Arco Design插件,存在一个包含频率范围输入字段的表单页面。该频率范围输入值需根据所选中转台型号进行边界校验,具体规则如下:
1.系统支持四种中转台型号:
-
V1型号:有效频率范围为136-174兆赫兹
-
U1型号:有效频率范围为400-470兆赫兹
-
U2型号:有效频率范围为450-527兆赫兹
-
U3型号:有效频率范围为350-400兆赫兹
2.实现功能要求:
-
当用户在频率输入框失焦(blur事件)时,自动执行范围校验
-
若输入值小于当前型号的最小允许值,则自动修正为最小值
-
若输入值大于当前型号的最大允许值,则自动修正为最大值
-
修正操作需同步更新输入框显示值,并提供适当的用户反馈
代码片段分2种:
- 第一种:固定的单段范围,比如:136-174兆赫兹
- 第二种:多段范围:比如130-140,155-160
结论:之所以分2种代码,是因为多段范围用单段的带啊吗无法实现,因此实现了2套方法。
二、代码
2.1 针对单段范围
单段范围情况:
V1(136-174兆林兹)
U1(400-470兆赫)
U2(450-527兆赫兹)
U3(350-400兆赫兹)
<a-table-columndataIndex="cvTMixedChannelRXFreq":title="$t('MixedChannel_RX_Frequency')":tooltip="true":width="120"
><template #cell="{ rowIndex, record }"><a-input-numberv-model="record.cvTMixedChannelRXFreq"style="width: 120px":precision="6"step="0.000001":min="freqRange.min":max="freqRange.max"></a-input-number></template>
</a-table-column>
<a-table-columndataIndex="cvTMixedChannelTXFreq":title="$t('MixedChannel_TX_Frequency')":tooltip="true":width="120"
><template #cell="{ rowIndex, record }"><a-input-numberv-model="record.cvTMixedChannelTXFreq"style="width: 120px":precision="6"step="0.000001":min="freqRange.min":max="freqRange.max"></a-input-number></template>
</a-table-column>// 新增频率范围响应式变量
const freqRange = reactive({min: 0,max: 1000,
});// 获取设备信息并设置频率范围
const getDeviceInfoMixed = async () => {try {const response = await getParamList({sn: rssiId.value,type: 3,});commonResponse({response,onSuccess: () => {const modelNo = response.data.modelNo || "";// 根据型号设置频率范围if (modelNo.includes("V1")) {Object.assign(freqRange, { min: 136, max: 174 });} else if (modelNo.includes("U1")) {Object.assign(freqRange, { min: 400, max: 470 });} else if (modelNo.includes("U2")) {Object.assign(freqRange, { min: 450, max: 520 });} else if (modelNo.includes("U3")) {Object.assign(freqRange, { min: 350, max: 400 });} else if (modelNo.includes("U5")) {Object.assign(freqRange, { min: 809, max: 941 });} else {// 默认范围Object.assign(freqRange, { min: 0, max: 1000 });}},});} catch (error) {console.error("Failed to get device info:", error);}
};
2.2 针对多段范围
V1(136-174兆林兹)
U1(400-470兆赫)
U2(450-527兆赫兹)
U3(350-400兆赫兹)
U5接收(模拟/数字/混合):851MHz870MHz、935941MHz
U5发射(模拟/数字/混合):806825MHz、851MHz870MHz、896902MHz、935941MHz
当出现不在范围内的机型时,点击写入按钮后弹窗“无效机型!系统仅支持:U1/U2/U3/U5/V1"
<a-table-columndataIndex="cvTMixedChannelRXFreq":title="$t('MixedChannel_RX_Frequency')":tooltip="true":width="120"
><template #cell="{ rowIndex, record }"><a-input-numberv-model="record.cvTMixedChannelRXFreq"style="width: 120px":precision="6"step="0.000001"@blur="(e) => handleFrequencyBlur(e, record, 'receive', 'cvTMixedChannelRX')"></a-input-number></template>
</a-table-column>
<a-table-columndataIndex="cvTMixedChannelTXFreq":title="$t('MixedChannel_TX_Frequency')":tooltip="true":width="120"
><template #cell="{ rowIndex, record }"><a-input-numberv-model="record.cvTMixedChannelTXFreq"style="width: 120px":precision="6"step="0.000001"@blur="(e) => handleFrequencyBlur(e, record, 'transmit', 'cvTMixedChannelTX')"></a-input-number></template>
</a-table-column>
<div class="param-button">
<a-button:disabled="offlineDisabled"v-if="operationAuthorityDisabled"type="primary"class="huge"@click="setMixedChannelModeVal"style="margin-left: 12px">{{ $t("ParamWrite") }}</a-button
>
</div>const errorRangeOfRxtXFreq = ref(false);
const currentModel = ref('');
const currentModelArr = ref(["V1","U1","U2","U3","U5",]);const freqRanges = {V1: {receive: { ranges: [{ min: 136, max: 174 }], defaultValue: 136 },transmit: { ranges: [{ min: 136, max: 174 }], defaultValue: 136 }},U1: {receive: { ranges: [{ min: 400, max: 470 }], defaultValue: 400 },transmit: { ranges: [{ min: 400, max: 470 }], defaultValue: 400 }},U2: {receive: { ranges: [{ min: 450, max: 527 }], defaultValue: 450 },transmit: { ranges: [{ min: 450, max: 527 }], defaultValue: 450 }},U3: {receive: { ranges: [{ min: 350, max: 400 }], defaultValue: 350 },transmit: { ranges: [{ min: 350, max: 400 }], defaultValue: 350 }},U5: {receive: {ranges: [{ min: 851, max: 870 }, { min: 935, max: 941 }],defaultValue: 851},transmit: {ranges: [{ min: 806, max: 825 }, { min: 851, max: 870 }, { min: 896, max: 902 }, { min: 935, max: 941 }],defaultValue: 806}},default: {receive: { ranges: [{ min: 0, max: 1000 }]},transmit: { ranges: [{ min: 0, max: 1000 }]}}
};const handleFrequencyBlur = (e, record, type, label) => {const value = parseFloat(e.target.value);const config = freqRanges[currentModel.value]?.[type] || freqRanges.default[type];const isValid = config.ranges.some(range =>value >= range.min && value <= range.max);if (!isValid) {if (config.defaultValue) {nextTick(() => {record[`${label}Freq`] = config.defaultValue;})}}
};const validateRecord = (record) => {const isReceiveValid = validateFrequency(record.cvTMixedChannelRXFreq, 'receive');const isTransmitValid = validateFrequency(record.cvTMixedChannelTXFreq, 'transmit');return isReceiveValid && isTransmitValid;
};const validateFrequency = (value, type) => {if (!currentModel.value) return true;const config = freqRanges[currentModel.value]?.[type] || freqRanges.default[type];return config.ranges.some(range =>value >= range.min && value <= range.max);
};// 获取设备信息并设置频率范围
const getDeviceInfoMixed = async () => {try {const response = await getParamList({sn: rssiId.value,type: 3,});commonResponse({response,onSuccess: () => {const modelNo = response.data.modelNo || "";// 根据型号设置频率范围if (modelNo.includes("V1")) {currentModel.value = "V1";} else if (modelNo.includes("U1")) {currentModel.value = "U1";} else if (modelNo.includes("U2")) {currentModel.value = "U2";} else if (modelNo.includes("U3")) {currentModel.value = "U3";} else if (modelNo.includes("U5")) {currentModel.value = "U5";} else {errorRangeOfRxtXFreq.value = true;currentModel.value = "default";}},});} catch (error) {console.error("Failed to get device info:", error);}
};const setMixedChannelModeVal = () => {if (currentModelArr.value.includes(currentModel.value)) {mixedChannelList.value.forEach(record =>{if (!validateRecord(record)) {errorRangeOfRxtXFreq.value = true;}})}if (errorRangeOfRxtXFreq.value) {window.Message.error(t('ErrorRangeOfRxtXFreq'))return;}调用更新接口....
}