最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue項目中解決數(shù)字精度丟失問題

 更新時間:2024年02月01日 08:27:43   作者:wangpq  
我們知道,浮點類型的數(shù)據(jù),在計算機中是以二進制的方式存儲的,但是表示的數(shù)據(jù)也有個上限和下限,當超過限制?,在計算機上顯示只能取最接近的限值,?數(shù)字解析精度丟失說的就是這個現(xiàn)象,所以本文給大家介紹了Vue項目中解決數(shù)字精度丟失問題的解決,需要的朋友可以參考下

項目背景

標準一碼游后端接口返回數(shù)據(jù)好些都包含用戶敏感信息(姓名、手機號、身份證號),基于保護用戶隱私數(shù)據(jù)等原因,產(chǎn)品經(jīng)理提出需求,要求對涉及到這些數(shù)據(jù)的后端接口進行加密處理。為了方便快速開發(fā),同時盡量以最小的改動代價實現(xiàn)其目標,經(jīng)過和后端商量,前后端不采取一個個字段加解密的方式(這種方式修改起來涉及到較多的頁面的字段處理,前后端工作量都較大,不利于代碼維護),而是對涉及到的接口,整體進行加密傳輸(新增、編輯等操作),解密展示(詳情查詢、列表展示等操作)。

什么是數(shù)字精度丟失

我們知道,浮點類型的數(shù)據(jù),在計算機中是以二進制的方式存儲的,但是表示的數(shù)據(jù)也有個上限和下限。當超過限制 ,在計算機上顯示只能取最接近的限值。 數(shù)字解析精度丟失說的就是這個現(xiàn)象, 簡單講就是數(shù)字超過了位數(shù)不夠表示了。誰讓后端返回給前端這樣的大數(shù)字數(shù)據(jù)呢。

解決方案

數(shù)字解析精度丟失的常用前端解決方案,目前網(wǎng)上常用的有 bignumber.js、json-bigint、lossless-json等,其中json-bigint、lossless-json無疑是其中的佼佼者,特別是解析一堆json數(shù)據(jù)用于展示的時候,兩者使用起來真的不要太香,使用時只需使用兩者的parse、stringify方法即可,跟原生的JSON.parse、JSON.stringify沒有任何區(qū)別,唯一需要注意的地方就是使用前部分特殊參數(shù)的配置罷了,還有就是node環(huán)境不同,導致json-bigint、lossless-json無法正常安裝,或者安裝成功,運行報錯的情形。

小小抱怨一下

我就在最先使用lossless-json的時候,遇到了坑,當時的node環(huán)境不管怎么安裝到項目中,總之就是報錯,還是那種直接指向安裝包,讓人無從下手的感覺。害得我都下載了數(shù)次依賴,無數(shù)遍node環(huán)境,搞到npm都無法運行了,還有nvm都崩了。最后一次重新安裝的node環(huán)境終于可以了,我的那個坑爹,還是原來的node版本啊,當時只要一使用,就報錯,現(xiàn)在不鬧了,OK了,我找誰說理去啊(真不知道當時哪個環(huán)節(jié)影響到了)。

同時,下載的lossless-json版本,后臺項目(vite搭建,vue版本2.7.14)最新版本4.0.1,都ok了,但是挪移到小程序項目(webpack搭建,vue版本2.6.11)中的時候,又出幺蛾子了,只要一使用lossless-json,就報錯指向到 lossless-json 源碼中,又經(jīng)過了多次嘗試,最后降級到2.0.1版本,才終于不再報錯了。也不確定lossless-json的各個版本,是否和vue版本,或者搭建項目的框架(webpack、vite)有關,或者和node版本有關,具體我也沒時間慢慢研究,去查他的文檔,畢竟我們只是為了快速解決問題,完成任務,又不是他的代碼開發(fā)者,要去糾結這些,你說是不是呢。

回歸正題

考慮到項目中需要使用此功能的地方很多,為了方便管理維護,我定義了一個全局對象$jsonbig,然后將json-bigint(或者lossless-json)的 parse、stringify方法封裝到此對象中,最后在需要使用的地方直接調(diào)用即可。

this.$jsonbig.parse("JSON字符串"); 
this.$jsonbig.stringify("JSON對象");

