现在项目架构是啥
- 技术栈
- 脚手架
- 开发规范
- css样式 less
- 响应式布局 pxToRem
- 组件库 mand-mobile
- 异步请求封装,拦截器统一处理请求和响应
- 路由 hash模式
- 开发和设计文档
目前架构的优势有哪些
多页面应用,设计器端和渲染端独立分开,应用分离,各自读各自的静态资源
路由页面按需加载,虽然渲染端是单页面应用
本地开发项目的时候通过env环境参数配置
响应式布局,根据屏幕的宽度定义跟字体,同时利用postcss中的pxToRem,实现响应式布局
移动端采用的第三方ui组件 按需引入,体积较小
跨域通过node服务转发,还有一种是在域名不一致的情况下打开H5页面,需要设置document.domain=’.xx.com’
架构有哪些缺陷
设计器端和渲染端SFC/js方法不要互相引用,如果有公共函数,抽离出来
对于常用的类型声明,定义声明全局类型声明,不要在每个文件使用的时候显式导入
class类里继承的属性太多,层层继承
静态资源没有压缩(图片和字体)
数据流管理混乱
- 渲染端的很多数据没有放到vuex集中管理
- action中随便更改state中的数据,导致数据来源不清晰
- postMessage事件名容易冲突,渲染端和设计器端通信通过postMessage来解决,定义事件名称的时候没有集中统一管理,会导致后面的通信名称跟之前的冲突
1
2
3
4topPostMessage({
name: 'changeZIndex',
zIndex:99
})
业务层面: 最重要的查询逻辑没有抽离,放到了每个图表组件本身。这样查询接口每次有改动,12个图表组件都得跟着改,维护性太差
ts没有发会类型编程的优势,反而成为一种累赘。这个需要自我检讨,后面再码代码的时候,还是会去定义和约束数据解构和类型
滥用this去读取data中数据,会多次重复地收集依赖,从而产生性能问题
Vue中避免滥用this去读取data中数据
怎么补充完善
减少两端的互相引用
项目根目录下创建typings目录,在目录下创建index.d.ts,定义全局声明
1
interface baseMode = 'same' | 'base
修改tsconfig.json,添加如下行
1
2
3
4
5{
"compilerOptions": {
"typeRoots": ["./node_modules/@types/", "./typings"],
}
}关于class继承层级太深的问题
优化图片 使用image-webpack-loader优化图片
字体文件可以使用CompressionWebpackPlugin进行压缩
项目是如何优化性能的
前端工程化方面
项目配置 externals 常用的库采用本地资源引入 减少构建包体积
路由页面配置按需加载
第三方Ui组件按需引入,比如手机端的ui库mand-mobile,
import Toast from 'mand-mobile/lib/toast'
1
2
3
4
5
6
7
8{
"plugins": [
["import", {
"libraryName": "mand-mobile",
"libraryDirectory": "lib"
}]
]
}
vue方面
- V-if和v-for禁止一起使用
- sscoped css 当前vue组件的css只作用于当前组件的元素
- 组件keep alive,包裹动态组件,缓存组件实例,主要是用于保留组件状态或避免重新渲染
- v-once只会渲染一次的组件
- 离开组件时,移除绑定事件,手动销毁事件监听器,以免造成内存泄漏
1
2
3private beforeDestroy() {
window.removeEventListener('message', this.dataSetting)
} - 组件渲染列表的时候,key绑定唯一的值
js编程方面
合理使用合成层,如使用transform: translateZ(0)开启硬件加速
axios封装 ajax请求都集中到了api目录下,所有的请求放在一个文件夹集中管理
返回顶部的时候,采用了请求动画帧来处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public scrollToTop() {
const dom = this.domRef
let timer = null
if (dom) {
cancelAnimationFrame(timer);
timer = requestAnimationFrame(
function fn() {
const oTop = dom.scrollTop
if (oTop > 0) {
dom.scrollTop = oTop - 100; // 距离顶部的距离
timer = requestAnimationFrame(fn)
} else {
cancelAnimationFrame(timer)
}
}
)
}
}