前端最佳实践

前端最佳实践

项目怎么都能写,但是如何写的优雅?如何省时省力?如何构建大型项目,而不乱?需要总结一些最佳实践~

核心问题

  • 如何进行组件的划分
  • 组件如何方便的获取(后端)数据
  • 组件如何方便的修改(后端)数据

封装的目的是什么?

  • 包装复杂逻辑
  • 提供简单接口
  • 方便调用
  • 简化开发
  • 少写代码
  • 功能统一
  • 样式统一
  • 代码风格统一
  • 代码生成
  • 可维护性
  • 扩展性
  • 健壮性
  • 可读性

前端目录结构组织

前提要划分好需求的各个模块,基于模块/功能点对应的建立models/services,否则大型项目,需求越来越多,最终会导致models/services混乱,models命名与其包含的内容不符等问题尽量避免;

如下为src中的目录

components

通用业务组件

models

数据层,与后端交互,为组件提供数据;

services

主要进行一些ajax请求,供models层调用,获取后端数据;
是否可以考虑与models层合并?

pages

页面,只有pages中的文件与redux连接?;
接受models层数据,组合components完成用户交互、数据展示等;

layouts

布局,提供整体的结构,头部底部等通用布局组件;

避免组件频繁渲染

如果一个复杂的页面,组件A嵌套的层次比较深,任何父级组件的重新渲染,都会导致A组件的重新渲染,通过shouldComponentUpdate周期函数,进行优化,避免没有必要的重复渲染;考虑是否使用immutable-js

基础数据放入redux

基础数据,其他业务页面会经常用到,简化获取基础数据方式,有利于各个业务页面获取/使用基础数据;特殊业务的请求是否可以考虑再业务组件中直接发起?不必经过redux?

比如客户数据,提供getCustomer action,用来获取客户数据,如果某个业务组件用到客户数据,直接从redux中获取;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
export function mapStateToProps(state){
return {
customers: state.customer.dataSource,
customersLoading:: state.customer.loading,
};
}
...
componentWillMount(){
const {
$actions: {customer},
} = this.props;

customer.getCustomer();
}

render(){
const {
customers,
customersLoading,
otherLoading,
} = this.props;

if(customerLoading || otherLoading) {
// show loading...
}
}
...

提供filter工具

提供filter工具,用来转换数据显示,比如id转换成对应的label,用于页面显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// filter.js

export function filterGender(gender) {
const genders = {
male: '男',
female: '女',
m: '男',
f: '女',
M: '男',
F: '女',
};

return genders[gender] || '未知';
}

复杂页面拆分

部分页面会很复杂,如果所有内容都写到一个文件,将增加修改/维护难度;

可以基于页面结构/功能点,合理的将页面拆分成各个小组件,适当的使用redux进行数据管理;

通用业务组件抽离

通用的业务组件抽离到components目录中

构建自动化

前端构建过程要自动化,基本通过几个命令搞定,核心命令有如下几个:

1
2
3
4
5
6
7
8
9
10
11
// 安装所有依赖
$ yarn

// 启动开发模式
$ yarn start 或 yarn dev

// 生产构建
$ yarn build

// 测试
$ yarn test

ajax封装

只关心请求,成功提示、异常提示要自动化,简单配置就OK;

1
ajax.put('/user/123', params, {successTip: '保存成功!', errorTip: '保存失败!'});

函数/组件编写原则

  • 可用

    编写一个函数/组件最核心也是最低的要求,要达到可用;

  • 健壮

    最基本的兼容性处理、边界处理、异常处理、用户输入校验;

  • 可靠

    尽可能在任何情况下,都返回一个可靠的结果,哪怕是异常情况下;

  • 宽容

    对需求宽容、对用户宽容、对调用者宽容、对维护者宽容;如果函数需要的是数字,调用者传入的是字符串数字是否允许等;

  • 精益求精

    可读性、扩展性是否良好?性能怎么样?

大型项目

做大型项目时,一定要组织好基础业务组件,很多模块都会用到的组件,维护好了,可以省很多事儿;

认证

单页面应用,一般会涉及跨域问题,cookie有时候不是很适合,最好使用tooken方式,适用面更广,但是浏览器与App不同,要做好安全性方面的工作。团队中有多个项目,最好统一认证方式,可以减少工作量,降低沟通成本;