Skip to content

EMI云数据平台(数据大屏)— 速记版

项目时间:2022年11月 - 2023年01月 | 工厂设备运行与化工用料实时数据展示 技术栈:Nuxt2 + Vue2 + DataV + v-scale-screen + ECharts + echarts-gl + Element UI + Less 一句话定位:挂在工厂大厅的大屏,实时展示机台效率、环保数据、染化料用量,配合 3D 地球、字幕雨这类要震撼的可视化。

📋 速记表(面试前快速扫)

一句话结论关键词
Q1v-zoom-up 放大+引导线,scale 反算坐标v-zoom-up 反算scale
Q2echarts-gl globe + lines3D 飞线globe lines3D
Q3v-scale-screen 等比缩放 + client-only 兼容 SSR等比缩放 SSR
Q4Canvas rAF 字幕雨,半透明拖尾Canvas rAF 雨
Q5clip-path 六边形蜂窝 + content-visibilityclip-path 蜂窝
Q6target:static + nuxt-precompress 预压 gz/br静态 预压缩
Q7rAF 表格自动滚动 + sessionStorage 缓存rAF滚动 缓存
Q8自封 Fullscreen API + IE 兜底 F11全屏兼容 IE兜底

Q1: v-zoom-up 自定义指令设计

面试官可能问:v-zoom-up 怎么实现放大和引导线?

🗣️ 口述稿

鼠标悬浮 DataV 边框盒出现放大按钮,点击模块从原位居中放大到屏幕中央,原位置 Canvas 画虚线框+网格"引导线",点遮罩/引导线恢复。动态创建按钮、getBoundingClientRect 记 originRect、加遮罩 + CSS 过渡 + transform:scale(1.35) 放大。

💡 关键词提示放大按钮 引导线 transform:scale

⚠️ 备注

  • 最值钱的是坐标系转换:外层 v-scale-screen 缩放后 offsetLeft 是缩放布局坐标,要居中必须反算 diffX=(window.innerWidth-rect.width)/2/scaleWidth - elOffsetLeft,能背出公式证明真调过坑
  • 每次悬浮 setTimeout 300ms 重取 originRect 防表格刷新导致脏缓存,顺便 pointerEvents:none 防误点

追问①:为什么 mouseenter 时 setTimeout 300ms 再取 originRect?

大屏数据几秒刷新改元素尺寸,缓存旧 originRect 会让引导线偏移。每次悬浮取最新 + pointerEvents:none 防误点。防脏缓存。

追问②:指令的 modifier/arg 干嘛?

v-zoom-up:table-visible(arg) 控制放大时表头半透明适配边框发光;.normalShadow(modifier) 关掉默认 box-shadow。用参数修正不同块的特例。


Q2: echarts-gl 动态地球飞线图

面试官可能问:3D 地球飞线怎么做的?

🗣️ 口述稿

首页中央 echarts-gl 的 globe 做 3D 地球:baseTexture 卫星图 + heightTexture 地形、displacementScale 起伏、autoRotate 自转。两个 lines3D 系列模拟飞出飞线,effect.trailLength 拖尾、trailColor 配色,起点固定、终点随机经纬度,造全球扩散效果。

💡 关键词提示globe lines3D 随机终点

⚠️ 备注

  • 讲选型理由:lines3D 是 globe 坐标系专用、effect.show 自带流光不用手写动画。2D lines 没世界地图 geo 撑不起来、linesGL 是另一套坐标系
  • 承认终点随机是"效果数据"非真实业务地图,更诚实
  • [需自行确认] "65条飞线(33+32)"按仓库 randomData 核对,别背死参数

追问①:3D 地球低配机卡怎么办?

降 displacementQuality、关 postEffect、降环境光计算量。

追问②:为什么终点用随机经纬度?

让每次刷新方向有变化、强调全球扩散动态感,是展示效果数据不是真实业务地图。


Q3: v-scale-screen 屏幕自适应 + SSR 兼容

面试官可能问:大屏怎么适配不同分辨率?

🗣️ 口述稿

