前端开发手册

2,272 阅读29分钟

前言

前几年在掘金就是个伸手党,白嫖了许多现成的解决方案。忽然觉得也得为社区做点贡献。现就日常开发中,积累的一些实用代码开发规范,分享给掘友们,希望降低你们成长道路上的试错成本,加速你们的精进速度,缩短你们成为大牛的时间。

Git篇

  • 发起合并代码请求前,一定要完整阅读 3 遍自己的代码,避免不规范的写法和无意义的改动。

  • 不要把有冲突的文件,提交到代码库。

image.png

  • 每天18:00之前向开发分支提交一次代码合并请求,第二天中午之前,把前一天的代码评审问题修改完。

  • 分支分为个性分支feature, 开发分支 dev, 发版分支 release,主干分支 master, 每次开发新功能时,基于master切一个特性分支,开发调试使用dev分支,提测与部署使用release分支,部署之后观察一两天,待release分支稳定后合并到master分支。。

  • git特性分支的命名规范 feature/YYYYDDMM-功能说明-开发者,YYYYDDMM是发版日期。如feature/20221028-data-board-xxx,release分支的命名规范是release/YYYYDDMM。

  • 每次向release分支推送代码时要更新一下master上的代码。

  • 自己的feature分支只能更新maser分支的代码,禁止把与本次迭代无关的功能合并到自己的feature特性分支。

  • 向部署分支推送代码出现冲突时,新建一个解决冲突的临时分支,在这个分支上解决完冲突之后,用这个分支发送代码合并请求到部署分支。

  • 要求打开git文件命名大小写敏感功能。git config core.ignorecase false

  • 如果预判到会与别的伙伴代码产生冲突,推荐指定一个人去修改公共文件。

  • 按照commitlint日志分类规范书写提交代码功能说明,commit 信息可参考《约定式提交》文档

  • 向远程仓库提交代码前,要检查开发时设置的调试逻辑与语句,是否删除。

  • 提交代码的时候,一定对照编码规范,预先检查一下自己的代码,看看是否意外修改了不应该修改的地方。

反例: 意外篡改了公共配置文件关键信息

image.png

通用篇

  • 从同一个工具库的导出,不要写多行。
// bad
import React from 'react';
import { lazy } from 'react';
// good
import React, {lazy} from 'react';
  • 提交代码时要对代码格式化,不能有对齐问题。

image.png

  • 提交的代码不能有单词拼写警告,ts警告,less警告,提交到git的代码别人拉取下来之后运行时不能报错。 浏览器控制台不能有警告。

反例: 单词拼写错误

image.png

image.png

  • 样式,js方法,vue的template视图,不能有大片重复,对重复的代码要进行合并。

  • 对于非常规业务逻辑,复杂的代码片段,一定要写注释,总体注释率不能低于10%。

  • 原则上单个文件的行数尽量控制在500行以内,单个方法的行数控制在80行以内,超过就要进行拆分。

反例:单个文件多达1239行。

image.png

  • 当期开发的需求如果用到历史业务功能, 对于历史业务技术债务,如功能实现过程不合理,变量+方法词不达意,代码重复率过高,复杂逻辑缺少注释,样式冗余重复, 要进行重构优化。

  • 有复用价值的代码要记录下来,整理一个现有功能速查文档,记录譬如说轮播图,EChart各种图表配置,移动端滚动加载更多,文件上传与导出功能代码在项目中的路径,需要用到的时候可以高效找到。

  • 不用使用过新或即将被淘汰的语法,避免引起兼容性问题或控制台输出大片的警告

  • 命名要准确,要有意义

比如说,下面的k是什么含义

image.png

比如说审核应该是audit或者Review,怎么能翻译成watch

image.png

比如说样式名称是color,属性却和color没有任何关系

image.png

  • 初始化数据,初始化操作的话,建议以initXXX开头命名变量和方法名。
  • 文件路径原则上使用别名路径,相对路径可读性较差。

反例:

image.png

  • 重复的内容要合并, 反例:

image.png

image.png

  • 互斥的判断条件要正确的定义 如下: 应该写成if-else if

image.png

