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-cli项目配置多环境的详细操作过程

    vue-cli项目配置多环境的详细操作过程

    vue-cli 默认只提供了 dev 和 prod 两种环境。这篇文章主要介绍了vue-cli项目配置多环境的详细操作过程,需要的朋友可以参考下
    2018-10-10
  • Vue父子组件通信全面详细介绍

    Vue父子组件通信全面详细介绍

    这篇文章主要介绍了React中父子组件通信详解,在父组件中,为子组件添加属性数据,即可实现父组件向子组件通信,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-10-10
  • vue实现element表格里表头信息提示功能(推荐)

    vue实现element表格里表头信息提示功能(推荐)

    小编最近接了这样一个需求,需要在element表格操作一栏添加提示功能,下面小编给大家带来了基于vue实现element表格里表头信息提示功能,需要的朋友参考下吧
    2019-11-11
  • vue如何利用store实现两个平行组件间的传值

    vue如何利用store实现两个平行组件间的传值

    这篇文章主要介绍了vue如何利用store实现两个平行组件间的传值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • Vue中的异步组件函数实现代码

    Vue中的异步组件函数实现代码

    这篇文章主要介绍了Vue中的异步组件函数实现代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-07-07
  • vue项目npm install失败的问题解决方案

    vue项目npm install失败的问题解决方案

    本文主要介绍了vue项目npm install失败的问题解决方案,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-01-01
  • Vue+ElementUI表格状态区分,row-class-name属性详解

    Vue+ElementUI表格状态区分,row-class-name属性详解

    这篇文章主要介绍了Vue+ElementUI表格状态区分,row-class-name属性,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • vue 实现左右拖拽元素并且不超过他的父元素的宽度

    vue 实现左右拖拽元素并且不超过他的父元素的宽度

    这篇文章主要介绍了vue 实现左右拖拽元素并且不超过他的父元素的宽度,需要的朋友可以参考下
    2018-11-11
  • vue制作点击切换图片效果的详细思路与步骤

    vue制作点击切换图片效果的详细思路与步骤

    这篇文章主要给大家介绍了关于vue制作点击切换图片效果的详细思路与步骤,图片切换是一个很经典的Vue入门学习案例,在你学习完一些基本的v-指令后,你可以尝试去写一个简单的demo去巩固和熟悉这些指令的使用方法,需要的朋友可以参考下
    2023-11-11
  • Element Rate 评分的使用方法

    Element Rate 评分的使用方法

    这篇文章主要介绍了Element Rate 评分的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07

最新评论