下面我將具體講一講在實際項目中是如何使用它們的吧。

一、使用json-bigint

查看json-bigint文檔可參考: gitee yarn

如何使用

1、先在js中定義公共方法:

const JsonBigint = require('json-bigint')({
	storeAsString: true
});
Object.defineProperty(Vue.prototype, '$jsonbig', {
	value: JsonBigint
})

2、具體使用

// 在使用admate.js的后臺框架中使用,新增、編輯、查看詳情、分頁列表等關鍵代碼片段:
setup: () = >useAdmateAdapter({
    urlPrefix: 'sot-admin-api/sys/company',
    axiosConfig: {
        r: row = >({
            method: 'GET',
            url: row.companyId
        }),
        d: {
            method: 'POST'
        },
        getList: {
            url: 'list'
        },
        u: {
            headers: {
                'Content-Type': 'application/json'
            }
        },
        c: {
            headers: {
                'Content-Type': 'application/json'
            }
        }
    },
    list: {
        filter: {
            keyword: null,
            areaCode: null,
            contactName: '',
            contactPhone: ''
        },
        dataAt: 'data.record'
    },
    form: {
        data: {
            __parentAreaCode: null,
            address: null,
            longitude: null,
            latitude: null
        }
    }
},
{
    afterGetList({ data }) {
        this.$set(this.list, 'data', this.$jsonbig.parse(this.$decrypt(data.record)))
    },
    afterOpenForm({ data }) {
        this.$set(this.form, 'data', this.$jsonbig.parse(this.$decrypt(data)))
    }
}),

/**
     * 獲取訂單詳情數(shù)據(jù)
     * @return Void
     */
queryForDetail() {
    this.$set(this.form__, "loading", true);
    this.$POST(`sot - admin - api / hotel / self - order / queryForDetail`, {
        id: this.form.data.orderId,
    }).then(({ data }) = >{
        this.$set(this.form__, "data", this.$jsonbig.parse(this.$decrypt(data)));
    }).finally((_) = >{
        this.$set(this.form__, "loading", false);
    });
},

解釋一下,decrypt為項目中解密用到的公共方法,使用this.decrypt(data)獲取到的是json數(shù)據(jù)字符串,就是它可能丟失了數(shù)據(jù)精度。使用全局方法 this.$jsonbig.parse將得到我們需要JSON數(shù)據(jù)對象,經(jīng)過parse轉換后,json數(shù)據(jù)中可能丟失精度的字段值(BigNumber類型)都將統(tǒng)一轉為字符串類型(不論后端原本返回的是字符串還是數(shù)值類型)。

注意:

我們標準一碼游后臺是用vite搭建的vue項目,在引入json-bigint的時候,我們使用到了require,如下

require('json-bigint')({ storeAsString: true })

如果您以為像在webpack搭建出來的項目那樣,直接require引入就可以了的話,那你真的是想得簡單了。

如果你你在實際項目中跑了代碼,你會發(fā)現(xiàn),項目運行時會在console里報錯,項目也跑不起來了,

init.js:143 Uncaught ReferenceError: require is not defined at init.js:143

其實歸根結底是vite搭建的vue項目不支持commonJS語法,所以要使用require還得額外安裝插件, 推薦使用 vite-plugin-require-transform

// 下載
npm i vite-plugin-require-transform --save-dev

// 使用
// 在vite.config.js中引入,并找到plugins,在里面添加requireTransform 配置參數(shù)
import requireTransform from 'vite-plugin-require-transform';
plugins: [
    // passing string type Regular expression
    requireTransform({
      fileRegex: /.js$|.vue$/ 
    }),
],

說到這里,有人也許會說,我們不用require,改為import引入不就可以了,

require('json-bigint')({ storeAsString: true })

重點來了,這里引用 json-bigint 的時候,后面的參數(shù) storeAsString 這個參數(shù)很重要,不可省略(后面接著講),如果沒有參數(shù)storeAsString,我想大家都知道如何改為import

import JsonBigint from 'json-bigint'

這真的不用我啰嗦解釋啥,可是如果帶上參數(shù)呢,該怎么設置默認參數(shù)storeAsString,我嘗試了好幾種寫法,都沒成功,又看了下文檔和百度,都沒見到,或許再去翻一下json-bigint的源代碼,也許能找到答案,可是誰叫我太懶了呢,有誰知道的,可以直接留言告訴我,多謝了啊。

