# 唐山津西钢铁 **Repository Path**: tyhdznkj/tangshan-jinxi-vue-pc ## Basic Information - **Project Name**: 唐山津西钢铁 - **Description**: No description available - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-09 - **Last Updated**: 2026-03-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ##### 项目运行前提 ```js // 1. node版本>=16.13.2 || // 2. 或者使用nvm进行多版本node切换 ``` ##### 项目拉取本地安装依赖 ```js // 1. npm i // 2. cnpm i // 3. yarn (推荐使用) ``` ##### 项目运行 ```js // 1. npm run dev // 2. yarn dev(推荐使用) ``` ##### 项目打包 ```js // 1. npm run build // 2. yarn build ``` ##### 注意点 ```js 1. 无需安装sass-loader 2. components 下的组件,无需import引入,直接在page页面使用即可 ``` ##### 特点 ```js 1. 运行速度快(当你执行完dev命令后,无需等待,体验快享受) 2. 打包后的文件夹相当小 ``` ##### 项目技术 ```js Vue3.0(全家桶) + scss + vite + axios + ElementPlus + fontAwesome + echarts ``` ##### 项目结构 ```js - node_modules //存放项目依赖的包目录 - dist //存放打包之后的代码文件 - public //存放公共文件目录 - src //存放代码的主要目录 ----- api //预计 (存放数据接口主文件夹) ----- backstage //预计 (后台接口管理) ----- assets // 存放了每个页面对应的css、js以及图片文件 ----- style //全局样式文件夹 -----mixin.scss //全局的公共的样式类名 ----- components //管理组件文件夹 ----- backstage //后台管理组件管理文件夹 ----- public //后台管理公共的组件文件夹 ----- public //公共组件文件夹 ----- data // 静态数据管理文件夹 ----- pagePublic //后台页面管理公共数据文件夹 ----- router //管理路由文件夹 ----- index.js //路由的入口 ----- util //存放项目封装的插件的文件夹 ----- request.js //ajax请求的配置 ----- views //存放页面文件 ----- backstage //后台管理页面主文件夹 ----- //模块1 ----- .... //(页面1) ----- .... //(页面2) ----- //模块2 ----- .... //(页面1) ----- .... //(页面2) ----- common //除后台管理页面 都在这 ----- login //(登录页面) ----- LargeScreen //(大屏页面) ...... ----- App.vue //根组件文件 ----- main.js //入口文件 - .env.dev //开发环境配置的全局变量 - .env.prod //生产环境配置的全局变量 - .gitignore //Git相关文件,配置不上传至git库的文件 - index.html //项目入口文件 - package.json //存放依赖包管理及命令管理信息文件 - readme.md //使用markdown编写的文档文件 - vite.config.js //项目配置文件 - yarn.locak //使用yarn包管理生成的文件,由yarn自动生成,自动管理。不需要管。 ``` #### 扩展 ##### 1. 什么是vite ```js 1.1 Vite是尤雨溪在开发vue3的时候开发的一个web开发构建工具 1.2 极速的服务启动: 使用原生 ESM 文件,无需打包! 1.3 轻量快速的热重载:无论应用程序大小如何,都始终极快的模块热重载(HMR) 1.4 丰富的功能: 对 TypeScript、JSX、CSS 等支持开箱即用。 1.5 vite使用简单,只需执行初始化命令,就可以可得到一个预设好的开发环境,开箱即可获得一堆功能,包括: css预处理、html预处理、异步加载、分包、压缩、HMR等。使用复杂度介于Paracel和Webpack的中间,只是 暴露了极少数的配置项和plugin接口,既不会像Paracel一样配置不灵活,又不会像Webpack一样需要了解庞 大的loader、plugin生态。灵活适中,复杂度适中 1.6 ``` ##### 2. vite和webpack区别 ###### 2.1 webpack和vite ```js 都是现代化打包工具 //备注:准确来说 vite是下一代前端开发与构建工具(官网有准确说道) ``` ###### 2.2 webpack打包过程 ```js 1. 识别入口文件 2.通过逐层识别模块依赖。(Commonjs、amd或者es6的import,webpack都会对其进行分析。来获取代码的依赖) 3.webpack做的就是分析代码。转换代码,编译代码,输出代码 4.最终形成打包后的代码 ``` ###### 2.3 webpack打包原理 ```js 1.先逐级递归识别依赖,构建依赖图谱 2.将代码转化成AST抽象语法树 3.在AST阶段中去处理代码 4.把AST抽象语法树变成浏览器可以识别的代码, 然后输出 ``` ###### 2.4 vite原理 ```js 1. 当声明一个 script 标签类型为 module 时 2.浏览器就会像服务器 http://localhost:3000/src/main.js //请求main.js文件: //发起一个GET请求 // /src/main.js: import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') 2.1 浏览器请求到了main.js文件,检测到内部含有import引入的包,又会对其内部的 import 引用发起 HTTP 请求获取模块的内容文件 // 如:GET http://localhost:3000/@modules/vue.js // 如:GET http://localhost:3000/src/App.vue 2.2 Vite 的主要功能就是通过劫持浏览器的这些请求,并在后端进行相应的处理将项目中使用的文件通过简单 的分解与整合,然后再返回给浏览器,vite整个过程中没有对文件进行打包编译,所以其运行速度比原始的 webpack开发编译速度快出许多! ``` ###### 2.5 webpack缺点一。缓慢的服务器启动 ```js 当冷启动开发服务器时,基于打包器的方式是在提供服务前去急切地抓取和构建你的整个应用。 ``` ###### 2.6 vite 针对2.5问题的改进 ```js 2.6.1 Vite 通过在一开始将应用中的模块区分为 依赖 和 源码 两类,改进了开发服务器启动时间。 2.6.2 依赖 大多为纯 JavaScript 并在开发时不会变动。一些较大的依赖(例如有上百个模块的组件库)处理的代价也很高。依赖也通常会以某些方式(例如 ESM 或者 CommonJS)被拆分到大量小模块中。 2.6.3 Vite 将会使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。 2.6.4 源码 通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源码都需要同时被加载。(例如基于路由拆分的代码模块)。 2.6.5 Vite 以 原生 ESM 方式服务源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入的代码,即只在当前屏幕上实际使用时才会被处理。 ``` ###### 2.7 webpack缺点2.使用的是node.js去实现 ```js //详情看下面的图 ``` ###### 2.8 vite根据2.723问题改进 ```js Vite 将会使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 Node.js 编写的打包器预构建依赖快 10-100 倍。 ``` ###### 2.9 webpack致命缺点3.热更新效率低下 ```js 2.9.1 当基于打包器启动时,编辑文件后将重新构建文件本身。显然我们不应该重新构建整个包,因为这样更新速度会随着应用体积增长而直线下降。 2.9.2 一些打包器的开发服务器将构建内容存入内存,这样它们只需要在文件更改时使模块图的一部分失活[1],但它也仍需要整个重新构建并重载页面。这样代价很高,并且重新加载页面会消除应用的当前状态,所以打包器支持了动态模块热重载(HMR):允许一个模块 “热替换” 它自己,而对页面其余部分没有影响。这大大改进了开发体验 - 然而,在实践中我们发现,即使是 HMR 更新速度也会随着应用规模的增长而显著下降。 ``` ###### 2.10 vite根据2.9问题改进 ```js 2.10.1 在 Vite 中,HMR 是在原生 ESM 上执行的。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失效(大多数时候只需要模块本身),使 HMR 更新始终快速,无论应用的大小。 2.10.2 Vite 同时利用 HTTP 头来加速整个页面的重新加载(再次让浏览器为我们做更多事情):源码模块的请求会根据 304 Not Modified 进行协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求。 ``` ###### 2.11 vite的缺点 ```js 2.11.1 生态问题: wepback厉害之处在于loader和plugin非常丰富,不过我认为生态只是时间问题,现在的vite,更像是当时刚出来的M1芯片Mac,我当时非常看好M1的Mac,毫不犹豫买了,现在也没什么问题 2.11.2 prod环境的构建,目前用的Rollup 原因在于esbuild对于css和代码分割不是很友好 ``` ###### 2.12 总结 ```js 2.12.1 webpack: 分析依赖=> 编译打包=> 交给本地服务器进行渲染。首先分析各个模块之间的依赖,然后进行打包,在启动webpack-dev-server,请求服务器时,直接显示打包结果。webpack打包之后存在的问题:随着模块的增多,会造成打出的 bundle 体积过大,进而会造成热更新速度明显拖慢。 2.12.2 vite: 启动服务器=> 请求模块时按需动态编译显示。是先启动开发服务器,请求某个模块时再对该模块进行实时编译,因为现代游览器本身支持ES-Module,所以会自动向依赖的Module发出请求。所以vite就将开发环境下的模块文件作为浏览器的执行文件,而不是像webpack进行打包后交给本地服务器。 2.12.3 分析了webpack和vite的打包方式后,也就明白了为什么vite比webpack打包快,因为它在启动的时候不需要打包,所以不用分析模块与模块之间的依赖关系,不用进行编译。这种方式就类似于我们在使用某个UI框架的时候,可以对其进行按需加载。同样的,vite也是这种机制,当浏览器请求某个模块时,再根据需要对模块内容进行编译。按需动态编译可以缩减编译时间,当项目越复杂,模块越多的情况下,vite明显优于webpack. 2.12.4 热更新方面,效率更高。当改动了某个模块的时候,也只用让浏览器重新请求该模块,不需要像webpack那样将模块以及模块依赖的模块全部编译一次。 ``` ###### 2.13 如图所示 2.13.1 webpack ![https://vitejs.cn/assets/bundler.37740380.png](https://vitejs.cn/assets/bundler.37740380.png) 2.13.2 Vite ![https://vitejs.cn/assets/esm.3070012d.png](https://vitejs.cn/assets/esm.3070012d.png) ##### 3. V3.0 与 V2.0 区别 ###### 3.1 生命周期 与 整体语法糖 ```js 整体来看,变化不大,只是名字大部分需要 + on,功能上类似。使用上 Vue3 组合式 API 需要先引入;Vue2 option API 1.语法糖 //V2 中 //V3中 //第一种 // useMousePosition.js import { ref, onMounted, onUnmounted } from vue function useMousePosition() { let x = ref(0) let y = ref(0) function update(e) { x.value = e.pageX y.value = e.pageY } onMounted(() => { window.addEventListener( mousemove , update) }) onUnmounted(() => { window.removeEventListener( mousemove , update) }) return { x, y } } //备注 :解决了 Vue2 Mixin的存在的命名冲突隐患,依赖关系不明确,不同组件间配置化使用不够灵活。 ``` ###### 总结 ```js V3是采用ts重写。无论在语法糖上的更新,还是在APi的更新还是挺大的区别的,以上只是例举了几点,其余还是需要开发者不断的学习. ``` ##### 4. 响应式原理 ```js 1. V2 响应式原理基础是es5中的Object.defineProperty; 2. V3 响应式原理基础是es6中的Proxy。 //Object.defineProperty 直接在一个对象上定义新的属性或修改现有的属性,并返回对象。 writable 和 value 与 getter 和 setter 不共存。 //例如 let obj = {} let name = "小明" Object.defineProperty(obj, name , { enumerable: true, // 可枚举(是否可通过for...in 或 Object.keys()进行访问) configurable: true, // 可配置(是否可使用delete删除,是否可再次设置属性) // value: , // 任意类型的值,默认undefined // writable: true, // 可重写 get: function() { return name }, set: function(value) { name = value } }) ``` ###### 4.2 搬运 Vue2 核心源码,略删减。 ```js function defineReactive(obj, key, val) { // 一 key 一个 dep const dep = new Dep() // 获取 key 的属性描述符,发现它是不可配置对象的话直接 return const property = Object.getOwnPropertyDescriptor(obj, key) if (property && property.configurable === false) { return } // 获取 getter 和 setter,并获取 val 值 const getter = property && property.get const setter = property && property.set if((!getter || setter) && arguments.length === 2) { val = obj[key] } // 递归处理,保证对象中所有 key 被观察 let childOb = observe(val) Object.defineProperty(obj, key, { enumerable: true, configurable: true, // get 劫持 obj[key] 的 进行依赖收集 get: function reactiveGetter() { const value = getter ? getter.call(obj) : val if(Dep.target) { // 依赖收集 dep.depend() if(childOb) { // 针对嵌套对象,依赖收集 childOb.dep.depend() // 触发数组响应式 if(Array.isArray(value)) { dependArray(value) } } } } return value }) // set 派发更新 obj[key] set: function reactiveSetter(newVal) { ... if(setter) { setter.call(obj, newVal) } else { val = newVal } // 新值设置响应式 childOb = observe(val) // 依赖通知更新 dep.notify() } } ``` 那 Vue3 为何会抛弃它呢?那肯定是有一些缺陷的。 主要原因:无法监听对象或数组新增、删除的元素。 Vue2 方案:针对常用数组原型方法push、pop、shift、unshift、splice、sort、reverse进行了hack处理;提供Vue.set监听对象/数组新增属性。对象的新增/删除响应,还可以new个新对象,新增则合并新属性和旧对象;删除则将删除属性后的对象深拷贝给新对象。 ###### 4.3 proxy ```js Proxy是ES6新特性,通过第2个参数handler拦截目标对象的行为。相较于Object.defineProperty提供语言全范围的响应能力,消除了局限性。但在兼容性上放弃了(IE11以下) 局限性: 1. 对象/数组的新增、删除。 2. 监测.length修改。 3. Map、Set、WeakMap、WeakSet的支持。 //例如: let obj = { name:"小明", age:18 } let p = new proxy(obj,{ //get 属性读取时操作 get(target,prop){ //taget 就是上面定义的obj对象 //prop 是obj的属性名 if (prop in target) { //如果该属性名存在与该对象中,则返回该属性值 return target[prop]; } else { //否则返回字符串 "该对象没有该属性" return "该对象没有该属性"; } }, //set 属性设置时 set(target, prop, value) { //target 就是 obj 这个对象 //prop 是 obj 的属性名 //value 是 要设置的值 if (prop === "age") { //如果该属性名是age,则返回修改后的值 target[prop] = value; } else { //否则弹出异常内容 throw "除年龄外,其它属性不可以更改"; } } }) // 备注:及时你这对象有100层 都会更改,不会像V2似的必须使用this.$set才能更改 ``` ###### 4.4 搬运V3的源码reactive.ts文件 ```js function createReactiveObject(target, isReadOnly, baseHandlers, collectionHandlers, proxyMap) { ... // collectionHandlers: 处理Map、Set、WeakMap、WeakSet // baseHandlers: 处理数组、对象 const proxy = new Proxy( target, targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers ) proxyMap.set(target, proxy) return proxy ``` ###### 4.5为什么在vue3中每个页面都需要引用ref,reactive ```js 在 Vue 3 中,每个页面都需要引用 ref 和 reactive 的原因是因为 Vue 3 引入了 Composition API,这是一种新的组合式 API,提供了更灵活的方式来编写 Vue 组件。 ref 和 reactive 都是 Composition API 中用于创建响应式数据的函数。ref 用于创建单个值的响应式数据,而 reactive 则用于创建复杂对象的响应式数据。 使用 Composition API 可以让我们更灵活地组织组件的逻辑,将相关的逻辑聚合在一起,而不是按照固定的生命周期函数来组织。这样可以使代码更加清晰易懂,也更容易维护。 另外,使用 ref 和 reactive 还可以带来性能上的提升。在 Vue 3 中,对响应式数据的追踪和更新机制进行了优化,使得响应式数据的更新更加高效。这也是 Vue 3 与 Vue 2 相比的一个重要的改进之一。 ``` ###### 为什么需要我们手动引入,而不是vue3自动引入? ```js 在 Vue 3 中,需要手动引入 ref 和 reactive,而不是自动引入,是因为 Vue 3 中引入了 Tree Shaking 机制,这种机制可以对无用的代码进行剪枝,从而减小打包后的文件体积。 如果 Vue 3 自动引入了 ref 和 reactive,那么无论我们是否使用这些 API,它们都会被打包进最终的代码中,这样就会增加打包后的文件体积。 而手动引入 ref 和 reactive,则可以让我们更加精细地控制打包后的文件大小。我们只需要在需要使用 ref 和 reactive 的地方手动引入它们即可,这样就可以避免引入无用的代码,减小文件体积。 此外,手动引入 ref 和 reactive 还可以提高代码的可读性和可维护性。我们可以在代码中清晰地看到每个 API 的引用位置,这样可以更方便地查找和修改代码。 ``` ##### 5. V3性能的提升 ```js 1. 打包大小减少41% 2. 初次渲染快55%,更新渲染快133% 3. 内存占比少54% ``` ##### 6. 端口对应路径 ```js 1. 8100 'base' 系统管理模块 2. 8200 'iron' 炼铁 3. 8500 'location' 定位 4. 8600 'production' 生产 5. 8700 'steel' 炼钢 ``` ##### 7. 停用 ```js 1. 铁水实绩 ironfactinfo 2. 铁水罐倒铁实绩 ironpourinfo 3. 出铁实绩 irontapinfo 4. 铁水罐配置计划 tpcconfigplan 5. 铁水罐罐位信息 tpcpositioninfo ``` ##### 8. 导出 ```js 1. 铁水罐检修统计 2. 铁水罐受铁实绩 3. 铁水罐生命周期 4. 主机配置 5. 铁包数据统计 ``` ##### 9. websocket标识 ```js logic 模块端口: 19090 location 模块端口: 19091 状态 == 值 : 页面 --> 模块 --> 功能 0:运输板块==》铁水罐跟踪==》机车运动消息 1:运输板块==》铁水罐跟踪==》罐运动坐标消息 2:运输板块==》铁水罐跟踪==》罐架运动列消息 3:运输板块==》铁水罐跟踪==》车颜色状态 4:运输板块==》铁水罐跟踪==》罐重罐/检修罐颜色状态 5:运输板块==》铁水罐跟踪==》罐架重罐颜色状态 6:生产板块==》左上方当前生产统计 7:生产板块==》左中当前生产统计 8:生产板块==》铁水平均装入 9:生产板块==》在线个数统计 10:生产板块==》高炉产量 11:生产板块==》平均皮重 12:生产板块==》铁水周转率 13:炼铁板块==》高炉出铁==》铁口跟踪数据 14:炼铁板块==》高炉出铁==》罐位跟踪 15:炼铁板块==》高炉出铁==》出铁完成 16: 状态检测==》 --> 识别主机 --> 刷新 17: 状态检测==》 --> 液位计 --> 刷新 18: 状态检测==》 --> ai/轨道衡 --> 刷新 19: 运输板块==》 铁水罐跟踪--> 左上角罐数刷新 ```