后端重构,如果接口做好抽象封装,只需要考虑jar之间的兼容性问题,jdk版本不变,基本不用做太大的调整,但是前端就不一样,除了vue框架本身,css的调整,改起来更是让人头疼。前面写了vue2项目升级到vue3经历分享1,vue2项目升级到vue3经历分享2,vue2项目升级到vue3经历分享3,因为没有改造完,于是又写了一篇。还有7天时间,希望能顺利推进。
1 el-table-column外层不能加span
很奇怪,为什么只有两列,其他的不见。
检查代码,第一个不规范的地方,为何el-table-column
外层多了一个<span>
,这个再新框架里面直接就显示不了,更为严谨。
去掉之后,列出来了,说明一个问题el-table-column
再el-table
中很重要,列存在才可以显示。
element-ui
中这么写可以,但是element-plus
中,这种外面加<span>
就不规范了。
一般情况下vue2使用Element UI这个组件库,表格组件的插槽的话一般都是使用v-slot,而vue3使用Element Plus组件库,表格组件中插槽一般为#default,不过不改,也能运行。调整后,问题解决。
2 $event.target使用问题
下面的代码,运行后提示 TypeError: Cannot read properties of undefined (reading 'target')
<el-table-column prop="remark" label="备注" show-overflow-tooltip min-width="120"><template #default="scope"><span v-show="!scope.row.isEditCell" style="cursor:pointer">{{scope.row.remark}}</span><el-input v-show="scope.row.isEditCell" v-model="scope.row.remark" @blur="cellBlur(scope.row,scope.column)" @focus="cellFocus(scope.row)" :ref="'remark'+scope.row.id" @keyup.enter.native="$event.target.blur"></el-input></template></el-table-column>
根据文心一言的指导,调整后代码如下,如此界面可以出来了。
<el-table-column prop="remark" label="备注" show-overflow-tooltip min-width="120"><template #default="scope"><span v-show="!scope.row.isEditCell" style="cursor:pointer">{{scope.row.remark}}</span><el-input v-show="scope.row.isEditCell" v-model="scope.row.remark" @blur="cellBlur(scope.row,scope.column)" @focus="cellFocus(scope.row)" :ref="el => { if (el) scope.remarkInput = el; }" @keyup.enter.native="finishEdit(scope.row)"></el-input></template></el-table-column>
finishEdit(row){row.isEditCell = false;},
3 this.$set is not a function
触发cellClick
,这里提示this.$set
不是跟函数,vue3为什么舍弃了this.$set
由于 Vue 3 使用 Proxy 使其数据属性自动成为响应式的,所以可以直接修改对象属性,而无需使用 $set。直接赋值即可。
3 TypeError: Cannot read properties of undefined (reading ‘querySelector’)
下面可以看到项目中前端工程师设计了一个select组件,里面直接操作了dom
,这个却是很忌讳,为啥,看看现在的我就知道了,升级改造,非常麻烦,因为el-select
随便一改造,项目肯定需要花费成本去修复这个问题。然成本从而而来?除非是想防御式编程。但问题是高级工程师随着年龄增长,边界效应递减,低级工程师跳槽涨工资,剩下就是丢给高级工程师的烂摊子,最终承受这些憋屈的就是这些高级工程师。这个也是为什么有些公司招所谓架构师或者技术经理,实际就是去救火的原因。
看之前工程运行的效果,实际就是一个默认全选的select,然后封装了一个控件,何必这么麻烦呢。
基于element-plus
原生控件改造,很难,待我写一个
element-plus
升级到2.4.3
,提示下面的错误
1:26:55 [vite] Internal server error: No known conditions for "./lib/locale/lang/zh-cn" entry in "element-plus" package 11:26:55 Plugin: vite:import-analysisFile: E:/workspace/vuework/acc3/src/App.vue
路径修正为import zhCn from 'element-plus/es/locale/lang/zh-cn'
,问题处理。之所以升级element-plus
,是因为el-select
中2.3.0
中有max-collapse-tags
,这个也就是之前为什么有工程师会写自定义select组件的原因,而2.4.0
可以加水印,2.4.3
可以在select
上下方便的加东西,这个版本差不多就够了
<template><el-selectv-model="inputValue"multipleclearablecollapse-tags:max-collapse-tags="2"style="width: 100%"><template #header><el-checkboxv-model="checkAll":indeterminate="indeterminate"@change="handleCheckAll">全选</el-checkbox></template><el-optionv-for="(item,index) in options":key="index":label="item.name":value="item.id"/></el-select>
</template>
<script lang="ts" setup>
import { ref, watch, getCurrentInstance } from "vue";
import type { CheckboxValueType } from 'element-plus'
const { proxy }: any = getCurrentInstance();
defineOptions({name: "multiSelect"
})
// 属性
const emits = defineEmits(['update:modelValue'])
const props = defineProps({modelValue:{type:String,},options:{type:Array,default:()=>[]},defaultProps:{type:Object,default:()=> ({label:'name',value:'id'})}
})
// 参数
const checkAll = ref(false)
const indeterminate = ref(false)
const inputValue = ref<CheckboxValueType[]>([])
// 方法
const handleCheckAll = (val) => {indeterminate.value = falsedebuggerif (val) {inputValue.value = props.options.map((_) => _.id)} else {inputValue.value = []}
}
watch(()=>inputValue,(val)=>{// 处理自动勾选debuggerif (val.value.length === 0){checkAll.value = false indeterminate.value = false } else if (val.value.length === props.options.length) {checkAll.value = true indeterminate.value = false } else{indeterminate.value = true} // 处理表单提交if (!proxy.$_.isEmpty(val)){emits('update:modelValue',val.value.join(','))} else{emits('update:modelValue','')}
},{immediate:true,deep:true})</script>
<style>
</style>
控件使用如下,如此简约易懂
<multi-select :options="expenseList" v-model="form.incomeExpenseIdList" :teleported="false" placeholder="支持多选收支类别"></multi-select>
效果如下:
4 表单查询数据错乱的问题
这个问题更加隐蔽,甚至有些莫名奇妙,this.form
跟当前页面的完全不是一个,怎么会传过来的呢?
查询关键字,可以搜索到这一款来自另外一个页面,那么为什么不是同一个页面会出现form
错乱的问题呢?
应该是出现在多个组件使用了,同一个name,当在递归组件的问题会产生混淆的问题。
5 表头th标签不见了
为什么会出现下面的问题
查看代码,还是挺有想象力的
但显示出来却少了东西
正常情况应该是下面的
处理方案居然是,将th
标签调整一下排版,问题解决,如此问题应该出在vite
编译器
待补充。。。