回到剛才的話題,剛剛提到的參數(shù) { storeAsString: true } ,為何說必不可少呢?

這是因為如果沒有設置這個參數(shù)為true,返回給我們的數(shù)據(jù),超精度的那個字段值,將是一個BigNumber類型,如下面截圖的companyId字段,

這種值,如要要在項目中展示或使用,是會出錯的,官方文檔告訴我們可以使用toString()或者String()單獨對這些字段進行格式化,可這次需求涉及到的頁面較多,每個改動到的后端接口返回的字段同樣很多,誰知道哪個字段精度丟失了,又在什么地方使用了(畢竟我們不是從頭一點點開發(fā)項目,遇到不對,立馬修改,而是在原來正常運營的項目中修改),因此 storeAsString這個參數(shù)就非常有用了,它使我們不必一個個的對BigNumber類型的字段進行處理,直接放心大膽的按原有的邏輯使用即可。

當然官方英文文檔不建議我們使用,說這是一種危險的行為,

看吧,兩個地方都這樣說,搞得我當時使用的時候心驚膽戰(zhàn)的,其實這破英文的意思:

指定BigInts是否應該以字符串的形式存儲在對象中,而不是默認的BigNumber。

請注意,這是一種危險的行為,因為它破壞了在不更改數(shù)據(jù)類型的情況下來回轉換的默認功能(因為這將把所有bigint轉換為be-and-stay字符串)。

看了中文解釋,現(xiàn)在我們再使用storeAsString設置為true,是不是瞬間放心不少,破英文單詞 dangerous 在這里嚇人呢 ,有沒有同感啊。

二、使用lossless-json

查看lossless-json文檔可參考: yarn

lossless-json使用和剛介紹的json-bigint類似,同樣是在js中定義公共方法,使用時完全一致,唯一不同的地方在于定義公共方法時為了將BigNumber類型字段自動轉化為字符串,lossless-json沒有類似storeAsString的參數(shù),而是要定義一個函數(shù)reviver,然后作為參數(shù)重寫入parse方法,具體如下設置:

import { parse, stringify } from 'lossless-json'
// 對number值進行轉換,如果不用這個方法,Number類型就變成LosslessNumber
const bigDataReviver = (key, value) = >{
    if (value && value.isLosslessNumber) {
        if (Number.isSafeInteger(parseInt(value.value))) {
            return parseInt(value.value)
        }
        return value.value
    } else {
        return value
    }
}
Object.defineProperty(Vue.prototype, '$jsonbig', {
    value: {
        parse: (keyword, reviver = bigDataReviver) = >{
            return parse(keyword, reviver)
        },
        stringify
    }
})

值得一提的是,lossless-json無法像下面這樣使用

import LosslessJson from 'lossless-json'
// 中間部分省略不顯示
Object.defineProperty(Vue.prototype, '$jsonbig', {
    value: {
        parse: (keyword, reviver = bigDataReviver) = >{
            return LosslessJson.parse(keyword, reviver)
        },
        stringify: LosslessJson.stringify
    }
})

如果你跑了項目,你可能會發(fā)現(xiàn),項目無法正常跑起來,并且在瀏覽器控制臺console欄,發(fā)現(xiàn)Uncaught SyntaxError報錯,如下圖

按照這英文提示,結合我們引用時候直接從對象中取parse, stringify方法 ,我們不難理解其含義,lossless-json并沒有向我們提供一個默認接口對象,讓我們通過一個對象直接調(diào)用parse, stringify方法,而是只暴露了parse, stringify。

就像我從json-bigint源碼中找到的,

紅框框選的這部分,在lossless-json中并沒有,所以才出現(xiàn)了上面的報錯。

關于在下載lossless-json引入使用報錯的情況,我文中開始就已經(jīng)提到,我就不再贅述,或許你遇都遇不到。

即使你真的遇到了,可以嘗試重裝,或者使用nvm切換node環(huán)境,再或者降級下載的版本,看能不能下載后使用吧,具體什么原因?qū)е碌?,我是沒有興趣慢慢嘗試和研究的,如果你有興趣,可以去查找資料或者問lossless-json的作者,我就不再這里繼續(xù)啰嗦了啊。

