uniapp-vue3來實現一個金額千分位展示效果

前言:

????????uniapp-vue3來實現一個金額千分位展示效果

實現效果:

實現目標:

1、封裝組件,組件內部要實現,

  • input輸入金額后,聚焦離開后,金額以千分位效果展示,
  • 聚焦后展示大寫金額的彈框
  • 隨時寫的內容,可以用v-model傳輸給父級
  • 金額要有最大值,還要只能輸入數字,小數后只能有2位

2、實現方法:

1)input框輸入金額,并添加聚焦,離開事件

頁面上添加內容:

<inputv-model="displayValue"@input="handleInput"@blur="handleBlur"@focus="handleFocus"placeholder="請輸入金額"
/>

js中增加配置

const displayValue = ref('')
const rawValue = ref(0)const handleInput = (e) => {let val = e.detail.value
}// 處理失去焦點
const handleBlur = () => {
}// 處理獲取焦點
const handleFocus = () => {
}

2)輸入的內容,處理非數字內容,還有只能有一個小數點,小數點后添加2位限制,最大值限制

const displayValue = ref('') //千分位處理后的字段
const rawValue = ref(0)      //拿到的實際內容數據
const maxFloatNum = ref(2)  //限制小數點后幾位
const maxNum = ref(100000000000) //設置最大值
const handleInput = (e) => {let val = e.detail.valueif(!val) return ''let value = val.toString().replace(/[^\d.]/g, '')if (value.length > 1 && value.startsWith('0')) {value = value.substring(1)}const min = 0const max = maxNum.value// 確保只有一個點const parts = value.split('.')if (parts.length > 2) {value = parts[0] + '.' + parts.slice(1).join('')}// 限制小數點后兩位if (parts.length === maxFloatNum.value) {value = parts[0] + '.' + parts[1].slice(0, maxFloatNum.value)}// 轉換為數字const numValue = parseFloat(value || 0)// 檢查范圍if (numValue > max) {value = max.toString()} else if (numValue < min) {value = min.toString()}rawValue.value = numValuedisplayValue.value = value}

3)聚焦和離開時候將數據轉換位千分位,通過正則

// 格式化顯示值(添加千分位)const formatDisplay = (value) => {const num = parseFloat(value || 0)return num.toFixed(maxFloatNum.value).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
// 處理失去焦點
const handleBlur = () => {displayValue.value = formatDisplay(rawValue.value)
}// 處理獲取焦點
const handleFocus = () => {displayValue.value = rawValue.value.toString()
}

4)來寫一個大小寫轉換的功能,并展示到界面input上面,配合樣式

