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