1,不理清楚业务逻辑,判断乱用
举个栗子,有代码如下:
if (d.Status === 'Created') {
if (d.isEdit === 'Y') {
xx.displayName = '草稿';
} else if (d.isEdit === 'N') {
xx.displayName = '草稿';
}
} else {
xx.displayName = '已提交';
}
且不说是否真的有关于isEdit的判断(经确认,该字段就Y和N两种值,不可能出现null或者空字符串),就算有,那也该找相关人员做进一步的确认,因为上述判断属于无效且浪费资源的代码,并且还有增加运维工作量(需要梳理和确认相关业务逻辑)和被误改的风险;
所以,上述教训是,如果一个业务逻辑需要大量的if判断,那么大量的if判断应该是以捋清楚业务逻辑为前提和目的,实际提交代码应该是完全理清业务逻辑的基础上经过完善的代码,而非类似上述代码。
同时,如果一个业务逻辑需要大量的if判断,不管能否精简(也即是相关判断整合),都应该注释相关的业务逻辑(大致描述下即可)和关于该段代码的思考(这段很重要,因为经过整合的业务逻辑有时候会很绕,这有助于运维快速定位问题,也会减少后续迭代或维护过程中对代码的误改风险);
2,页面加载不加loading
其实,在网络情况不好的情况下(这种情况很常见,考虑到用户基数,基本上等于一定出现)页面加载会很慢,此时,加loading的目的是:
2.1,一方面是告诉用户,操作已生效,当前处于加载阶段,使其不用太过着急;
2.2,另一方面限制用户进行误操作,例如多页签页面,一个页面本来就没加载完成,结果用户还可以在加载期间切换页签触发新的请求,结果就很可能是用户觉得:这应用,加载不出来了,还一点反应都没有,这是我机子的问题,还是这个应用的问题?增加用户的焦虑,不仅仅是体验不友好的问题,还会增加与用户沟通的难度(人在生气的情况下很难沟通的)
3,状态维护在本页面内
这其实是个需要斟酌的问题,关键点在于该状态在切换页面后再返回的时候,还需不需要原状态?
如果需要在返回时,维持原状态的话,需要考虑如何缓存的问题;基于Vue的开发一般会在路由配置文件router.js里配置keep-alive进行页面级缓存,该方案在大部分情况下是可行的(只是需要了解页面缓存之后,生命周期的变化,比较推荐的是BeforeRouteEnter和Be...Leave这两个路由钩子)
上述之所以说大部分情况下,是因为微信内置浏览器内核对于keep-alive的缓存好像有问题,例如本人最近碰到的一个情况:一个列表页面有3个页签,其中两个有按钮,剩下一个没按钮(解释下,有按钮代表有详情页,没按钮代表没详情页);此时查看中间页签列表的详情页后,点击微信下方的返回按钮(微信不知道哪一次更新后,在页面下方放了两个按钮,一个左箭头代表回退,一个右箭头代表前进)回退到列表页时,页签倒是正常显示在了第二个页签,只是按钮没了。。。???
所以,上述教训是:自己写的代码,需要去看一下效果,一旦方案不兼容,就需要斟酌一下优化的方式(例如本例中,考虑将状态保存在vuex中,通过computed读取数据的方式)
4,胡乱开启监听
这个问题出现的场景是在Vue中的watch事件定义中(但其实,该现象放之其他框架也是一样的道理)
言归正传,有个需求,需要把页面内的搜索框优化一下,改成实时查询,即我输入什么,马上查询,不再需要点一下搜索按钮才开始查询;
然后灵魂操作开始了:1,首先在data里定义一个变量,跟输入框绑定;2,然后在watch里监听该变量,触发查询函数;
其实上述操作倒也不是不行,毕竟我有时候也会给输入框绑定一个@Input事件;但好歹加个防抖/节流处理呀,限制一下查询频率。(讲真,这也是http1.1优化了1.0时期的一个请求只能使用一条连接,不然这么频繁而大量的请求,光是tcp三次握手和四次挥手就足以卡死了,都等不到响应返回~)
然后说说我的考虑吧:用户之所以有这个需求,大致上应该是因为懒得频繁点击搜索按钮;但事实上,用户也不可能真的要求每输入一个字符就查一次,所以基于这个考虑,大致上我们是可以考虑限制查询频率的;那么除了上述的防抖/节流限制查询频率,也可以考虑使用失焦函数(即Blur),在失焦的时候(一般是用户点击完成,关闭软键盘的时候;PC端的话一般是用户点击非输入框区域即可失焦)才进行查询操作;
当然,在不考虑需要进行其他操作的前提下(例如查询之前或之后保存当前的查询关键字,然后每次搜索的时候展示关键字列表等逻辑),考虑到用户体验友好性,加了限制的Input事件(或者上述提到的watch监控,实际上Input也是利用监听机制)体验感会更好一点。
5,代码封装的可行性与必要性
一般而言,从组件化的思路来看,组件化一般服务于代码复用的场景;这就涉及一个复杂而尴尬的问题:如果多个页面叫代码复用的话,那这个多是从数字几开始算的呢?2?还是3?还是更大的数字?
就我个人的理解,如果是大的项目,可以在一开始就约定好;如果是小的项目,在保证文件顺序一目了然的情况下(我的意思是,复用性很小的组件就尽量不要丢到components目录了),可以抛开上述多的限制(原因是,基本上后来人总会因为各种各样的原因,例如思维方式不一样,或者接受到的知识体系不尽相同,而对前人的代码产生各种嫌弃。那我的想法是,做好当前阶段的事情,该注释注释,该封装封装。)
以下具体解释下上述文字:
1)注释的必要性:我在第一点已经说明了
2)封装的必要性:
一来,代码封装到一个整体的块或者文件中,相关的状态变量和函数一目了然,大大减少了后来者梳理相关流程时(如果他需要修改或优化该处的逻辑时),来回查找相关函数或变量的工作量;
二来,大大减少被误修改的风险,功能相对简单的页面还好说,颇为复杂的页面(一般PC端很常见,因为页面宽度足够,各种表格,各种页签,还穿插判断)的情况下,大量代码交叉在一块,就很要亲命了!此时,如果没有进行代码拆分相关的工作,后期迭代或运维过程中,巨量增加梳理工作量的同时,误修改的情况发生也是不足为奇的。
3)封装的可行性:适度为准,不太建议从走极端跑到右极端(即我觉得啥都可以封装一下,一个页面出现十来个子组件)的情况。
4)封装的时机:
4.1),肯定是该逻辑复用性很强咯,基本上大部分页面都会用到;
4.2),相关逻辑复用性不那么强(例如,只有那么一两个页面用到),那就要考虑页面体量复不复杂,以及该段逻辑复不复杂:
a)考虑封装的情况有该段逻辑复杂,而且代码量在适中以上(比如涵盖5~6个方法,十几个变量);
b)不考虑封装的情况有:该段逻辑不复杂,或者逻辑复杂的情况下,页面体量不大(或者干脆就是个展示型页面);
5)以上论述及建议仅供参考,切不可生搬硬套,一切以代码健壮性,以及减轻迭代和运维工作为前提。
6,this暂存变量多种定义
6.1,为什么要暂存this对象:
简单来说,就是this指针会在调用的过程中发生改变,
可以参考:https://www.cnblogs.com/lovellll/p/10225272.html
6.2,暂存乱象:
维护过一个“历史悠久”的项目就会发现,关于this对象暂存对象的变量定义可谓是千奇百怪,比如:
const _this = this;
const _that = this;
const vm = this;
...
其实,变量名取什么是开发者个人的自由,但从代码规范的角度,以及代码健壮性和可维护性来说,统一的变量名更优雅~
此处建议:
1)如果项目从头到尾是一个人开发的,那么最好从一开始就约束该暂存变量名的声明,即开始的时候声明为_this,那么直到项目结束都用这个_this来暂存this对象;
2)如果是中途接手的别人的运维项目,那么在开发过程中,仔细留意下已有的代码里,关于this对象暂存的变量声明,后续维护和迭代过程中,继续沿用已经约束好的变量声明;
鸣谢:
网友评论