js中封裝小寫轉大寫方法
//封裝的小寫轉大寫方法,適合各種場景const amountToChinese = (num)=> {const cnNums = ['零', '壹', '貳', '叁', '肆', '伍', '陸', '柒', '捌', '玖']const cnIntRadice = ['', '拾', '佰', '仟']const cnIntUnits = ['', '萬', '億', '兆']const cnDecUnits = ['角', '分', '毫', '厘']const cnInteger = '整'const cnIntLast = '元'if(num > maxNum.value){return '-'}// 處理負數let sign = '';if (num < 0) {sign = '負';num = Math.abs(num);}// 分離整數和小數部分let numStr = num.toString();let integerStr = '';let decimalStr = '';if (numStr.indexOf('.') !== -1) {const parts = numStr.split('.');integerStr = parts[0];decimalStr = parts[1].substring(0, 4); // 最多支持4位小數} else {integerStr = numStr;}// 處理整數部分let chineseInteger = '';if (parseInt(integerStr, 10) > 0) {let zeroCount = 0;const intLen = integerStr.length;for (let i = 0; i < intLen; i++) {const n = integerStr.charAt(i);const p = intLen - i - 1;const q = p / 4;const m = p % 4;if (n === '0') {zeroCount++;} else {if (zeroCount > 0) {chineseInteger += cnNums[0];}zeroCount = 0;chineseInteger += cnNums[parseInt(n)] + cnIntRadice[m];}if (m === 0 && zeroCount < 4) {chineseInteger += cnIntUnits[q];}}chineseInteger += cnIntLast;}// 處理小數部分let chineseDecimal = '';if (decimalStr) {for (let i = 0; i < decimalStr.length; i++) {const n = decimalStr.charAt(i);if (n !== '0') {chineseDecimal += cnNums[parseInt(n)] + cnDecUnits[i];}}}// 組合結果let result = sign + chineseInteger + chineseDecimal;if (!chineseInteger && !chineseDecimal) {result = cnNums[0] + cnIntLast + cnInteger;} else if (!chineseDecimal) {result += cnInteger;}return result;}
樣式中通過定位,來實現input上面內容的展示
<style lang="scss" scoped>.moneyInputBox{position: relative;input{width: 100%;padding: 0 10rpx !important;box-sizing: border-box !important;border: 1rpx solid #dadbde;height: 62rpx !important;line-height: 42rpx!important;border-radius: 4px;}.bigNumBox{position: absolute;bottom: 76rpx;width:auto;background: rgba(0,0,0,.5);padding:10rpx;color:#fff;border-radius: 20rpx;border:1rpx solid #dadbde;}}
</style>

5)將我們當前的組件,用watch監聽+emit發送的方法,實現數據的雙向綁定,可以在父級用v-model來綁定內容

js具體配置:
<script setup>import { ref, watch, defineProps, defineEmits } from 'vue'const props = defineProps({modelValue: {type: [Number, String],default: 0}})const emit = defineEmits(['update:modelValue'])// 監聽外部傳入的modelValue變化watch(() => props.modelValue, (newVal) => {if (newVal !== rawValue.value) {rawValue.value = parseFloat(newVal) || 0displayValue.value = formatDisplay(rawValue.value)bigNumCont.value = amountToChinese(rawValue.value)}}, { immediate: true })  </script>
父級調用:
<moneyInput v-model="moneyNum"></moneyInput><script setup>const moneyNum = ref(100)

封裝代碼源碼? moneyInput.vue

<template><view class="moneyInputBox"><inputv-model="displayValue"@input="handleInput"@blur="handleBlur"@focus="handleFocus"placeholder="請輸入金額"/><view v-if="showBigNum" class="bigNumBox">{{bigNumCont}}</view></view>
</template><script setup>import { ref, watch, defineProps, defineEmits } from 'vue'const props = defineProps({modelValue: {type: [Number, String],default: 0}})const emit = defineEmits(['update:modelValue'])const displayValue = ref('')const rawValue = ref(0)const maxFloatNum = ref(2)const maxNum = ref(100000000000)const showBigNum = ref(false)const bigNumCont = ref('')// 格式化顯示值(添加千分位)const formatDisplay = (value) => {const num = parseFloat(value || 0)return num.toFixed(maxFloatNum.value).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}// 處理輸入變化const handleInput = (e) => {let val = e.detail.valueif(!val) return ''let value = val.toString().replace(/[^\d.]/g, '')if (value.length > 1 && value.startsWith('0')) {value = value.substring(1)}const min = 0const max = maxNum.value// 確保只有一個點const parts = value.split('.')if (parts.length > 2) {value = parts[0] + '.' + parts.slice(1).join('')}// 限制小數點后兩位if (parts.length === maxFloatNum.value) {value = parts[0] + '.' + parts[1].slice(0, maxFloatNum.value)}// 轉換為數字const numValue = parseFloat(value || 0)// 檢查范圍if (numValue > max) {value = max.toString()} else if (numValue < min) {value = min.toString()}rawValue.value = numValuedisplayValue.value = valuebigNumCont.value = amountToChinese(rawValue.value)emit('update:modelValue', rawValue.value)}// 處理失去焦點const handleBlur = () => {showBigNum.value = falsedisplayValue.value = formatDisplay(rawValue.value)bigNumCont.value = amountToChinese(rawValue.value)}// 處理獲取焦點const handleFocus = () => {showBigNum.value = truedisplayValue.value = rawValue.value.toString()bigNumCont.value = amountToChinese(rawValue.value)}const amountToChinese = (num)=> {const cnNums = ['零', '壹', '貳', '叁', '肆', '伍', '陸', '柒', '捌', '玖']const cnIntRadice = ['', '拾', '佰', '仟']const cnIntUnits = ['', '萬', '億', '兆']const cnDecUnits = ['角', '分', '毫', '厘']const cnInteger = '整'const cnIntLast = '元'if(num > maxNum.value){return '-'}// 處理負數let sign = '';if (num < 0) {sign = '負';num = Math.abs(num);}// 分離整數和小數部分let numStr = num.toString();let integerStr = '';let decimalStr = '';if (numStr.indexOf('.') !== -1) {const parts = numStr.split('.');integerStr = parts[0];decimalStr = parts[1].substring(0, 4); // 最多支持4位小數} else {integerStr = numStr;}// 處理整數部分let chineseInteger = '';if (parseInt(integerStr, 10) > 0) {let zeroCount = 0;const intLen = integerStr.length;for (let i = 0; i < intLen; i++) {const n = integerStr.charAt(i);const p = intLen - i - 1;const q = p / 4;const m = p % 4;if (n === '0') {zeroCount++;} else {if (zeroCount > 0) {chineseInteger += cnNums[0];}zeroCount = 0;chineseInteger += cnNums[parseInt(n)] + cnIntRadice[m];}if (m === 0 && zeroCount < 4) {chineseInteger += cnIntUnits[q];}}chineseInteger += cnIntLast;}// 處理小數部分let chineseDecimal = '';if (decimalStr) {for (let i = 0; i < decimalStr.length; i++) {const n = decimalStr.charAt(i);if (n !== '0') {chineseDecimal += cnNums[parseInt(n)] + cnDecUnits[i];}}}// 組合結果let result = sign + chineseInteger + chineseDecimal;if (!chineseInteger && !chineseDecimal) {result = cnNums[0] + cnIntLast + cnInteger;} else if (!chineseDecimal) {result += cnInteger;}return result;}// 監聽外部傳入的modelValue變化watch(() => props.modelValue, (newVal) => {if (newVal !== rawValue.value) {rawValue.value = parseFloat(newVal) || 0displayValue.value = formatDisplay(rawValue.value)bigNumCont.value = amountToChinese(rawValue.value)}}, { immediate: true })
</script><style lang="scss" scoped>.moneyInputBox{position: relative;input{width: 100%;padding: 0 10rpx !important;box-sizing: border-box !important;border: 1rpx solid #dadbde;height: 62rpx !important;line-height: 42rpx!important;border-radius: 4px;}.bigNumBox{position: absolute;bottom: 76rpx;width:auto;background: rgba(0,0,0,.5);padding:10rpx;color:#fff;border-radius: 20rpx;border:1rpx solid #dadbde;}}
</style>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/92011.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/92011.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/92011.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

途游Android面試題及參考答案

對 Java 面向對象的理解是什么?多態的實現方法有哪些? Java 面向對象是一種編程思想,核心在于將現實世界中的事物抽象為 “對象”,每個對象由 “屬性”(數據)和 “方法”(行為)組成,通過對象之間的交互完成功能。其核心特性包括封裝、繼承和多態: 封裝是指將對象的屬…

通過filezilla在局域網下實現高速傳輸數據

一. filezilla安裝 1.1 linux安裝 sudo apt update sudo apt install openssh-server1.2 windows安裝 windows安裝可以參考這篇文章 二. 使用方法 2.1 wifi下使用方法 直接查看想要連接的電腦的ip&#xff0c;其他的按照有線網絡設置好了ip之后進行連接就行。 2.2 有線網…

python的易物小店交換系統

前端開發框架:vue.js 數據庫 mysql 版本不限 后端語言框架支持&#xff1a; 1 java(SSM/springboot)-idea/eclipse 2.NodejsVue.js -vscode 3.python(flask/django)–pycharm/vscode 4.php(thinkphp/laravel)-hbuilderx 數據庫工具&#xff1a;Navicat/SQLyog等都可以 在需求分…

[硬件電路-119]:模擬電路 - 信號處理電路 - 比較器,模擬電路中的“決策者”,模擬信號到數字電平邏輯信號的轉化者...

前言&#xff1a;比較器的價值1、為何稱比較器為“決策者”&#xff1f;邏輯判斷的物理實現比較器通過硬件電路直接完成“大于/小于”的二元判斷&#xff0c;無需軟件干預。例如&#xff1a;在過壓保護電路中&#xff0c;比較器實時監測輸入電壓 Vin? 與參考電壓 Vref?&#…

【從零開始學習Redis】初識Redis

初識Redis 一句話理解Redis&#xff1a; Redis是一個基于內存的、支持多種數據結構的高性能鍵值數據庫&#xff0c;常被用于緩存、分布式鎖和消息隊列。和 MySQL 的區別&#xff1a;特點RedisMySQL類型非關系型&#xff08;NoSQL&#xff09;關系型&#xff08;SQL&#xff09;…

CUDA雜記--nvcc使用介紹

nvcc 是 NVIDIA CUDA 生態的核心編譯器&#xff0c;負責將 CUDA C/C 代碼&#xff08;混合了主機代碼和設備代碼&#xff09;編譯為可在 CPU 和 GPU 上運行的二進制文件。它不僅是一個簡單的編譯器&#xff0c;更是一個“編譯驅動程序”&#xff0c;協調多個工具鏈&#xff08;…

Codeforces Round 1040 (Div. 2)(補題)

文章目錄前言A.Submission is All You NeedB. PathlessC.Double PerspectiveD.Stay or Mirror前言 又被卡在第二題了&#xff0c;當時腦子跟犯糊涂似的&#xff0c;B題越理越亂&#xff0c;導致比賽結束&#xff0c;還在想著題&#xff0c;徹夜難眠&#xff01; A.Submission …

Apifox 7 月更新|通過 AI 命名參數及檢測接口規范、在線文檔支持自定義 CSS 和 JavaScript、鑒權能力升級

Apifox 新版本上線啦&#xff01; 看看本次版本更新主要涵蓋的重點內容&#xff0c;有沒有你所關注的功能特性&#xff1a; AI 助力接口設計 通過 AI 為參數命名 支持讓 AI 對接口進行規范性檢測 在線文檔功能增強 在線文檔支持自定義 CSS 和 JavaScript 目錄支持設置展示…

Node.js以及異步編程

什么是服務器&#xff1f;我們知道客戶端通過訪問服務器&#xff0c;然后服務器去操作數據庫把我們想要的數據拿過來給客戶端。比如服務器就是餐廳的服務員&#xff0c;數據庫就是廚房&#xff0c;客戶端就是我們的顧客。首先我們點菜&#xff0c;服務器告訴廚師做飯&#xff0…

UniApp 實現頂部固定導航欄 Tab 及滾動變色效果

頂部導航欄是一個非常常見的組件&#xff0c;尤其是固定在頂部的 Tab 導航&#xff0c;既能方便用戶快速切換內容&#xff0c;又能保持頁面結構的清晰。本文將詳細介紹如何在 UniApp Vue3 TypeScript 項目中實現一個固定在頂部、且能根據滾動狀態改變樣式的 Tab 導航欄。效果…

c++泛型編程

C泛型編程 1. 基本概念 1.1 泛型編程&#xff08;Generic Programming&#xff09; 泛型編程是C中一種重要的編程范式&#xff0c;它通過 參數化類型 來實現代碼的通用性和復用性。 1.2 模板&#xff08;Templates&#xff09; 模板 是泛型編程的基礎&#xff0c;允許編寫與數據…

Vue.js + Node.js 開發前后臺框架

在 Vue.js + Node.js 開發前后臺框架時,推薦采用現代化的技術棧組合和最佳實踐。以下是一個高效、可擴展的全棧框架方案: 技術棧推薦 層級 技術選型 說明 前端框架 Vue 3 (Composition API) 最新Vue核心庫,推薦使用<script setup>語法 UI組件庫 Element Plus / Ant D…

Vision Transformer (ViT) 詳解:當Transformer“看見”世界,計算機視覺的范式革命

摘要: 長久以來&#xff0c;卷積神經網絡&#xff08;CNN&#xff09;憑借其精心設計的歸納偏置&#xff08;inductive biases&#xff09;&#xff0c;無可爭議地統治著計算機視覺領域。然而&#xff0c;一篇名為《An Image is Worth 16x16 Words》的論文徹底改變了這一格局&a…

go goroutine chan 用法

方法1 代碼 package mainimport ("fmt""sync""time" )func main() {allChan : make(chan interface{}, 3)var sendWg, recvWg sync.WaitGroup // 分別同步發送和接收// 發送goroutinesendWg.Add(1)go func() {defer sendWg.Done()for i : 0; i &…

Web前端文件上傳安全與敏感數據安全處理

一、文件上傳安全1. 文件上傳時的核心安全檢查點文件上傳是 Web 應用的高風險功能&#xff0c;需從多維度驗證&#xff0c;防止惡意文件上傳&#xff08;如木馬、病毒&#xff09;或路徑攻擊&#xff0c;關鍵檢查點包括&#xff1a;MIME 類型驗證檢查請求頭中的 Content-Type&a…

文法中的間接左遞歸

&#x1f31f; 第一步&#xff1a;理解基本概念? 什么是文法&#xff08;Grammar&#xff09;&#xff1f;在編程語言或語法分析中&#xff0c;文法 是一組規則&#xff0c;用來描述一種語言的結構。例如&#xff1a;S → A a A → B b B → S c 這表示&#xff1a;S 可以…

Anthropic:跨越生產效能拐點的AI增長飛輪

資本競賽中的戰略轉折點 人工智能領域的競爭已經從理念之爭演變為資本、算力與地緣政治影響力的全面較量。Anthropic傳聞中的1700億美元估值&#xff0c;如果成為現實&#xff0c;將標志著前沿AI發展格局的地震式轉變。這不僅僅是構建更智能模型的問題&#xff0c;更是為主導下…

【Unity3D實例-功能-移動】小兵移動-通過鼠標點擊進行

在Unity的世界里&#xff0c;當你輕點鼠標&#xff0c;角色仿佛被賦予了新的使命&#xff0c;沿著一條無形的軌跡&#xff0c;向著地圖上的目標點進發。每一次移動&#xff0c;不僅是簡單的位移&#xff0c;更是對未知的探索。這種交互&#xff0c;讓玩家與游戲世界緊密相連&am…

從0到1學PHP(十四):PHP 性能優化:打造高效應用

目錄一、PHP 性能評估與分析1.1 性能指標體系1.2 性能分析工具使用1.3 性能瓶頸定位方法與流程二、代碼層面優化技巧2.1 高效的循環與條件判斷寫法2.2 函數與類的優化設計2.3 內存管理與垃圾回收機制優化三、緩存策略與實現3.1 數據緩存3.2 頁面緩存與部分緩存技術3.3 OPcache …

移動管家手機控車系統硬件安裝與軟件綁定設置

移動管家手機控車系統硬件安裝與軟件綁定配合使用&#xff0c;具體設置步驟如下&#xff1a;一、硬件安裝準備 ?加裝智能控制主機?&#xff1a;需在車輛上加裝移動管家專用智能控制模塊&#xff0c;該模塊需與原車電路系統連接&#xff0c;并將原車鑰匙芯片焊接至主控盒內以實…