框架篇

  • 嵌套循环,不要使用相同的迭代变量名称,以免引起混淆。

image.png

  • 不要把常量值定义成变量 image.png

    image.png

  • 有关联的变量要用reactive而不是ref定义

image.png

  • vue中的子组件,dom元素,定义组件的ref属性时,加上Ref后缀。普通的ref变量,禁止加ref后缀
// count变量命名禁止加ref后缀
const count=ref(1);

// 组件或dom元素命名要加Ref后缀
const newsEditRef=ref();
<NewsEdit ref="newsEditRef" />
  • 不要出现无意义的代码
    this.socket.onmessage = (data: any) => {
      const message = JSON.parse(data.data || '{}');
      // bad
      if (message.type === 'pong') {
      } else {
        this.onMsg(message);
      }
    };
  • vue 组件props定义推荐使用vue3的写法
const props=withDefaults(
  defineProps<{
     visible: boolean;
     data?: object;
 }>(),
 {
     visible:false,
     data:()=>{}
  }
)

而不是这种写法

const props=defineProps({
     visible: {
          type: Boolean;
          default: false;
      },
     progressDetail: {
      type: Object,
        default: function () {
          return {};
        },
      },
})
  • 路由名称要与页面名称一致,方便查找。

  • v-for中的key原则上不能取index,用别的值作为唯一标识 image.png

  • defineEmits建议使用如下方式定义 image.png 而不是 image.png

  • 不要在文件中导入defineProps、defineEmits、defineExpose、withDefaults,这四个全局编译器宏可以直接使用。

  • 元素的动态属性,重要属性写在前面,静态属性写在后面,其中v-if/v-show/v-for这类属性的优先级最高。普通的动态属性安装从短到长的顺序排列 image.png

  • vue中导入的文件,将vue的api方法和UI库的导入放在最前面,其次是自定义的UI组件,接着是类库,方法名,最后是类型定义。示例:

image.png

  • 把较复杂,最容易改动的方法放在文件前面定义 。

  • 把有关联的变量,函数集中写在一起。

  • 多个文件用到的常量要集中管理,收归到一处。

  • props,reactive定义的每个属性都要写注释 image.png

  • 父子组件嵌套不超过3层。超过三层的话不建议再抽取组件。

  • 推荐用容器+组件组织方式,开发页面。父子组件,子组件之间的通信都放在父组件中处理。

image.png

  • vue3编程风格采用setup语法糖写法。

  • template部分,v-if表达式语句过长时,要将冗长的判断表达式写成computed变量。

  • vue中引入外部样式的推荐写法

// bad
<style lang='less' scoped>
  @import "@feature-customer/views/client-info/index.module.less'
</style>

// good
<style lang='less' scoped src="@feature-customer/views/client-info/index.module.less' > </style> 

JS篇

  • 按照一些简写技巧书写代码。参见:

20个提升效率的JS简写技巧

你不知道的十个 JS 小技巧

几个一看就会的实用JavaScript优雅小技巧

  • window对象,书写的时候可以省掉window.索引

正常:

  const shareChannels = getQueryString(window.location.search, 'shareChannels');

优化:

    const shareChannels = getQueryString(location.search, 'shareChannels');
  • 只会在一个地方使用的常量,不必提取到公共常量文件

反例: 把只会在一个地方使用的常量,提取到src/common/constants.ts中,这段代码,放到使用的业务文件里面就行了,阅读与查找起来更方便

export const taskContentMap: TLooseStrObj = {
  '090101':
    '首次“一对一专属理财经理”自我介绍;告知客户服务升级(贵宾客户专属产品及服务权益体系升级亮点);邀请添加客户企业微信;邀约与客户首次面访时间',
  '090102': '新增邀约',
  '090103':
    '根据场景自我介绍一对一专属贵宾理财经理;介绍我行客户分层经营的模式;递交统一制作的贵宾服务手册,并介绍贵宾专属服务及权益;客户需求进一步理解、深挖、把握客户期望',
  '090104': '客户是否已领取当月贵宾权益',
  '090105': '客户风评等级',
  '090106':
    '掌握客户持仓情况及资配需求; 配合客户目前资产情况及资配需求进行邀约切入;新增邀约(点击跳转新增邀约页面):沟通目的-产品销售类+活动邀约',
  '090107': '投资理财热点海报推送;了解客户投资理财目的及收益目标;了解客户现有持仓,生成财富诊断报告或资配建议书',
  '090108': '可结合热点资讯向该客户推送海报',
};
  • 可以优化的if判断语句
    const launchBtn = document.getElementById('launch-btn');
    // bad
    if(launchBtn){
      launchBtn.removeEventListener('launch', handleLaunch);
    }
    // good
    launchBtn?.removeEventListener('launch', handleLaunch);  
  • 调试通过的日志要注释掉