v-scale-screen 按设计稿 2560×1440 等比缩放,监听 resize 取宽高比例较小值做 transform:scale(),2K/4K/1080p 完整展示不破版。v-zoom-up 的居中反算正是靠这个 scale 系数。

💡 关键词提示等比缩放 取小值 scale系数

⚠️ 备注

  • 最真实的坑是 Nuxt2 SSR:v-scale-screen 依赖 DOM,SSR 报错。用 <client-only> 包裹只客户端渲染 + dv-loading 遮初始化
  • 为什么不用 rem/百分比:等比保证逐像素一致绝不破版,大屏要所见即得

追问①:它跟 v-zoom-up 坐标什么关系?

正是 scale 缩放让 v-zoom-up 居中要反算。window.innerWidth/2560 是 scale 系数、diffX/scaleWidth 反算偏移。同一套心智两处贯通。

追问②:为什么不用 rem 百分比?

等比保证逐像素一致不破版;rem/百分比是自适应不是等比。大屏要所见即得。


Q4: 字幕雨(Matrix Rain)

面试官可能问:代码雨效果怎么实现?

🗣️ 口述稿

Canvas 全屏 + requestAnimationFrame 逐帧。每帧先画半透明背景让旧字符逐渐消失成拖尾,再遍历每列 rainDropPositionArray[i]++ 画一个从字符池随机取的字符,触底 90% 概率重置该列从头下落。列数是 canvasWidth/fontSize,降帧 speed 控到约 30fps。

💡 关键词提示Canvas rAF 90%重置

⚠️ 备注

  • 为什么 Canvas 不是 CSS:CSS 要为每列建 DOM,142 列×多字符下落海量节点,Canvas 一个元素全画
  • rAF 做了 webkit/moz/o/ms 前缀兜底 setTimeOut(1000/60),因为工业大屏可能跑旧 Chrome

追问①:rAF 兼容性怎么处理?

手动做 webkit/moz/o/ms 前缀兜底到 setTimeOut(1000/60)。工业大屏可能跑旧 Chrome,兼容老环境意识。


Q5: 六边形背景动态闪烁

面试官可能问:顶部蜂巢背景怎么做的?

🗣️ 口述稿

纯 CSS:clip-path: polygon(...) 切六边形,5 行×每行 120 个 flex 交错排列,generateGlitch 每 2s 遍历按 Math.random()>0.5 随机切亮,配合 transition 产生电路板闪烁。

💡 关键词提示clip-path flex交错 随机切亮

⚠️ 备注

  • 为什么 CSS 不是 Canvas:clip-path+flex 原生适配宽度,虽然 600 个 DOM 有开销,用 content-visibility:auto 跳过屏外渲染 + mask 渐变淡出

追问①:600 个 DOM 会不会卡?

会有一点,所以用 content-visibility:auto 让浏览器跳过屏外渲染,只给可见区做 transition。


Q6: Nuxt2 静态生成 + 预压缩

面试官可能问:Nuxt2 部署和优化怎么做的?

🗣️ 口述稿

target:'static' + npm run generate 出纯静态文件部署 Nginx,DataV 数据前端 Axios 实时拉所以不需要 SSR。nuxt-precompress 构建时生成 .gz+.br 双格式(gzip level9/brotli level11),Nginx gzip_static on 优先返 brotli。

💡 关键词提示target:static nuxt-precompress gzip_static

⚠️ 备注

  • 为什么静态不 SSR:数据前端轮询拉不是渲染注入,静态+Nginx 免运维不用养 Node 进程
  • [需自行确认] "brotli 比 gzip 高15-25%"是常识非本项目实测;端口按仓库 server.port 核对

追问①:gzip_static 和实时 gzip 差别?

静态预压缩构建期压好,请求时不 CPU 实时压、响应更快;实时 gzip 每次请求都压耗 CPU。


Q7: 表格自动滚动 + sessionStorage 缓存

面试官可能问:底部表格自动滚动和缓存怎么做的?

🗣️ 口述稿