最后

以上就是Vue項目中解決數(shù)字精度丟失問題的詳細內(nèi)容,更多關于Vue數(shù)字精度丟失的資料請關注腳本之家其它相關文章!

相關文章

  • 詳解vue父子組件間傳值(props)

    詳解vue父子組件間傳值(props)

    本篇文章主要介紹了詳解vue父子組件間傳值(props),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • uniapp嵌套webview無法返回上一級解決方式

    uniapp嵌套webview無法返回上一級解決方式

    uniapp是一款非常強大的跨平臺開發(fā)框架,它可以讓我們只編寫一份代碼,就能在多個平臺上運行,這篇文章主要給大家介紹了關于uniapp嵌套webview無法返回上一級的解決方式,需要的朋友可以參考下
    2024-05-05
  • Vue3請求攔截器里如何配置token

    Vue3請求攔截器里如何配置token

    這篇文章主要介紹了Vue3請求攔截器里如何配置token,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • vue項目安裝使用vconsole方式

    vue項目安裝使用vconsole方式

    這篇文章主要介紹了vue項目安裝使用vconsole方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Vue axios的使用和全局baseURL配置方式

    Vue axios的使用和全局baseURL配置方式

    作為一個全棧開發(fā)人員,前端UI框架和網(wǎng)絡請求都得有基本的掌握,我以最簡潔易懂的方式講解axios的使用和全局baseURL的配置
    2024-05-05
  • 腳手架vue-cli工程webpack的基本用法詳解

    腳手架vue-cli工程webpack的基本用法詳解

    這篇文章主要介紹了vue-cli工程webpack的基本用法,非常不錯,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2018-09-09
  • vue中數(shù)據(jù)狀態(tài)輪詢過程

    vue中數(shù)據(jù)狀態(tài)輪詢過程

    文章講述了在Vue中實現(xiàn)數(shù)據(jù)狀態(tài)輪詢的兩種方法,首先,介紹如何在頁面掛載后請求數(shù)據(jù),并根據(jù)數(shù)據(jù)狀態(tài)決定是否輪詢,在data中定義定時器,并在組件銷毀前清空定時器以防止內(nèi)存泄漏,如果無單獨的狀態(tài)接口,則將狀態(tài)方法替換為數(shù)據(jù)方法
    2025-11-11
  • vue使用h函數(shù)封裝dialog組件(以命令的形式使用dialog組件)

    vue使用h函數(shù)封裝dialog組件(以命令的形式使用dialog組件)

    文章介紹了如何將彈窗封裝成命令式形式,并解決了彈窗中的表單不能正常展示的問題,通過重新創(chuàng)建一個新的Vue應用實例并注冊所需的組件,解決了無法解析組件的警告,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • Vue.js中用webpack合并打包多個組件并實現(xiàn)按需加載

    Vue.js中用webpack合并打包多個組件并實現(xiàn)按需加載

    對于現(xiàn)在前端插件的頻繁更新,我也是無力吐槽,但是既然入了前端的坑就得認嘛,所以多多少少要對組件化有點了解,下面這篇文章主要給大家介紹了在Vue.js中用webpack合并打包多個組件并實現(xiàn)按需加載的相關資料,需要的朋友可以參考下。
    2017-02-02
  • vue和react中關于插槽詳解

    vue和react中關于插槽詳解

    這篇文章主要介紹了vue和react中關于插槽詳解,slot插槽是Vue對組件嵌套這種擴展機制的稱謂,在react可以也這樣稱呼,但是并不很常見。不過叫slot確實很形象
    2022-08-08

最新評論

富锦市| 长垣县| 正安县| 鸡泽县| 东光县| 闽侯县| 留坝县| 新野县| 宁海县| 安塞县| 合山市| 浙江省| 祁阳县| 繁峙县| 龙江县| 正阳县| 青川县| 克山县| 卢龙县| 麻阳| 阿坝县| 黑山县| 长丰县| 祥云县| 凯里市| 鹤山市| 合作市| 永昌县| 拜城县| 叶城县| 永福县| 迭部县| 博白县| 太谷县| 都匀市| 阿荣旗| 广水市| 宁安市| 岳池县| 左权县| 长岭县|