Vue3实现进制转换器的具体方案
更新时间:2026年01月27日 10:04:03 作者:滕青山
这是一个支持二、八、十、十六进制实时同步转换的在线工具。采用十进制中转策略,内置防死锁、数据清洗、正则校验与格式化显示(前缀/分组),并支持2–36进制自定义转换。代码简洁健壮,兼顾实用性与可维护性。
工具截图:

一、核心设计思路
1.1 十进制中转策略
所有进制转换都通过十进制作为中转站:
任意进制 → parseInt(value, base) → 十进制 十进制 → decimal.toString(base) → 目标进制
这样避免了 N×(N-1) 种转换函数的组合爆炸,复杂度从 O(n²) 降至 O(n)。
1.2 防死锁机制
四个输入框实时同步时,必须防止循环触发:
let isUpdating = false
const onSyncInput = (source) => {
if (isUpdating) return // 阻止递归调用
isUpdating = true
// ... 执行转换逻辑
isUpdating = false
}
二、同步转换模式实现
2.1 核心转换函数
const onSyncInput = (source) => {
if (isUpdating) return
isUpdating = true
try {
let decimalNum = 0
let cleanValue = ''
// 第一步: 数据清洗 + 转十进制
switch (source) {
case 'binary':
// 去除空格、下划线、0b前缀
cleanValue = binaryValue.value.replace(/[\s_]/g, '').replace(/^0[bB]/, '')
// 正则验证是否为合法二进制
if (cleanValue && /^[01]+$/.test(cleanValue)) {
decimalNum = parseInt(cleanValue, 2)
} else {
clearOthers('binary') // 清空其他框
isUpdating = false
return
}
break
case 'octal':
cleanValue = octalValue.value.replace(/[\s_]/g, '').replace(/^0[oO]/, '')
if (cleanValue && /^[0-7]+$/.test(cleanValue)) {
decimalNum = parseInt(cleanValue, 8)
} else {
clearOthers('octal')
isUpdating = false
return
}
break
case 'decimal':
cleanValue = decimalValue.value.replace(/[\s_,]/g, '')
if (cleanValue && /^\d+$/.test(cleanValue)) {
decimalNum = parseInt(cleanValue, 10)
} else {
clearOthers('decimal')
isUpdating = false
return
}
break
case 'hex':
cleanValue = hexValue.value.replace(/[\s_]/g, '').replace(/^0[xX]/, '')
if (cleanValue && /^[0-9A-Fa-f]+$/.test(cleanValue)) {
decimalNum = parseInt(cleanValue, 16)
} else {
clearOthers('hex')
isUpdating = false
return
}
break
}
// 第二步: 广播更新其他进制(跳过源输入框)
if (source !== 'binary') {
binaryValue.value = formatValue(decimalNum.toString(2), 2)
}
if (source !== 'octal') {
octalValue.value = formatValue(decimalNum.toString(8), 8)
}
if (source !== 'decimal') {
decimalValue.value = decimalNum.toString()
}
if (source !== 'hex') {
let hex = decimalNum.toString(16)
if (uppercaseHex.value) hex = hex.toUpperCase()
hexValue.value = formatValue(hex, 16)
}
} catch (err) {
console.error('Conversion error:', err)
}
isUpdating = false
}
关键点:
- 数据清洗: 用正则去除空格、下划线、前缀等干扰字符
- 严格验证: 每种进制都有对应的正则验证规则
- 跳过源框: 避免回填源输入框导致光标跳动
- 异常处理: try-catch 防止非法输入崩溃
2.2 数据验证正则
/^[01]+$/ // 二进制: 只允许 0 和 1 /^[0-7]+$/ // 八进制: 只允许 0-7 /^\d+$/ // 十进制: 只允许数字 /^[0-9A-Fa-f]+$/ // 十六进制: 允许 0-9 和 A-F(大小写)
2.3 格式化显示函数
const formatValue = (value, base) => {
let formatted = value
// 1. 添加前缀(可选)
let prefix = ''
if (showPrefix.value) {
switch (base) {
case 2: prefix = '0b'; break
case 8: prefix = '0o'; break
case 16: prefix = '0x'; break
}
}
// 2. 数字分组(提升可读性)
if (digitGrouping.value && formatted.length > 4) {
let groupSize = 4
if (base === 2) groupSize = 4 // 二进制: 1010 1100
else if (base === 8) groupSize = 3 // 八进制: 123 456
else if (base === 10) groupSize = 3 // 十进制: 123 456
else if (base === 16) groupSize = 4 // 十六进制: 1A2B 3C4D
// 从右向左分组
const groups = []
for (let i = formatted.length; i > 0; i -= groupSize) {
groups.unshift(formatted.substring(Math.max(0, i - groupSize), i))
}
formatted = groups.join(' ')
}
return prefix + formatted
}
分组规则:
- 二进制/十六进制: 每 4 位一组
- 八进制/十进制: 每 3 位一组
2.4 辅助函数
// 清除其他输入框
const clearOthers = (except) => {
if (except !== 'binary') binaryValue.value = ''
if (except !== 'octal') octalValue.value = ''
if (except !== 'decimal') decimalValue.value = ''
if (except !== 'hex') hexValue.value = ''
}
// 清除全部
const clearAll = () => {
binaryValue.value = ''
octalValue.value = ''
decimalValue.value = ''
hexValue.value = ''
}
// 复制文本(去除格式化空格)
const copyText = async (text) => {
if (!text) return
try {
// 去除空格、下划线、前缀,复制纯净数据
const cleanText = text.replace(/[\s_]/g, '')
await navigator.clipboard.writeText(cleanText)
safeMessage.success(t('baseConverter.notifications.copySuccess'))
} catch (err) {
console.error('Failed to copy:', err)
safeMessage.error(t('baseConverter.notifications.copyFailed'))
}
}
三、自定义进制模式实现
3.1 核心转换函数
const convertCustom = () => {
if (!customInput.value.trim()) {
customOutput.value = ''
return
}
try {
// 利用原生 API 支持 2-36 进制
const decimal = parseInt(customInput.value, customFromBase.value)
if (isNaN(decimal)) {
customOutput.value = t('common.invalidInput')
return
}
customOutput.value = decimal.toString(customToBase.value).toUpperCase()
} catch (err) {
customOutput.value = t('common.conversionError')
}
}
原生 API 优势:
parseInt(str, radix): 支持 2-36 进制解析num.toString(radix): 支持 2-36 进制输出- 无需自己实现进制转换算法
3.2 进制交换函数
const swapBases = () => {
// 交换源进制和目标进制
const temp = customFromBase.value
customFromBase.value = customToBase.value
customToBase.value = temp
// 将输出作为新的输入
customInput.value = customOutput.value
convertCustom()
}
四、响应式配置实现
4.1 大小写切换
watch(uppercaseHex, () => {
if (hexValue.value) {
hexValue.value = uppercaseHex.value
? hexValue.value.toUpperCase()
: hexValue.value.toLowerCase()
}
})
4.2 前缀/分组切换
// 监听前缀切换
watch(showPrefix, () => {
if (decimalValue.value) {
onSyncInput('decimal') // 重新格式化所有输入框
}
})
// 监听数字分组切换
watch(digitGrouping, () => {
if (decimalValue.value) {
onSyncInput('decimal')
}
})
4.3 自定义进制变化
// 监听自定义进制变化,自动重新转换
watch([customFromBase, customToBase], () => {
convertCustom()
})
五、状态管理
5.1 响应式状态定义
// Tab 切换
const activeTab = ref('sync')
// 同步转换模式的四个输入框
const binaryValue = ref('')
const octalValue = ref('')
const decimalValue = ref('')
const hexValue = ref('')
// 配置选项
const uppercaseHex = ref(false) // 十六进制大写
const showPrefix = ref(false) // 显示前缀 (0x, 0b)
const digitGrouping = ref(true) // 数字分组
// 自定义进制模式
const customFromBase = ref(10) // 源进制
const customToBase = ref(16) // 目标进制
const customInput = ref('') // 输入值
const customOutput = ref('') // 输出值
// 防死锁标志位
let isUpdating = false
六、已知限制与改进方向
6.1 大数精度问题
当前使用 Number 类型,超过 Number.MAX_SAFE_INTEGER (2^53 - 1) 会丢失精度。
改进方案:
// 使用 BigInt 替代 Number
const decimalNum = BigInt(`0b${cleanValue}`)
const result = decimalNum.toString(16)
注意事项:
BigInt不支持小数BigInt和Number不能直接运算- 需要特殊处理边界情况
6.2 性能优化
对于频繁输入场景,可添加防抖:
import { debounce } from 'lodash-es'
const onSyncInput = debounce((source) => {
// ... 转换逻辑
}, 100)
七、核心流程总结
用户输入 → 数据清洗 → 正则验证 → parseInt(转十进制)
↓
十进制中转
↓
格式化显示 ← toString(转目标进制) ← 广播更新
核心原则:
- 十进制中转: 避免组合爆炸
- 防死锁机制: 阻止循环触发
- 数据清洗: 确保输入合法
- 格式化显示: 提升可读性
- 原生 API: 避免重复造轮子
以上就是Vue3实现进制转换器的具体方案的详细内容,更多关于Vue3进制转换器的资料请关注脚本之家其它相关文章!
相关文章
Vue+ElementUI表格状态区分,row-class-name属性详解
这篇文章主要介绍了Vue+ElementUI表格状态区分,row-class-name属性,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-08-08


最新评论