反例:

image.png

  • 蹩脚的判断逻辑,实际上等同于handleAuditType === 'details'

image.png

  • 条件判断中含有数字代码,要给数字代号去个有意义的值

反例:

image.png

正例:

// 身份证的反面
} else if (no == Cert.reverse) {
  • 函数里面新建的变量一律用const修饰。

反例:

image.png

  • 比较是否相等,原则上用恒等 ===。

反例:

image.png

  • 接口请求和响应数据, 不需要打印。可以直接在网络请求面板查看。
  • 函数有参数的话,注释要写成多行注释。没有参数的,注释 可以 写一行,不然样板代码太多。

反例:

image.png

正例: 对于变量的注释,推荐上下结构。

image.png

  • 如果只有一个接口请求的话,不建议用async/await try...catch, finally功能不如Promise原生方法优雅。

image.png

  • 减少!, !== 等反向判断的使用,多采用正向判断,不用在大脑中拐弯。如这里的 useList.length !== 0 可以修改为useList.length。 image.png

  • 拿到需求文档后,先不着急写业务逻辑,先考虑一下如何拆分组件,提取有复用价值的组件。

  • 函数要按照自顶向下的顺序书写。聚合函数写在上面,调用函数依序写在下面。

  • 函数的结构本质上要短小、以不容纳if/else if/else嵌套结构为目标。多了就拆分

  • 函数方法的参数最多不要多于2个,多于两个时以对象的方式传参

  • 函数内部不要做出出乎预期的改动,不要对外部产生影响

  • 条件判断,循环嵌套不能超过三层。就要进行拆解

  • 三目表达式不能嵌套

  • 对容易混淆的变量,要有鲜明的区分。如list--表示从接口查询出来的列表值, showList--表示显示使用的列表值

  • 调试通过之后,要注释打印语句,提测阶段的代码原则上不能有日志打印。

  • 触发显示/隐藏,动态添加移除类的方法,用toggleXXX开头 image.png

  • 查询接口数据的方法,以queryXXX开头,不要用get开头,因为许多接口也是用get开头,以示区分。

image.png

image.png

  • 不要用data这种太宽泛的命名,对变量名命名要具体

image.png

  • 命名要统一,方法名用小驼峰,样式名用烤串风格, 反例:

image.png image.png

  • 命名要有意义,不能出现数字排序,字母排序这样的命名。

  • 对枚举值要有解释说明,不要直接写与数字判断比较的逻辑

image.png

image.png

  • 大的实例对象,定时器要在页面销毁或不用的时候及时清除。

  • 如果只用到一个库的两个功能,如loash或jQuery库的个别功能,可以考虑将常用库的方法抽取出来,如lodash的cloneDeep,isEqual ,减少打包体积。

  • 提交代码的时候,如果导出的内容在文件中只有一处,要删除无用导出

  • 数组清零用arr.length=0比arr=[] 效率更高

  • 不要写一些看起来很古怪的代码,比如下面的在循环中不断覆盖一个变量的值,把自身展开赋值给自己。

image.png

TS篇

  • 方法参数,每个属性类型要明确,不能滥用any定义
const handleShowAuditModal=(record:any)=>{}
  • 消除别人写的文件中的ts警告,不要修改原来的判断条件和业务逻辑。

  • 禁止使用as never断言,要定义成具体的类型。如下 将tagsGroupData.tags定义成{id:string;name:string;}[]即可

image.png

  • 每个业务模块用到的ts类型声明,都集中放在一个文件中,取名为module.d.ts
  • 即便是改别人的代码,对于一些显而易见的数据类型,不能用any定义

image.png

  • 自定义的类型,类型中的每个静态属性,都要写注释。

反例:

image.png

  • 用type关键字定义的类型,命名时以TXX开头,用interface命令的类型,以IXX开头。

image.png image.png

  • 子组件props的任何一种属性,不能用any定义

反例:

type IProps={
  detail:anyinfo:any;
}
  • 三方库的事件入参类型,要从对应的库文件中导出来,原则上不能用any

  • 接口的类型,引入ytt生成的接口文档,(如果yapi上的接口类型定义不正确,可以在yapi上编辑修改之后,重新生成)

image.png

微信小程序篇

  • 开发小程序之前,先参照微信小程序开发配置指南, 对微信开发者工具进行配置。

  • 页面底部有内容时,别忘记添加安全底部样式

// 正常文档流底部安全距离
.safe-bottom-area {
  /*兼容 IOS<11.2*/
  padding-bottom: calc(constant(safe-area-inset-bottom) + 16rpx);
  /*兼容 IOS>11.2*/
  padding-bottom: calc(env(safe-area-inset-bottom) + 16rpx);
}

// 固定定位的底部安全距离
.safe-bottom-area-fixed {
  /*兼容 IOS<11.2*/
  bottom: calc(constant(safe-area-inset-bottom) + 16rpx);
  /*兼容 IOS>11.2*/
  bottom: calc(env(safe-area-inset-bottom) + 16rpx);
}
  • 事件优先用catchtap而不是bindtap,catch事件绑定可以阻止冒泡事件向上冒泡
<view class="right" catchtap="handleJump" data-page="{{leftText}}">{{ rightText }}
    <van-icon name="arrow" />
  </view>
  • 用表单组件配置数据生成表单,表单配置数据优先用对象定义而不是数组,对象也能用wx:for 遍历,查找效率更高。
formConfig: {
       borrowerName: {
         type: 'text',
         label: '借款人姓名',
         value: '',
         errMsg: '',
         reg: 'name',
         validator: (context: TLooseObj) => baseValidator(context, 'formConfig', 'borrowerName')
       },
    ...
}

 <view wx:for="{{formConfig}}" wx:key="key" wx:for-index="key">
  • 对于表单配置项,要把能固定的都固定下来,保留真正需要动态配置的项。

反例, 如下是否在表单行右侧显示选择箭头的参数showRightIcon,就是可以确定的常量。text类型肯定不需要,select,date类型肯定需要。所以这个参数不是必需的,可以删除掉。

formConfig: {
     borrowerName: {
       type: 'text',
       label: '借款人姓名',
       value: '',
       errMsg: '',
       reg: 'name',
       showRightIcon: false,
       validator: (context: TLooseObj) => baseValidator(context, 'formConfig', 'borrowerName')
     },
  ...
}
  • 仅仅进行显隐判断,标签要用block而不是view, 不会产生额外的dom元素,渲染性能更好
<block wx:if="{{show}}">
  <text>这里不会产生额外的包裹层</text>
  <text>但这里仍然需要 block 以控制多个元素</text>
</block>

  • 工具方法的导入,要统一入口

反例:

import { getPickerOptions,findOptionIndex } from '../../utils/options';
import { emptyValidator } from '../../utils/index';

正例:

import { getPickerOptions,findOptionIndex,emptyValidator } from '../../utils/index';
  • 业务方法定义的顺序,业务方法不能写在所有系统方法之后,查找时不好找,onLoad 方法是每个页面几乎都会用到的,其它的系统方法不一定用到,为了便于查找,要求把自定义业务方法写在用到的系统方法之后。

反例: image.png

正例:

image.png

  • 一个标签上不能同时出现wx:if 和wx:for

CSS篇

在vue文件中引入外部样式文件推荐的写法是:

// bad
<style lang='less' scoped>
  @import "@feature-customer/views/client-info/index.module.less'
</style>

// good
<style lang='less' scoped src="@feature-customer/views/client-info/index.module.less' > </style> 
  • 不推荐使用styled-components写样式,因为生成的样式名称含有hash串,语义不清, 调试页面元素时定位查找不太方便

image.png

  • 不推荐使用scss预编译语言,scss不同版本语法不太一样,使用最新版scss时,控制台会输出许多过时语法警告。而less无此问题。

image.png

  • 不要滥用flex布局 经常发现布局时,许多地方定义的flex相关属性,去除之后,页面并没有丝毫受到影响,此外,flex属性用多了,开发的移动端页面,在个别机型上比如说三星,IOS12,华为手机上,出现各种兼容性问题。
  • 条件样式写法可以优化

正常写法:

<view class="house-info-body {{selected[index] ? '' : 'hidden'}}">

优化写法

<view class="house-info-body {{selected[index] && 'hidden'}}">
  • 样式名能简写的单词要简写。

反例:certification可以简写成cert

image.png

  • 样式名不能出现数字,字母序号,要有意义。

反例:

image.png

  • 属性值可以简写的要简写

反例:

image.png

  • 动画元素要使用绝对定位。

  • 图片要设置width和height。

  • 选择器原则上不能用id,影响复用性。如果用了id,不要在id选择器前面嵌套其它选择器,纯粹是多余的。

此外id的定义只能出现在当前页面, 不允许把id样式写到外部的css文件中。

  • 利用继承减少代码量,比如color,cursor, letter-spacing, line-height, white-space,word-spacing,font-xxx等等,很多人不注意这个细节,编写很多冗余代码。

  • 通配符选择器尽量少用

  • 能使用background-color, 就尽量不要使用background,防止原有别的样式属性被覆盖。

  • 属性值为0时,不加单位,零始终是零,添加维度不会为包含的信息附带任何价值。

  • 页面中有全局样式定义的,新起一个style标签, 全局样式写在最前面

image.png

  • 有父子关系的,优先使用父子选择器,减少后代选择器的使用

image.png

  • 采用组块命名,一个组块不要超过三级(超过之后重新定义新的组块) image.png

  • 样式名用横杠连接,全部小写

  • 颜色值统一用小写值。

反例:

image.png

  • 不允许出现重复的属性值

image.png

  • 要选择恰当的选择器,不要太宽泛。

反例:

.render-item ~ .render-item

正例:改成兄弟选择器

.render-item + .render-item

HTML篇

  • 不为人知的 HTML 技巧

  • 避免使用table,因为一个很小的改动会造成整个table重新布局,用div仿table效果

  • input 的placeholder不要写请输入xxx, 建议直接写出校验规则,如必须输入数字,大小写英文字母中的两种。

  • 如果不包含子元素,推荐标签自闭合。 image.png

  • 优先使用语义化标签,比如说列表行,用li而不要用div,容器用section而不是div, 固定在底部的tab用footer而不是div

  • 减少无意义的div嵌套。如实现复选框选中效果

image.png

这是vue优化之后的实现 image.png 这是原来react的实现 image.png

image.png

npm包管理规范

  • node的版本推荐采用 v22.14.0
  • node版本管理工具推荐采用nvm
  • npm下载镜像地址建议采用nrm管理
  • npm工具包统一采用pnpm安装
  • 安装npm工具包时, 精确指定安装的版本号,删除版本号前面的^或~

image.png

  • 区分运行和生产依赖:运行依赖安装时加-D放在package.json的  "devDependencies"字段下面
  • 尽量减少引入npm工具包的体积,如果只用到某一个体积较大的工具包的某个方法,推荐的做法是把用到的方法的代码片段抽取出来,添加到项目中,而不是全量引入,或者引入这个包的esm版本(如lodash存在lodash和lodash-es两个版本, 要使用lodash-es版本。
  • 有些第三方工具包不支持pnpm安装。只能用script标签引入这类第三方包,要求只能引入用于生产环境的压缩版本。

IDE篇

IDE统一用 VSCode

必装扩展:Code Spell Checker + Stylelint + ESLint + Vue-Offical + Prettier-Code formatter + GitLens

推荐安装:Tabnine AI + javascript console utils + AutoCloseTag + Auto Rename Tag + indent-rainbow + Vue VSCode Snippets +

Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code

注意:vetur插件不兼容vue3的语法,如果安装了的话,要卸载掉。

技术栈篇

构建工具: Nx-WorkSpace+ Vite3 + Pnpm + DotEnv

开发框架: TypeScript + Vue3 + Vue-Router4 + Pinia + Less +Axios

UI库: PC端--AntDesignVue3 移动端--Vant3

移动端调试工具: vConsole

微信小程序: 用的是微信开发者工具,使用微信小程序原生语言开发

评审篇

  • 提前熟悉需求文档,找出自己看不懂或者有疑惑的地方,开会时有针对性的提问。

  • 评审需求也是一个暴露风险的过程,对于技术实现有难度的地方,要及时反馈并调研可行性。

  • 要把需求吃透,先在大脑中,把需求做一遍,对交互逻辑,业务逻辑,UI展示效果细节有疑惑的地方,要当场反馈。

  • 评审需求时一定要多想多问,尤其是异常情况

  • 一场评审,问不出三个问题,就是欠缺思考的表现

  • 听需求评审时,要从易用性,实用性的角度,对UI设计,业务逻辑不合理的地方提出质疑,并给出合理建议。

  • 相似的业务,要充分复用已有的功能。说服产品使用现有的成熟方案,不要重新设计UI和交互效果,业务流程。

UI篇

  • 与产品协商某些设计效果需要修改时,要让产品及时推动UI改设计稿,尤其是外部项目,免得到时测试拿设计稿效果怼开发。

  • UI经常遗忘异常流的设计稿, 要重点检查UI提供的设计稿有没有空数据页面,包括列表页和搜索页空状态页面,错误状态页面设计稿。

  • 要检查UI设计稿画出的效果生成的样式代码,是不是与设计效果一致,经常出现背景渐变和纹理效果的生成样式代码与实际效果相差甚远。

  • 要检查UI设计稿的基准尺寸是否正确。有时UI变换设计稿的基准,导致开发把页面都快写完一大半了,发现尺寸不对。

  • 要检查UI设计稿的数量是否与需求文档要求做的内容数量一致,有无缺漏

  • 要检查设计稿上的元素是否可以正常抓取。有时候UI提供的设计稿,有些页面的布局,样式抓取不到

  • 要检查切图是否规范。有时候UI切的图片,图片并不是在图片背景的正中央,上下左右不对称

  • 要检查图片和文字是否分离。有时候UI不分离按钮上的文字和背景图, 影响按钮背景图的通用性

  • 要检查样式属性值是否正确。有时候UI会混淆一些属性值。如背景色透明度和整个区块的透明度相混淆

  • 拿到UI设计稿之后,先不用着急写样式,先思考如何布局,哪些样式可以复用。

UE篇

  • 图表纵轴以人为单位的,不能出现小数。

image.png

  • 跳转到表单类页面,要用router.replace而不是router.push,防止操作成功后,点击浏览器的返回,还能返回到表单编辑页面。

image.png

  • 表单错误信息应该在表单项下方展示,原则上不能使用弹窗,弹窗一般是给接口报错用的 image.png

  • UI的设计稿经常前后不一致,对于这种情况,要及时指出。如下图所示, 边距风格不一致。

  • 开发时间比较紧张的情况下, 当UI设计某些效果与UI库不一致时, 可向UI设计师或产品经理建议,改成所使用UI库的风格。

  • 有些交互设计流程不合理。如下面的流程,必须把多账户列表数据传递到下一页面,而数组跨页面传递用本地存储或url参数都不优雅, 而在每个页面都调用查询用户列表数据接口,增加服务器带宽压力。更好的做法是,在当前页面弹窗,展示多账户列表数据,让用户选择要认证的客户后提交表单,省却了跨页面传递数据的繁冗操作。

1677897758966.png

  • 表单项上下要对齐

企业微信截图_16824809536959.png

  • 宽度要留足,不然提示语看不全

企业微信截图_16824808682217.png 企业微信截图_16824800167417.png

接口篇

  • 前端要引导后端,定义合理的接口数据类型

至于为什么要这么做,请看下面的反例展示,excludeTags原本应该定义成一个string[], materials也应该定义成一个Item[], 而前端未告知后端,后端也没仔细看需求文档,定义接口数据类型怎么省事怎么来,把这两个字段都定义成了字符串,结果就是:

// 在编辑和详情页面,需要把字符串转成数组
formData.taskClientRule.excludeTags =
      excludeTags === '' ? [] : excludeTags?.split(',').map((item) => Number(item)) || [];
formData.materials = isValidJson(materialsStr) ? JSON.parse(materialsStr) : [];

// 在提交数据时, 又得将数组转换成字符串
params.excludeTags= formData.taskClientRule.excludeTags.join(','),
params.materialsStr = JSON.stringify(materialContent.materials || []);

不合理的数据类型设计, 既多了一些额外的转换,也增加了产生bug的概率,上例中的Number(item)isValidJson(materialsStr)都是因为自测出bug,才添加上去的。

  • 要检查一下接口文档提供的数据,是否满足页面展示要求。后端有时不看UI设计稿,返回数据缺少字段。

  • 督促后端把接口文档写得准确一些, 不然用ytt工具根据接口文档生成ts类型会出问题

  • 明确字段是string的数字还是number类型的数字

  • 明确null代表空值,还是空字符串代表空值

  • 明确日期的类型是字符串还是时间戳,如果要回显时间,尽量让后端处理成YYYY-MM-DD HH:mm:ss的格式,之前遇到过形如这样的时间格式"2023-05-23T15:28:51.000+0800",经过dayjs的format方法处理后,在移动端部分IOS机型上,显示Invalid Date.

image.png

  • 给后端建议返回的响应数据不要有冗余的嵌套

  • 给后端提议减少不必要的传参,有些参数后端可以直接获取到,如企业id,员工id,应用id

  • 要求后端减少接口冗余的数据返回,如下图所示,除了list和total字段,其余字段都是没用的。 image.png

  • 给后端建议,接口传参特别多的, 不能用get请求。

  • 有分页功能的,要让后端造点分页数据。

  • 每个接口都要写注释说明接口用途。

image.png

测试篇

  • 要检查界面是否与UI设计稿一致, 有没有走样。

  • PC端页面 列表查询表单,上下列输入框,选择框要垂直对齐,列表单元格原则上不能出现换行,字段长度固定的,比如说一些列的值是枚举值,日期,姓名,要固定列宽。

  • 弹窗内容不能溢出到屏幕之外。

  • 对历史代码进行过重构的话,要充分自测

  • 提测之前,先向测试要一下测试用例,对照测试用例检查一遍,有没有代码实现逻辑与测试用例不一致的地方。

  • 在哪个环境showcase,就在哪个环境自测,测试好了再演示。有时会出现开发环境和测试环境表现不一致的情况

  • 把每个业务正常和异常流程完整的走一遍,基本上就能消除百分之九十九的bug

  • 有非必填项,不填写的话,看看会不会显示undefined.

  • 如果提交按钮含有表单校验全部通过才可操作逻辑的,新增了表单项,要测试一下自己的修改有没有影响到表单按钮的校验禁用逻辑

  • 移动端的列表下拉刷新,要提防扩展运算符引起的重复插入问题,以及splice引起的数据丢失问题。

  • 修改组件属性,最好全局搜索一下,防止漏改。

  • 测试主要测边界,测极端情况。

  1. 比如说没有数据时,是否会展示空页面

  2. 接口报错时,是否会挂掉

  3. 文字太长时,是否会溢出容器

  4. 大小屏幕适配,是否布局错乱或者元素尺寸不协调

  • 要在手机上检查一下常见的问题,如1px问题,键盘遮挡问题, fixed定位的兼容性问题

  • 如果表单中文件上传项,要检查一下提交表单时,表单是否有如果有文件还在上传中,禁止提交的逻辑

  • 要求测试提缺陷时,附带接口返回数据,方便排查问题。

  • 协商提测时间小技巧,尽量把提测时间安排在周一,周末自己可以多点点,多看看,有无低级和阻塞流程的bug。

  • 原则上重大缺陷当天要修复,不能过夜。

工时评估篇

  • 评估工时前,要把新开发功能的业务逻辑吃透,不能模棱两可。如果发现还有盲区,问产品直到没有任何疑问时再开始评估工时。

  • 原则上PC端一个列表页0.5天,表单页1天,单纯UI修改,10页面/天,如果表单页或列表页比较复杂的话,则酌情加工时。

  • 移动端的话,原则上一屏内容1天,页面展示含有动画,或者特殊效果的话,适当延长工时。

  • 最后上报总工时的时候要在预先计算出来的总工时的基础上追加20%处理意外事情的时间。

  • 需求排期紧张的时候,没有额外的修复测试阶段问题的时间。

  • 修复常规生产问题,不单独安排工时。自己以前挖的坑自己填。

项目进度篇

  • 工作日报按条目陈述,每天的工作日报要体现出进度变化。

  • 开发过程中,注意整体时间进度的把控,先完成再完美,有风险时及时反馈。

  • 开线上会议,要及时入会,不要让团队成员久等。并提前检查好自己的麦克风,音量是否调节好,发言的时候要保证说话声音清晰。

  • 每天下班时要在参与项目所在企微项目群的群公告-前端开发排期 在线文档中填写一下进度。

  • 汇报工作,采用总分结构。先说结论,再详细展开。

  • 每天固定时间开站会/远程会议,每个人发言3分钟,讲一下昨天要做什么,今天做什么。有没有需要外部协调的事情。

  • 每天下班前,提交一次代码,项目的owner会在第二天给出代码审核意见。按照审核意见修改。

  • 需求评审完之后,要在2天内给出技术实现风险点的调研结果。

  • 在一个问题上卡了一天的话,要及时暴露风险,发挥群体智慧,攻克难题。

  • 上线不是终点。上线后的一段时间(至少一周内),一定要持续观察自己负责的功能是否正常运行

沟通篇

  • 不是一堆人凑在一起就是一个团队, 团队成员之间应该相互促进对方目标的完成,而不是袖手旁观和阻碍使绊, 遇到问题多为对方考虑一下,给对方提供一些有用的指导信息,帮助对方快速解决问题。

  • 团体对外沟通,先内部统一意见,再与外部洽谈。

  • 尽量一次性把话说明白,不要让别人追问和往复。

  • 在群里讨论排查问题,对于关键信息(比如说traceId, 出问题页面的url, staffId,不要给对方发图片,要发文字。

  • 群里@自己的消息,要及时进行回复。

  • 接到任务, 先确定好任务内容+对接人+提测上线,把目标对齐再开始干。

  • 要善于记会议记录。开会时,要对有歧义的点,需要会后确定的事项,内容太多且比较重要的点进行记录。对于代码评审,功能演示会议中提到的问题,要进行记录。会后逐条修改。

  • 就事论事只说对了一半,说话的语气也比较重要。许多人际冲突都是因为讨论具体的事情的过程中语气不当造成的,所以说话要柔和。

  • 测试或者后端给前端反馈问题,先接受问题,再细致排查。经常我们感觉是别人的问题,结果排查到最后发现是自己的问题。

  • 沟通要找对关键人,谁是直接负责人,是谁开发的, 就找谁。

  • 需要2个以上的人沟通的问题,拉一个群,不要挨个去找。如果找某个人就可以确定的事情,建议点对点精准沟通,不要在大群里讨论。

  • 有问题优先自己消化解决,原因参见前端开发手册--第二部分--关于员工培养的一份调研报告,耗时超过半天仍旧无法解决在向外寻求帮助。

  • 重点项目,每天主动向负责人反馈进度和推进过程中遇到的卡点。

  • 出差在外,与客户沟通,第一,要给对方留下我们很专业的印象。第二,要界定好职责边界。

  • 少问是什么的问题,多问为什么的问题。如果有条件的话,问别人问题之前自己先查阅一下相关知识,不要问一些在对方看来很基础很低级的问题。

文档篇

  • 文档的命名为上线时间+功能说明,文档按倒序排列, 上线时间最晚的排在第一个。

  • 每个人一个文件夹, 将自己参与过的需求迭代记录在里面。

  • 要记录的内容参见 前端开发手册--第一部分--项目需求迭代记录模板

  • 文档中篇幅较长的条目内容,建议倒序排列