金恒开发注意事项

142 阅读15分钟

5db9a75f70c70233ad10db85a5ba492.png

项目安装启动

设置私服镜像

npm config set registry http://172.18.248.130

安装插件

npm install --force or --legacy-peer-deps

aysnc await promise

async 关键字用于声明一个异步函数。在异步函数中,可以使用 await 关键字来等待一个 Promise 对象的结果。

异步函数总是返回一个 Promise 。如果函数体没有显式返回任何值,它会隐式返回一个已解决(resolved)的 Promise ;如果函数体中有 return 语句,则返回的值会被包裹在一个已解决的 Promise 中;如果在函数体内抛出错误,则返回一个拒绝(rejected)的 Promise 。

 await必须结合async一起使用,右边的Promise对象必须处于reslove状态,后续代码才能正常执行。 async await相当于Promise.resolve('XX').then(res => {这里执行的是await后面的代码})

解决ts报错 'this' implicitly has type 'any' because it does not have a type annotation

"noImplicitThis": false

flex

flex属性介绍

  • flex属性其实是一种简写,是flex-grow,flex-shrink和flex-basis的缩写形式。
  • 默认值为0 1 auto。前两个属性可选。

flex-grow

flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大

flex-shrink

flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小

flex-basis

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。 它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间

image.png

解决设置flex: 1的情况下再设置width不生效

flex: 0 0 width; // 元素不放大不缩小 占据的空间为width对应的数值大小

能源一体化

监听粘贴操作,获取剪贴板中图片base64数据

JS获取粘贴板中的图片进行展示和上传

文件上传

  1. 如果调用通用的文件上传接口/store/attach/upload,不能传文件的二进制流,这样接口会无法识别文件扩展名,报5000。需转为file格式上传,且入参需是表单形式。

1729125723650.png

1729125801439.png

后续

通过监听paste事件,可直接获取图片的blob,再通过const file = new File([blob], fileName, { type: fileType })将blob转为file。之前是blob转base64再转file,多走一步。

//绑定粘贴事件 Ctrl+V
bindPaste();
//绑定粘贴事件
function bindPaste(){
	//定义变量存储获取的图片内容
	var blob;
	//获取body对象
	var body = document.getElementsByTagName("body");
	//定义body标签绑定的粘贴事件处理函数
	var fun=function(e){
		//获取clipboardData对象
		var data=e.clipboardData||window.clipboardData;
		//获取图片内容
		blob=data.items[0].getAsFile();
		const file = new File([blob], fileName, { type: fileType }); // 将blob转为file
	}
	//通过body标签绑定粘贴事件,注意有些标签绑定粘贴事件可能出错
	body[0].removeEventListener('paste',fun);
	body[0].addEventListener('paste',fun);
}

页面优化 老界面截图 便于数据验证

IT人员修改位置

ac93d92535abddb521f7ea57d164fac.jpg

智慧中心7楼中大屏适配

智慧中心7楼中大屏分辨率为14560*3402,能源一体化首页是按照1920*1080的分辨率进行设计以及开发的,如果不做任何配置,在大屏上展示的效果如下

dbc6c5da70b56e585e4cca1e7de7738.jpg 为了进行适配,进行一下调整:

  1. 根节点html fontSize根据屏幕宽进行计算。在调试的过程中发现,根节点html fontSize在屏幕大于3840时被限制为40px,找到相关代码

微信图片_20241018150359.png 进行相应调整 1729235169078.png 1729235208798.png

注意:在屏幕宽度大于3000时,不仅需要根据屏幕宽度计算fontSize,还需要考虑屏幕的宽高比,用屏幕高宽比除以1080/1920得到scaleY,再用baseSize * scaleX * scaleY计算出fontSize。之所以要乘以scaleY,是因为大屏的横向拉伸幅度较大,就是过宽过矮,不是按照1920*1080等比例拉伸的;

  1. 在进行大屏开发的时候,字体大小变量推荐使用px,而不是vw,图片大小设置也用px,之前使用vw进行开发,导致字体以及图片在大屏上异常大,原因在于大屏宽度过高; 1729236064318.png

  2. 关于echarts图表的大屏适配,X轴、Y轴的字体大小不能写死,需要根据屏幕根节点fontSize进行计算,同理折线图的线宽也不能写死;

1729236312211.png

1729236373789.png

解决根据表格数据动态修改表格高度时报错(2024-10-24)

