Vue3实现进制转换器的具体方案

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

在线工具网址:https://see-tool.com/base-converter

工具截图:

一、核心设计思路

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
}

关键点:

  1. 数据清洗: 用正则去除空格、下划线、前缀等干扰字符
  2. 严格验证: 每种进制都有对应的正则验证规则
  3. 跳过源框: 避免回填源输入框导致光标跳动
  4. 异常处理: 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 不支持小数
  • BigIntNumber 不能直接运算
  • 需要特殊处理边界情况

6.2 性能优化

对于频繁输入场景,可添加防抖:

import { debounce } from 'lodash-es'

const onSyncInput = debounce((source) => {
  // ... 转换逻辑
}, 100)

七、核心流程总结

用户输入 → 数据清洗 → 正则验证 → parseInt(转十进制)
                                        ↓
                                   十进制中转
                                        ↓
    格式化显示 ← toString(转目标进制) ← 广播更新

核心原则:

  1. 十进制中转: 避免组合爆炸
  2. 防死锁机制: 阻止循环触发
  3. 数据清洗: 确保输入合法
  4. 格式化显示: 提升可读性
  5. 原生 API: 避免重复造轮子

以上就是Vue3实现进制转换器的具体方案的详细内容,更多关于Vue3进制转换器的资料请关注脚本之家其它相关文章!

相关文章

  • Vue文件如何转换成base64并去除多余的文件类型前缀

    Vue文件如何转换成base64并去除多余的文件类型前缀

    这篇文章主要介绍了Vue文件如何转换成base64并去除多余的文件类型前缀问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Vue简明介绍配置对象的配置选项

    Vue简明介绍配置对象的配置选项

    我们知道每一个vue项目应用都是通过vue的构造函数进行创建一个新的vue项目的。创建vue实例的配置对象,可以包括一下属性选项,比如:data、methods、watch、template等等,每一个选项都有不同的功能,大家可以根据自己的需求选择不同的配置
    2022-08-08
  • vue输入框中输完后光标自动跳到下一个输入框中的实现方法

    vue输入框中输完后光标自动跳到下一个输入框中的实现方法

    最近在工作中遇到了些问题,总结下分享给同样遇到这个问题的朋友,这篇文章主要给大家介绍了关于vue输入框中输完后光标自动跳到下一个输入框中的实现方法,需要的朋友可以参考下
    2023-03-03
  • 解决elementui上传组件el-upload无法第二次上传问题

    解决elementui上传组件el-upload无法第二次上传问题

    这篇文章主要介绍了解决elementui上传组件el-upload无法第二次上传问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 使用el-upload实现文件上传方式(包括预览,下载)

    使用el-upload实现文件上传方式(包括预览,下载)

    该文章介绍了两种文件上传、预览和下载的方法,分别是通过卡片形式和按钮形式,卡片形式中的下载和预览功能尚未完善,父组件使用了el-upload组件,可以实现新增、编辑和查看文件的功能
    2025-11-11
  • Vue.js bootstrap前端实现分页和排序

    Vue.js bootstrap前端实现分页和排序

    这篇文章主要为大家详细介绍了Vue.js结合bootstrap前端实现分页和排序效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • Vue3使用v-if指令进行条件渲染的实例代码

    Vue3使用v-if指令进行条件渲染的实例代码

    条件渲染是根据条件的真假来有条件地渲染元素,在Vue.js 3.x中,常见的条件渲染包括使用v-if指令和v-show指令,本文讲解使用v-if指令进行条件渲染,需要的朋友可以参考下
    2024-03-03
  • 关于element-ui中@selection-change执行两次的问题

    关于element-ui中@selection-change执行两次的问题

    这篇文章主要介绍了关于element-ui中@selection-change执行两次的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • vue+elementUI中表格高亮或字体颜色改变操作

    vue+elementUI中表格高亮或字体颜色改变操作

    这篇文章主要介绍了vue+elementUI中表格高亮或字体颜色改变操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • 怎样在vue项目下添加ESLint的方法

    怎样在vue项目下添加ESLint的方法

    这篇文章主要介绍了怎样在vue项目下添加ESLint的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05

最新评论