1、背景
在开发公司项目时,需要控制用户输入格式,把用户输入的值转换成其他国家的数字分隔形式,并在离焦后进行小数位数的控制,不足的需要补0,vue-currency-input就是一款能够很好实现这些需求的插件。
然而在实际使用中还是不太顺利,此篇文章就用来记录安装使用过程中所遇到的问题以及我的解决方式。作为参考,我的项目所使用的vue版本为:2.6.11,vue-currency-input插件版本为1.x。
2、vue-currency-input 1.x官方文档
3、问题及解决
3.1、在vue2.7之前的版本中,使用vue-currency-input 2.x报错
在最新版本的插件官方文档中有介绍,如果项目所使用的vue版本低于2.7,则应该使用vue-currency-input 2.x。于是我将使用文档的版本切换成2.x的,并按照文档说明安装了vue-currency-input@2.x及Vue Composition API 插件,并在项目中封装成组件使用,代码如下:
<template>
<el-input
ref="inputRef"
v-model="formattedValue"
:placeholder="placeholder"
:disabled="disabled"
/>
</template>
<script>
import { watch } from 'vue'
import { useCurrencyInput } from 'vue-currency-input'
export default {
name: 'DivPrecisionInput',
props: {
value: {
type: [Number, String],
default: undefined
},
options: {
type: Object,
default() {
return {}
}
},
placeholder: {
type: String,
default: undefined
},
disabled: Boolean
},
emits: ['moneyInput'],
setup(props, { emit }) {
const options = {
locale: 'pt',
currency: 'BRL',
currencyDisplay: 'hidden',
precision: 2,
...props.options
}
const { inputRef, formattedValue, setValue, numberValue } = useCurrencyInput(options)
watch(() => props.value, (value) => {
if (options.valueRange) { // 限制可输入数值范围
const maxValue = options.valueRange.max
const minValue = options.valueRange.min
if (value !== null && value > maxValue) {
setValue(maxValue)
emit('moneyInput', maxValue)
} else if (value !== null && value < minValue) {
setValue(minValue)
emit('moneyInput', minValue)
} else {
setValue(value)
emit('moneyInput', numberValue.value)
}
} else {
setValue(value)
emit('moneyInput', numberValue.value)
}
})
return {
inputRef,
formattedValue
}
}
}
</script>
<style lang="scss" scoped>
</style>
依赖如下:
运行后却出现如下错误:
似乎是引入的组合式API不生效?具体的原因我也不太清楚,但是插件1.x版本是基于vue2的,1.x文档中举例出来的用法也都是基于vue2,于是就只能将插件版本降低至1.x,果然就不报错了。
3.2、pnpm环境下patch的使用
vue-currency-input对于国内开发不友好的一点就是,没有适配全角下的小数点(其实就是中文的句号)。虽然严谨的来说,输入数字本来就应该是英文环境下的小数点,但由于公司的开发、测试团队都在国内,为了交互友好,需要在插件源码中加入中文小数点,那么就到了patch这个工具的领域了。
如果项目使用的是npm,可以参考这篇博文:http://t.csdnimg.cn/Fr6mh,讲得非常详细,还有一些可能遇到的问题及处理方案。本文主要来说pnpm环境下如何魔改,相较于npm环境下,变化还是很大的。
1、通过运行 pnpm patch 插件名@版本号 命令,将包提取到临时目录
插件名就是node_modules目录中这个插件的名字
执行命令:
pnpm patch vue-currency-input@1.22.6 --edit-dir '空文件目录'
--edit-dir 用来指定包代码存放的临时目录地址,不指定的话就是在系统环境变量temp所指定的目录下生成随机名称文件夹。注意!路径名中不要出现中文,中文在第二步中可能会显示为乱码,导致临时目录地址找不到。
执行完成后,控制台会出现如下信息,证明我们第一步成功了,接下来可以进行第二步了
2、在临时目录下修改代码,并通过 pnpm patch-commit '临时目录地址' 来生成补丁文件
执行命令:
pnpm patch-commit 'D:\temp\temp_20240717'
执行成功后,会在项目根目录中生成一个patches的文件夹,里面记录着我们的修改内容。建议插件dist中打包好的代码和源码都修改下,如果只修改源码,要再运行下插件的打包命令才能生效。
3、重启项目,验证补丁是否生效
可能会遇到的问题
如果你是windows环境,且环境变量temp所指定的位置与patch指定的临时目录位置在不同的盘,可能会出现如下错误:
EXDEV EXDEV: cross-device link not permitted, link 'D:\temp\temp_20240717' -> 'C:\Users\xx~1\AppData\Local\Temp\99a65b35aafe6e4ce0b0c4d54edc96ce\Binary_Property\ASCII.js'(此处是环境变量temp的位置)
出现这个错误,已经有人在github上提问了,pnpm的作者给出的答案是:如果临时文件目录与环境变量temp不在同一驱动器上,则无法在Windows上运行。所以只能将环境变量temp的路径设置为我们指定的临时目录所在的盘的某个位置,或者指定临时目录要与环境变量temp在同一个盘。