能源一体化项目的页面现在都改为一屏展示,所以页面中的表格在数据比较多的时候需要结合其他区块的高度计算出页面剩余高度赋予表格,然而当数据比较少时,表格的高度就是表格数据全部展示时的高度。
在开发工序精管发电能源计划页面时,如果没有给表格高度变量tableHeight赋初始值,会报错:Uncaught (in promise)TypeError:Cannot read properties of null(reading style')at TableLayout.setHeight(table-layout.ts:74:10)23539c95b49b781f77a1a3949bd799b.png

所以切记表格高度变量tableHeight必须要有初始,不能为空字符串。 image.png

props type为多个类型时,需用||进行分割,而不是|

相关报错如下: 80f23474ab34197f655545eec31503b.png

正确语法: 1729766528265.png

echarts 如何设置 legend 展示为虚线或者实线

如果通过itemStyle: {opacity: 0}设置虚线,会导致虚线的高度无法调整,在大屏上只是一根细线。 1729860701198.png

可通过icon:'path://' + svg path,采用svg图片生成legend,进行解决。注意path://不能忘记拼接,不然不会生效。
echarts 如何设置 legend 展示为虚线或者实线

image.png

element plus组件Image图片使用注意事项

使用Image加载assets目录下的图片,直接传入相对地址,会报404

25611ba14ab6b8eebf6e654e5927972.png

597a76aaf5ede8172ee4dacee2458e6.png

解决方法有两种:

  1. 将图片放在public文件夹下
  2. 使用import引入assets下的图片 1730164664340.png

首页工序能耗点击标题右侧箭头 如何跳转至对应工序首页时 左侧菜单也切换至工序精管菜单

1730775386156.png

实现步骤:

  1. 点击箭头进行页面跳转时,先跳转至工序精管整个模块的首页(AppMain.vue),在跳转的路径后面拼接实际要跳转的页面地址(childPath) 1730775620113.png
  2. 在AppMain.vue页面获取页面地址,如果地址后面拼接了childPath,则再进行一次页面跳转。 1730775874187.png

解决报错:TypeError:Cannot read properties of undefined (reading'产量')

1731043960231.png 报错的原因是使用el-tab来进行模块切换,在页面加载时,三个子模块的相应dom也会进行加载,如果html元素包裹的数据是通过对象匹配key进行获取的,且对象为空,或对象匹配不上key,会报上面的错误,导致包含此类数据的dom都无法加载。

1731045843616.png

html元素包裹的数据是通过对象匹配key进行获取

解决方法是在数据匹配时使用?.链判断运算,它允许开发人员读取深度嵌套在对象链中的属性值,而无需验证每个引用,当引用为空时,表达式停止计算并返回 undefined

1731046210172.png

解决el-tab切换时 图表无法计算宽高 导致图表展示大小和位置不合适

1731046643936.png

解决方法:
不要通过%来设置表格的宽高,需通过px/rem/vw/wh来明确指定表格宽高

1731046777319.png

组件defineExpose响应式对象上的一个属性,怎么保持相应响应性?

1731048650932.png 通过toRef()基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同步。

proxy.$refs

proxy.$refs访问组件或者元素,可用于遍历时访问组件并调用其expose出来的方法。从而避免为创建多个ref对象 导致代码冗余。
不推荐 1731049347394.png

1731049398967.png

推荐 1731049486878.png

name + alias ?? label

+的优先级高于??,上式等同于(name + alias) ?? label,如果先要执行??,则需给??运算加括号name + (alias ?? label)

parseInt取整不会进行四舍五入,对接口数据取整应使用Math.round

element plus 表头换行

之前是通过div分割来实现换行,现在可通过换行符\n结合css样式white-space: pre-line来实现

1731637934839.png

之前实现方式

1731638010460.png

1731638052433.png

现在实现方式

参考:[ ]()

通过max-height设置表格最大高度

这个高度应该是页面一屏展示的情况下,整个屏幕高度减去除了表格以外其他区域的高度得到到的数值,从而在表格高度超过max-height时,显示滚动条,不超过则不显示。
这样比之前根据接口返回数据条数乘以行高再加上表头高度来获取整个表格高度,并判断表格不加滚动条完全展示的情况下,页面能不能一屏展示,如果不能一屏展示,则需要将页面高度减去其他区域高度而获得的剩余高度,设置为表格高度要方便的多。

左侧菜单收起与展开 echarts自适应

实现代码: 1732585625670.png

1732585676599.png 注意点: 包裹echarts的父元素必须明确指定宽高,宽度不可用flex: 1来代替,不然会导致包裹echarts的父元素宽度计算不正确,从而resize失败

1732586118557.png

1732586242108.png

热风炉换烧模型 排班与统计 表格滚动至箭头所在行

image.png

可通过scrollTo/scrollTop来实现

滚动容器

  • overflow: auto:只有在内容溢出的情况下才会显示滚动条,这是最常用的选项。
  • overflow: scroll:即使内容未溢出,也会始终显示滚动条。

scrollTo

用于将滚动容器的元素滚动到 指定的坐标位置

// 使用 scrollTo 
function useScrollTo() { 
    const container = document.getElementById('scroll-container'); // 滚动到绝对位置 使用对象参数进行平滑滚动 
    container.scrollTo({ top: 200, left: 0, behavior: 'smooth' }); 
}

scrollTop & scrollLeft

表示滚动容器当前已经滚动的水平或垂直距离。可以用来获取或设置滚动容器的滚动位置

1733359582878.png

参考:浏览器滚动能力完全解析:scroll, scrollTo, scrollBy, scrollIntoView

首页消息代办点击跳转至对应页面打开详情弹窗

该功能分三步来完成:

  1. 先跳转至sems.nisco.cn/index?path=xxxx 确保左侧菜单切换
  2. 再跳转至子页面 例如sems.nisco.cn/licenseApprove/addForm
  3. 在子页面根据id打开消息详情弹窗

之前使用window.location.href来进行页面跳转,相比于Vue Router,window.location.href会重新加载页面,导致页面加载时间长,在上面的1、2两步之间过度时间长 页面很长时间右侧处于空白状态。为了优化用户体验,采用Vue Router来实现1、2两步。具体步骤如下:

  1. 先在src/views/portal/components/PortalHeader/PortalHeader.vue文件中监听消息点击事件,根据消息id调接口获取1、2两步跳转的路由地址,并通过query(params无法携带参数,切记)在跳转时携带childPath以及businessId两个参数。通过pinia存储一级菜单path 用于左侧菜单匹配。

1733465429426.png

关于左侧菜单匹配,跳转至sems.nisco.cn/index?path=xxxx 会在src/layout/components/SidebarUtils/src/layout/components/SidebarUtils.ts文件中根据pinia存储的一级菜单path来进行子系统菜单以及子系统名称匹配。

1733464585721.png

  1. 跳转至sems.nisco.cn/index?path=xxxx 页面后 在src/layout/components/AppMain.vue文件中会获取路由参数,完成第二步的子页面跳转

1733464953932.png

  1. 最后在子页面中通过在hooks中定义的useOpenDetail打开详情弹窗

1733465877425.png

注意点

  1. Vue router无法通过params携带参数,需使用query
  2. 在src/layout/components/AppMain.vue文件中进行子页面跳转时 需加个延时器 延时建议为1000ms 不然子页面可能不能正常打开
  3. 从首页消息队列打开详情页面 再点击菜单popover进行一级菜单切换 需设置sideMenuPath为'',不然左侧菜单不刷新。相关代码在src/layout/components/Sidebar/index.vue文件中

1733466338616.png

解决npm run build报NODE OPTIONS不是内部或外部命令,也不是可运行的程序或批处理文件

为了解决npm run build打包内存溢出报错 image.png

在package.json->scripts/build添加NODE OPTIONS=--max old space size=8192 1733881968891.png

cmd运行npm run build 报'NODE OPTIONS'不是内部或外部命令,也不是可运行的程序或批处理文件 v2-1fd3dec0d71e1345ac89012636b64156_r.jpg 解决方法:
运行 npm install -g win-node-env
然后再运行npm run build就可以成功打包了!

参考:
Vue编译报错内存溢出问题解决方式
'NODE_OPTIONS' 不是内部或外部命令,也不是可运行的程序

解决echarts引用了markPoint或者markLine没有效果

import 'echarts/lib/component/markPoint'
import 'echarts/lib/component/markLine'

参考: echarts引用了markPoint或者markLine没有效果

IOT数据相加

系统管理/公共配置/业务字典 点击新增

1735260767862.png

image.png

  1. strKey参考已有数据进行填充,
  2. value1为需要相加的数据的strValue以英文分号(;)分割
  3. value2为数据名称,参考上方的strValue2
  4. 不同strValue3的数据无法相加,因为来自不同的IOT设备。

v-for遍历对象

1735881848822.png

表格滚动条滚动时加粗 便于操作

通过伪类active,在滚动条滚动时设置纵向/横向滚动条高度/宽度,实现滚动时加粗。 1736153654678.png

使用ref定义的数组通过forEach方法修改数值 会失去响应性

在Vue 3中,使用ref定义响应式数据时,如果直接使用forEach遍历数组并对其进行操作,可能会导致数组内的元素不再具有响应式特性,即失去“响应性”。这是因为forEach不会创建新的作用域,因此在其内部进行的任何赋值操作都不会被Vue的响应式系统跟踪。

解决方法:直接给数组重新赋值,下面图片中的三个方法未必有效。

1736911369145.png

image.png

1736832431441.png

报表修改settMonth

1741048421536.png

解决节能技术/项目资料管理/项目资料信息 资料汇总弹窗查看的附件与关联项目不对应

原因是每个文件类型都有一个对应的el-dialog,里面包含文件上传组件。如果el-dialog未设置destory-on-close,会导致弹窗关闭后,文件上传组件依然存在。进而导致proxy.$refs.fileUploader.init(row.id)获取的文件上传组件不是当前打开的弹窗内的文件上传组件,而是第一个打开的弹窗内的文件上传组件。从而导致弹窗中展示数据变化了,但是附件没有变化。
解决方法: 1、共用一个弹窗,进而共用一个文件上传组件;(推荐,这样可以减少冗余代码) 2、给每个弹窗设置destory-on-close。(项目中使用的是这个方案,因为按照1来调整的话,改动量过大)

1743664137996.png

钢轧集控(二期)

keepAlive页面切换至其他页面如何清除定时器

通过onActivated在页面展示时设置定时器,onDeactivated页面隐藏时清除定时器。

1736831780540.png

解决数据更新时echarts需要重复加载

在调用setOption更新数据时,如果传入的notMerge属性,则将其设置为false

image.png

解决代码发布报错

sass相关

1738811796883.png

这种报错一般是样式编写不正确 例如scss的@for循环中不支持#{$i - 1}的写法。 image.png

免登录实现流程

  1. 编写免登录页面,调用登录接口,传入用户名与密码等参数,接口报2000后,根据路由中传入的redirect参数,跳转至指定页面;

1738825389677.png 2.在router/index.ts中注册autoLogin.vue页面路由

image.png

1738825522840.png 3. 在src/permission.ts中将免登录页面路由加入访问白名单;

1738825633731.png 4. 在浏览器中输入地址,即可免登录跳转。

1738825690162.png

.native

记住Vue鼠标修饰符,让你拿捏鼠标! 欢迎大佬补充~
修饰符 .native 用于在父组件监听子组件触发的原生事件。

1739251355781.png

如何在缩放页面时表格列宽随之调整

  1. 在hooks/userScaleSize中定义getRatioSize方法

image.png 2. 在el-table-column中通过getRatioSize计算minWidth或width大小

1739329601138.png

缩放页面发现,会再次调用getRatioSize方法重新计算表格中列表的宽度。疑惑点:
1、为啥缩放页面会再次调用getRatioSize方法;
2、el-table属性中min-width与width的使用场景。

1739330152361.png

LCA

解决yarn安装不上 需要删除yarn.lock

1736927269580.png

金相

ref获取vue组件报错

Uncaught (in promise) TypeError: dataOptions.call is not a function

image.png

Uncaught (in promise) TypeError:convert object to primitive value

Vue文件中使用的组件未import 1740312562206.png

在使用reactive定义一个对象xx,获取接口数据后,使用for(let key in xx)对对象进行赋值,会报相关错误,只用改成通过ref定义对象,再通过xx.value给对象赋值,才不会报相关错误,原因不解。

el-dialog居中展示且可丝滑拖拽

通过设置overlay的flex代替dialog的position 1740965664879.png

解决el-dialog打开 数据展示区域为空 不能展示接口返回数据

先将v-model绑定的数据设置为true 再调用接口给弹窗中关联的数据赋值。

el-image图片放大会被遮挡

1741749904203.png

解决图片无法正常访问

浏览器快捷方式/目标后贴上--ignore-certificate-errors --allow-running-insecure-content 注意这段字符串前面要加一个空格。

1741755954011.png

el-image 设置lazy后图片不展示

一图连铸

解决使用sortable.js拖拽表格改变某两行顺序后提交接口 再刷新表格数据 表格重新渲染后行排序不对

需要指定表格的row-key

image.png

image.png

使用v-for生成的div 设置data-xx属性 在css中通过attr(data-xx)无法使用该属性

按照如下截图方式 1742448258338.png

直接在style中设置变量名以及对应值,再在css中通过var()使用

1742448697524.png

1742448722637.png

解决报错'Uncaught (in promise) TypeError: Cannot read properties of null (reading "shapeFlag")'

1742793637092.png 原因在于定义一个对象时,这个对象中使用的变量未定义

image.png