1. 个人经验总结 - 前端开发经验总结

  • 前端开发过程(如果有的部分已经有现有代码或者已经提前做好了,那么可以提前)
    • 项目结构
      • 注意要分层设计,如Angular中分为好多层
      • 注意提取公共组件
      • (路由)注意每个子业务需要有独立的url(即每个子页面需不需要有独立的url,比如有子路径,或者有id参数等),这样可以保证刷新页面不会回到初始界面。这要根据具体业务来判断,比如wizard这种的某个中间状态可以没有独立的url,到下一步时不用改变url。
      • 考虑清楚哪些东西是根据部署环境变化的,需要提取到哪一级的环境变量或者配置文件中?前端的environment中?node.js的服务端环境变量中(作为接口提供给前端?还是在运行过程中在node.js的app.js代码中去做文件操作改变前端文件)?
        • 如果某些依赖需要马上加载,那么这些依赖的地址最好别从后端读,那就慢了
    • 页面(可以先使用mock数据做结构和样式)
      • HTML静态结构及样式
        • 尽量使用现成的框架(如Angular、Bootstrap栅格系统)和控件(如Bootstrap控件、Material控件)。
        • 可以现在浏览器的开发者工具中一批批的调试样式,然后一批一批的更新到代码中。
        • 可以先把样式作为内联style写在DOM元素上,都调好以后再一起整理到单独的css样式文件中。
      • 动态效果
        • 注意把逻辑代码提取成函数或单独的文件,如Angular中分离出独立的xxx.service.ts
      • 前端逻辑
        • 数据检验、限制
        • 数据解析、整理
        • 可以从业务类继承出子类,加上一些界面显示使用的字段
    • 与后台交互
      • 读+解析数据成UI对象、写+整理数据成参数对象
        • 创建合理的业务数据对象
        • 注意加载中效果的样式、位置、层级、开始结束时机
        • 注意多个请求的依赖关系,避免同时异步请求导致行为异常
    • 单元测试(使用mock数据)
      • 测试对象是业务逻辑函数(如Angular中service.ts文件中的函数),页面显示相关的简单函数没必要测(如果有逻辑,那么说明需要提取出来)。
  • 代码工程
    • 前端代码也要注意职责分离,如Angular这种工程化的框架,页面(如命名为xxx.page.ts)中最好只留和页面元素、事件相关的代码,而把业务逻辑、公共函数等提取到yyy.component.ts或yyy.service.ts中,并写相应的yyy.service.spec.ts单元测试(可以通过修改test.ts中的正则表达式而只跑这些单元测试并生成代码覆盖率报告)。
    • 写逻辑的时候要想好情理上怎么做是合适的易于理解的,代码只是一个实现方式
      • 比如在做输入验证时,如果有多条记录要验证,每条记录有自己的检查逻辑,然后彼此之间又有总数限制、不重名等,那么先要在情理上想通,否则会比较复杂,因为要考虑很多检查时机如编辑每一条记录时、删除一条记录时,还要考虑验证错误信息的优先级如先显示重名还是自己本身的错误,还要考虑有重复时都显示错误信息还是只在后面的记录上显示,还是无所谓?因此最终应当每个时机都去检查所有记录,每个记录的检查都要先检查自身合法性,然后再检查总体合法性。
    • 每个有特别业务含义的元素上最好都加上id,方便测试人员做自动化测试。
      • 比如按钮上、提示信息上。
      • 外层还是内层看情况,都可以,至少有一个上面要有。
  • 开发经验
    • url设计
      • 要斟酌哪些页面有单独的url及命名方式、跳转关系,哪些页面共用url(比如一些中间页面)
      • 单个实体的页面最好在url上有单独的url+id
      • 虽然Angular等是单页面应用,可以在一个url上实现所有页面,但这样的话用户不方便保存连接、刷新页面(会丢失状态)。
    • 虽然是在前端,也可以对模型类进行分类。比如分成直接和接口数据对应的类,然后在此基础上可以继承出用于UI操作的子类,包含一些用于UI显示的字段,如是否显示扩展信息等。
    • 开发时可以先在浏览器的开发者工具中调样式,然后适时作为style记录到页面代码上,最后再统一整理成多个合理的class(不一定每个都要定义成class或者id,可以通过上层的class或id来定位也行)
    • 浏览器Console的使用
      • 可以执行js、jQuery语句或表达式
        • 比如可以直接在浏览器上执行JSON.parse()、new RegExp("")等函数来进行测试,比如测试最终要转换的json字符串的合法性、最终要使用的正则表达式的合法性
        • 但js、jQuery语句的运行环境是当前页面的当前时刻,也就是说如果想跑jQuery语句,必须当前页面的当前时刻已经引入过jQuery等相关的库
        • 如果想看的是使用typescript代码引入的库或者运行时才引入的不知道什么库的代码,平时该表达式/语句不存在,可以在浏览器中Debug到该处代码时,再在watch或者console中查看表达式或者运行语句。
    • 暂存数据还是每次都重新请求
      • 有时要斟酌接口数据应该每次都重新请求,还是应该页面上缓存一下(尤其Angular这种单页面程序,即使跳转页不会刷新页面),也就是斟酌数据的实时性重要还是性能和体验重要。或者说如果有多个用户同时对同一资源进行操作,不刷新页面的话可以接受什么时候不用重新请求数据,什么时候又需要重新请求(尤其对Angular这种组件化、层次化的应用,如果多个层次或组件都需要请求数据,那么就要考虑要不要用一个全局的service来缓存数据,还要避免不同组件的异步操作互相之间有影响,会导致奇怪的行为,比如全局的loading控制要避免错乱)。
  • 问题总结
    • 如果多个ajax请求的结果之间有依赖关系,那么就要嵌套调用,否则容易因为多个请求的结束先后时机不同而导致逻辑不同。
      • 不一定是指同一个功能中的两个请求,即使是两个功能块,如果各自有异步请求且之间在逻辑上有先后或依赖关系,那么也要考虑做成同步的!!!否则可能会引起奇怪的页面或逻辑问题,。比如页面上的loading效果会错乱,比如被别的异步操作打断而提前结束,或者页面过几秒又自己发生变化。
    • 开发过程中要考虑清楚代码最终运行在哪里,是浏览器还是服务端
      • 比如Angular的environment变量其实还是运行在前端也就是用户浏览器中,而如果用了node.js服务端代码如app.js,那么使用的process.env.xxx读取的就是服务器端的环境变量(来自node.js环境变量或者Cloudfoundry环境变量或linux环境变量?)
    • 页面多线程与block用户频繁操作
      • 当页面使用了tab标签页、刷新按钮、提交按钮等可以在业务处理后更新页面元素的功能时,如果在操作时不把tab标签页、刷新按钮给disable掉,或者不把结果元素给block掉,用户就有可能在页面上快速得胡乱操作。
      • 这个时候,由于页面代码在和后台交互时很可能用的是ajax等异步操作,如果每条线中的逻辑不太完美,比如用了一些标识变量来控制逻辑操作顺序,那么用户胡乱操作多次,可能会导致各个异步操作操作,比如某判断变量的值在赋值或更新之前就被使用。
        • 如果目前没有使用block或disable的功能,那么就要尽量少用这种判断变量,避免多线程或异步处理时出问题,要让逻辑上用户重复操作时也是正确的。
      • 如果使用了block或disable的功能,那么主要要在异步操作的回调中把按钮等元素的状态切换回去,否则如果放在异步回调外面,就有可能操作还没完成就先把按钮等元素的状态切换回去了,因为是异步的。比如在ajax请求处理完成的success或者error回调函数中,去重新enable按钮或者取消结果元素的block。
  • 其他专题
    • CDN
      • 使用外部库时,如果官方提供了相关地区CDN地址,最好使用CDN提高静态文件访问速度。
      • 对于大型企业对外网站,也可以找运营商购买CDN服务,使用自己的CDN地址。
      • 通常CDN供应商会提供CDN上传和维护静态文件的方式,如接口、站点
    • 使用第三方组件
      • 注意license
      • 尽量指定版本。如果像在AngularJS项目的package.json中使用^(使用该大版本下的最新版本)等通配符指定组件的版本的话,无法保证每个开发人员(尤其新机器)编译时使用的第三方库的版本一致。
    • loading效果
      • 想好页面上需要几个loading效果,哪些操作对应哪个loading效果,哪些loading效果需要block哪些用户操作(还是仅仅disable一些元素就行了?)
      • 想好页面上需要每个loading效果的作用范围
      • 想好页面上需要每个loading效果的触发/开始和结束时机
        • 每次触发/开始一定要有对应的结束,避免用户无法继续操作,或者会以为一直在加载
        • 触发/开始和结束时机,尽量符合事实逻辑(真的开始才显示loading,可能还要小心如果有一些第三方组件比较早开始加载,那么也要算上,可以在一开始就开始loading),要准确。
      • 如果一些操作会共用某个loading效果,并且是异步的有可能同时发生,而且只用了同一个变量来标识loading效果的开始和结束,一定要小心loading的开始、结束会互相影响,多测试!如果函数有上下级调用,注意if的各个分支(比如else分支里别忘了关掉loading效果),注意如果上级标识开始,那么下级只需要在所有分支去合理标识结束即可!
      • 考虑发生异常时,除了正常的异常处理外,是否还需要关掉loading效果。

posted on 2019-07-23 08:53  碎羽love星谊  阅读(827)  评论(0编辑  收藏  举报

导航