三个底部表格用 requestAnimationFrame 驱动 scrollTop+=1,触底 scrollTop=0 无限循环;鼠标悬浮暂停离开恢复。数据首次拉完 sessionStorage 缓存,切 tab 回来直接用不重新请求。

💡 关键词提示rAF滚动 触底循环 sessionStorage

⚠️ 备注

  • 为什么 rAF 不 setInterval:和刷新率同步更平滑、后台自动暂停省资源、setInterval 后台降频
  • 为什么 sessionStorage:v-if 切换每次重挂载,缓存避免重复请求。承认是体验优化非强一致方案

追问①:缓存会不会读到旧数据?

sessionStorage 当前标签页级、关页即清,数据又持续刷新,缓存只为避免切 tab 重请求,真实度要求不高够用。是体验优化不是强一致。


Q8: 全屏 API 跨浏览器兼容

面试官可能问:大屏全屏功能怎么兼容?

🗣️ 口述稿

自封 Fullscreen API 兼容层:requestFullScreen || webkit || moz || ms,退出同理;老 IE 用 ActiveX WScript.Shell.SendKeys("F11") 模拟;screen.height-clientHeight<=17 + document.fullscreenElement 综合判断状态。

💡 关键词提示Fullscreen兼容 IE的F11 多信号判断

⚠️ 备注

  • 为什么不用 screenfull.js:包体积敏感,全屏逻辑不到30行,自包还能专做 IE 兜底。讲"按体量砍依赖"

追问①:判断全屏为什么用分辨率差值兜底?

不同浏览器 fullscreenElement 支持不一,用 screen.height-clientHeight<=17 经验值兜底再叠 API 判断。多信号综合的鲁棒思路。


🎙️ 行为面试

为什么做这个项目?

中恒智造给纺织厂做智造,客户要挂工厂大厅/会议室的大屏,实时展示机台效率、水/汽/母液用量、环保数据。之前老板来视察只能看 Excel。我从 0 搭 Nuxt2 + DataV + ECharts 大屏。

💡 关键词客户大屏 可视化 从0搭建

最大难点?

  1. v-zoom-up/地球的屏幕坐标反算——v-scale-screen 缩放后 getBoundingClientRect(屏幕像素)和 offsetLeft(缩放布局)两套概念,居中/引导线都要反算 scale
  2. echarts-gl 在低配机帧率低——降位移精度/关后处理才稳
  3. Nuxt2 SSR 和纯客户端库冲突——DataV/echarts-gl/v-scale-screen 都要 process.client + client-only,否则 window is not defined

💡 关键词坐标反算 低配帧率 SSR冲突

遗憾/弯路?

  1. 用 setInterval 5s 轮询不是 WebSocket——延迟高带宽浪费、更新不及时
  2. factory/theory 内容页代码重复——都是 dv-border-box 包一层没抽公共组件
  3. 数据多是 Math.random() mock 没真接 IoT 传感器——该接 MQTT 实时流,实用价值打折

💡 关键词setInterval轮询 代码重复 mock数据

DataV 和 ECharts 什么区别?

DataV(@jiaminghi/data-view)做装饰性可视化(边框/装饰线/翻牌器/loading),ECharts 做数据可视化(折线/柱状/雷达/3D 地球)。DataV 负责好看、ECharts 负责有数据,互补。


🃏 极简速记卡(面试前5分钟看)

  • Q1 v-zoom-up:放大+引导线,scale反算坐标
  • Q2 地球:globe+lines3D 随机终点
  • Q3 适配:等比缩放+SSR用client-only
  • Q4 字幕雨:Canvas rAF+半透明拖尾
  • Q5 蜂窝:clip-path+自定义闪烁
  • Q6 部署:静态+预压缩gz/br
  • Q7 表格:rAF滚动+session缓存
  • Q8 全屏:自封装+IE的F11兜底
  • 行为 动机:客户大屏;难点:坐标反算+SSR;遗憾:5s轮询+mock数据

上一篇:07-EMI协同管控平台 下一篇:09-中恒智造官网

前端开发工程师 · 面试准备