Vue3實現(xiàn)進制轉(zhuǎn)換器的具體方案
在線工具網(wǎng)址:https://see-tool.com/base-converter
工具截圖:

一、核心設(shè)計思路
1.1 十進制中轉(zhuǎn)策略
所有進制轉(zhuǎn)換都通過十進制作為中轉(zhuǎn)站:
任意進制 → parseInt(value, base) → 十進制 十進制 → decimal.toString(base) → 目標進制
這樣避免了 N×(N-1) 種轉(zhuǎn)換函數(shù)的組合爆炸,復(fù)雜度從 O(n²) 降至 O(n)。
1.2 防死鎖機制
四個輸入框?qū)崟r同步時,必須防止循環(huán)觸發(fā):
let isUpdating = false
const onSyncInput = (source) => {
if (isUpdating) return // 阻止遞歸調(diào)用
isUpdating = true
// ... 執(zhí)行轉(zhuǎn)換邏輯
isUpdating = false
}
二、同步轉(zhuǎn)換模式實現(xiàn)
2.1 核心轉(zhuǎn)換函數(shù)
const onSyncInput = (source) => {
if (isUpdating) return
isUpdating = true
try {
let decimalNum = 0
let cleanValue = ''
// 第一步: 數(shù)據(jù)清洗 + 轉(zhuǎn)十進制
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
}
關(guān)鍵點:
- 數(shù)據(jù)清洗: 用正則去除空格、下劃線、前綴等干擾字符
- 嚴格驗證: 每種進制都有對應(yīng)的正則驗證規(guī)則
- 跳過源框: 避免回填源輸入框?qū)е鹿鈽颂鴦?/li>
- 異常處理: try-catch 防止非法輸入崩潰
2.2 數(shù)據(jù)驗證正則
/^[01]+$/ // 二進制: 只允許 0 和 1 /^[0-7]+$/ // 八進制: 只允許 0-7 /^\d+$/ // 十進制: 只允許數(shù)字 /^[0-9A-Fa-f]+$/ // 十六進制: 允許 0-9 和 A-F(大小寫)
2.3 格式化顯示函數(shù)
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. 數(shù)字分組(提升可讀性)
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
}
分組規(guī)則:
- 二進制/十六進制: 每 4 位一組
- 八進制/十進制: 每 3 位一組
2.4 輔助函數(shù)
// 清除其他輸入框
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 = ''
}
// 復(fù)制文本(去除格式化空格)
const copyText = async (text) => {
if (!text) return
try {
// 去除空格、下劃線、前綴,復(fù)制純凈數(shù)據(jù)
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'))
}
}
三、自定義進制模式實現(xiàn)
3.1 核心轉(zhuǎn)換函數(shù)
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 優(yōu)勢:
parseInt(str, radix): 支持 2-36 進制解析num.toString(radix): 支持 2-36 進制輸出- 無需自己實現(xiàn)進制轉(zhuǎn)換算法
3.2 進制交換函數(shù)
const swapBases = () => {
// 交換源進制和目標進制
const temp = customFromBase.value
customFromBase.value = customToBase.value
customToBase.value = temp
// 將輸出作為新的輸入
customInput.value = customOutput.value
convertCustom()
}
四、響應(yīng)式配置實現(xiàn)
4.1 大小寫切換
watch(uppercaseHex, () => {
if (hexValue.value) {
hexValue.value = uppercaseHex.value
? hexValue.value.toUpperCase()
: hexValue.value.toLowerCase()
}
})
4.2 前綴/分組切換
// 監(jiān)聽前綴切換
watch(showPrefix, () => {
if (decimalValue.value) {
onSyncInput('decimal') // 重新格式化所有輸入框
}
})
// 監(jiān)聽數(shù)字分組切換
watch(digitGrouping, () => {
if (decimalValue.value) {
onSyncInput('decimal')
}
})
4.3 自定義進制變化
// 監(jiān)聽自定義進制變化,自動重新轉(zhuǎn)換
watch([customFromBase, customToBase], () => {
convertCustom()
})
五、狀態(tài)管理
5.1 響應(yīng)式狀態(tài)定義
// Tab 切換
const activeTab = ref('sync')
// 同步轉(zhuǎn)換模式的四個輸入框
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) // 數(shù)字分組
// 自定義進制模式
const customFromBase = ref(10) // 源進制
const customToBase = ref(16) // 目標進制
const customInput = ref('') // 輸入值
const customOutput = ref('') // 輸出值
// 防死鎖標志位
let isUpdating = false
六、已知限制與改進方向
6.1 大數(shù)精度問題
當前使用 Number 類型,超過 Number.MAX_SAFE_INTEGER (2^53 - 1) 會丟失精度。
改進方案:
// 使用 BigInt 替代 Number
const decimalNum = BigInt(`0b${cleanValue}`)
const result = decimalNum.toString(16)
注意事項:
BigInt不支持小數(shù)BigInt和Number不能直接運算- 需要特殊處理邊界情況
6.2 性能優(yōu)化
對于頻繁輸入場景,可添加防抖:
import { debounce } from 'lodash-es'
const onSyncInput = debounce((source) => {
// ... 轉(zhuǎn)換邏輯
}, 100)
七、核心流程總結(jié)
用戶輸入 → 數(shù)據(jù)清洗 → 正則驗證 → parseInt(轉(zhuǎn)十進制)
↓
十進制中轉(zhuǎn)
↓
格式化顯示 ← toString(轉(zhuǎn)目標進制) ← 廣播更新
核心原則:
- 十進制中轉(zhuǎn): 避免組合爆炸
- 防死鎖機制: 阻止循環(huán)觸發(fā)
- 數(shù)據(jù)清洗: 確保輸入合法
- 格式化顯示: 提升可讀性
- 原生 API: 避免重復(fù)造輪子
以上就是Vue3實現(xiàn)進制轉(zhuǎn)換器的具體方案的詳細內(nèi)容,更多關(guān)于Vue3進制轉(zhuǎn)換器的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue文件如何轉(zhuǎn)換成base64并去除多余的文件類型前綴
這篇文章主要介紹了Vue文件如何轉(zhuǎn)換成base64并去除多余的文件類型前綴問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
vue輸入框中輸完后光標自動跳到下一個輸入框中的實現(xiàn)方法
最近在工作中遇到了些問題,總結(jié)下分享給同樣遇到這個問題的朋友,這篇文章主要給大家介紹了關(guān)于vue輸入框中輸完后光標自動跳到下一個輸入框中的實現(xiàn)方法,需要的朋友可以參考下2023-03-03
解決elementui上傳組件el-upload無法第二次上傳問題
這篇文章主要介紹了解決elementui上傳組件el-upload無法第二次上傳問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03
使用el-upload實現(xiàn)文件上傳方式(包括預(yù)覽,下載)
該文章介紹了兩種文件上傳、預(yù)覽和下載的方法,分別是通過卡片形式和按鈕形式,卡片形式中的下載和預(yù)覽功能尚未完善,父組件使用了el-upload組件,可以實現(xiàn)新增、編輯和查看文件的功能2025-11-11
Vue.js bootstrap前端實現(xiàn)分頁和排序
這篇文章主要為大家詳細介紹了Vue.js結(jié)合bootstrap前端實現(xiàn)分頁和排序效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03
關(guān)于element-ui中@selection-change執(zhí)行兩次的問題
這篇文章主要介紹了關(guān)于element-ui中@selection-change執(zhí)行兩次的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08

