写到第5篇了,解决了很多问题,还有一些需要调整
1 el-input-number指令兼容性调整
下面这个可编辑的表格,全是0,于是需要一个指令,让它自己实现如果是0,就置空;如果是数字就是格式化为千分位;如果焦点放上去,变成数字。焦点失去有变成格式化。
在vue2中这么写,但在vue3中vnode.elm.querySelector
,这种写法是不行的,因为你不应该直接操作dom,el 参数实际上指向的是 el-input-number 的根 DOM 元素,而不是内部的 input 元素。由于 el-input-number 是组件,不是原生的 input 元素,直接监听其内部 input 事件可能不太方便。
let options = {precision: 2,thousands: ','
}
const money = (el, binding, vnode) => {// // 判断是否是input元素if (vnode) {el = vnode.elm.querySelector('input')} else {throw new Error('v-money-format requires 1 input')}const opt = Object.assign({}, options, binding.value ? binding.value : {})const regStr = '/^$*+?.|'const inRegStr = regStr.includes(opt.thousands) ? (`\\${opt.thousands}`) : opt.thousandsconst thousandsReg = new RegExp(inRegStr, 'g')if (!el.isFocus) { //设置初始值 input框为0 去除显示if (el.value == 0) {el.value = '';}else if(el.value != '' || el.value != 0){ //初始化千分位el.value = el.value.replace(thousandsReg, '').cut();}}el.onfocus = function () {el.isFocus = trueel.value = el.value.replace(thousandsReg, '')}el.onblur = function () {el.isFocus = falseif (el.value != '') {el.value = el.value.cut();}if (el.value == 0) {el.value = '';}// el.value = moneyFormat(el.value, opt.precision, opt.thousands)}el.oninput = function () {el.value = el.value.replace(/[^\d.-]/g, '')}
}export default money
把这个代码放到文心一言,改成vue3的模式,无效,只能自己想办法。调整为vue3
的模式
/*** 金额格式化指令*/
import $tool from '@/utils/tool' const options = { precision: 2, thousands: ','
} const money = { mounted(el, binding,vnode) { let input;if (vnode){input = el.querySelector('input');} else{throw new Error('v-money-format requires 1 input');}const opt = Object.assign({}, options, binding.value || {}) const regStr = '/^$*+?.|' const inRegStr = regStr.includes(opt.thousands) ? (`\\${opt.thousands}`) : opt.thousands const thousandsReg = new RegExp(inRegStr, 'g') // 初始化输入框if (!input.isFocus && input.value) {if (input.value === '0') {input.value = '';} else if (input.value !== '' || input.value !== '0') {let fmt = $tool.cut(input.value.replace(thousandsReg, ''));input.value = fmtconsole.log(input.value);}} else {input.value = null;}// 监听事件input.addEventListener('focus', () => {input.isFocus = true;input.value = input.value.replace(thousandsReg, '');});input.addEventListener('blur', () => {input.isFocus = false;if (input.value !== '') {input.value = $tool.cut(input.value);}if (input.value === '0') {input.value = '';}});input.addEventListener('input', () => {if (input.value) {input.value = input.value.replace(/[^\d.-]/g, '');} else {input.value = '0';}});},
} export default money;
运行提示moneyFormat.ts:31 The specified value "3,333" cannot be parsed, or is out of range,
vue2是没有这个问题的,分析原因,在vue2中el-input-number
类型依旧是text
但是在element-plus
中变成了number
,改成el-inpu
,结果发现blur
事件后input.value
被置空了。搞了快一天了,项目进度要紧,这种方案放弃了。
如果不用指令,采用formatter
和parser
会怎么样呢?
调试你会发现,如果是在表格中,你没改一下,整个数字样式都不会重新格式化一遍。虽然这样,但是可用。
2 v-model中默认属性的问题
在vue2中当你的组件采用v-model绑定值,例如
进入到组件中,通过this.value
赋值,这个在vue3中是不行的,需要改成modelValue
,否则undefined
错误
还需要定义出来。
3 keep-alive有些页面缓存了,有些没有缓存
在setup
模式下,给页面定义一个名称,就可以被缓存。
defineOptions({name: "采购入库单"
})
但是在本次vue2升级到vue3的过程中,发现有些页面增加后,缓存了,有些没有被缓存了。经过调试发现
上面的name
中的内容,要跟页签的名称一致,否则不会缓存。也就是说,这个name
必须设置为凭证字
才可以。这么推理keepalive应该是map结构。
即你必须要改成与页签同名,因为这个页面名在项目中是Component
的名称