移动Web端

通用

HTML部分

  • style放样式表里, 在头部(head)引入
  • Javascript在尾部(body结束前)引入
  • 添加必要的mate标签,利于SEO

    1. <meta name="keywords" content="">
    2. <meta name="description" content="不超过150个字符">
    3. ...
  • 尽量减少标签数量,减少不必要的嵌套

  • 结构清晰,对于流量型项目要尽量使用语义化标签
    1. <h1>标题</h1>
    2. <p>段落</p>
    3. <a>超链接</a>
    4. <ul>
    5. <li>1.有序列表</li>
    6. <li>2.有序列表</li>
    7. <li>3.有序列表</li>
    8. </ul>
    9. ...

Javascript部分

  • 变量采用驼峰命名发

    1. let doctorId = null;
  • 私有变量以”_”开头

    1. let _price = 0.00;
  • 常量全部大写

    1. const ADMIN_ROLE = 16;
  • 函数功能保证单一,减少耦合性,同时注释说明 ```javascript 单行注释 // xxxx

多行注释 /**

  • xxx
  • xxx */

函数注释 /**

  • 以星号开头,紧跟一个空格,第一行为函数说明
  • @param {类型} 参数 单独类型的参数
  • @param {[类型|类型|类型]} 参数 多种类型的参数
  • @param {类型} [可选参数] 参数 可选参数用[]包起来
  • @return {类型} 说明
  • @author 作者 创建时间 修改时间(短日期)改别人代码要留名
  • @example 举例(如果需要) */ ```

CSS部分

  • 使用css的缩写属性

    1. padding: 20px 30px;✅
    2. padding-top: 20px;padding-left: 30px;padding-right: 30px;padding-bottom:20px;❎
    3. border: 1px solid #e2e2e2;✅
    4. border-width: 1px;border-style: solid;border-color:#e2e2e2;❎
    5. ...
  • 颜色书写完全

    1. color: #ff99aa;✅
    2. color: #f9a;❎
  • 命名规范

    1. 容器: container
    2. 页头:header
    3. 内容:content/container
    4. 页面主体:main
    5. 页尾:footer
    6. 导航:nav
    7. 侧栏:sidebar
    8. 栏目:column
    9. 页面外围控制整体佈局宽度:wrapper
    10. 左右中:left right center
    11. 导航:nav
    12. 主导航:mainnav
    13. 子导航:subnav
    14. 顶导航:topnav
    15. 边导航:sidebar
    16. 左导航:leftsidebar
    17. 右导航:rightsidebar
    18. 菜单:menu
    19. 子菜单:submenu
    20. 标题: title
    21. 摘要: summary
    22. 标志:logo
    23. 广告:banner
    24. 登陆:login
    25. 登录条:loginbar
    26. 注册:register
    27. 搜索:search
    28. 功能区:shop
    29. 标题:title
    30. 加入:joinus
    31. 状态:status
    32. 按钮:btn
    33. 滚动:scroll
    34. 标籤页:tab
    35. 文章列表:list
    36. 提示信息:msg
    37. 当前的: current
    38. 小技巧:tips
    39. 图标: icon
    40. 注释:note
    41. 指南:guild
    42. 服务:service
    43. 热点:hot
    44. 新闻:news
    45. 下载:download
    46. 投票:vote
    47. 合作伙伴:partner
    48. 友情链接:link
    49. 版权:copy
    50. ...
  • 移动端适配方式

常用的适配方式有rem、vw。
vw的特点是矢量不失真,原生支持使用简单,PC端同移动端。
rem的特点是移动PC同时支持,需要针对不同尺寸平台做媒体查询。

如何选择?
当项目仅一套样式且使用在移动端上建议vw,其他情况自行选择

React项目

脚手架的选择

脚手架的选择有umi、create-react-app。
umi的特点是功能齐全,包含了路由、状态管理、现成的构建等。
create-react-app的特点是轻量,可自定义强。

如何选择?
当使用antd(蚂蚁开源)生态技术时推荐使用umi,其他时候自行选择。

umi项目目录结构

  1. ├── README.md // 项目说明、注意事项等
  2. ├── config // 项目配置
  3. └── config.ts
  4. ├── dist // build目录
  5. ├── mock // 模拟数据
  6. ├── node_modules
  7. ├── package.json
  8. ├── public
  9. └── favicon.png
  10. ├── src
  11. ├── app.ts // 入口文件
  12. ├── assets // 静态资源
  13. ├── fonts // 字体
  14. └── DIN-Bold.otf
  15. └── images // 图片
  16. ├── default
  17. ├── i_circle
  18. ├── i_login
  19. └── i_qa
  20. ├── components // 组件
  21. ├── userModal
  22. ├── userModal.less
  23. └── userModal.tsx
  24. └── videoItem
  25. ├── videoItem.less
  26. └── videoItem.tsx
  27. ├── global.less // 全局样式
  28. ├── locales // 国际化
  29. ├── models // 状态管理数据集
  30. ├── groupDisease.ts
  31. ├── groupIndexData.ts
  32. ├── pages // 页面
  33. ├── message
  34. ├── message.less
  35. └── message.tsx
  36. ├── my
  37. ├── my.less
  38. └── my.tsx
  39. └── utils // 工具箱
  40. ├── isWeichat.ts
  41. ├── request.ts
  42. ├── storage.ts
  43. ├── tools.ts
  44. └── type.d.ts
  45. ├── .umirc.ts // 配置文件
  46. ├── tsconfig.json
  47. ├── typings.d.ts
  48. └── yarn.lock

umi项目配置

  1. import { defineConfig } from 'umi';
  2. const { REACT_APP_ENV } = process.env;
  3. const proxy: any = {
  4. dev: {
  5. '/api/': {
  6. target: 'http://proxy.pule.com',
  7. changeOrigin: true,
  8. pathRewrite: { '^': '' },
  9. },
  10. },
  11. test: {
  12. '/api/': {
  13. target: 'https://yyk.pule.com',
  14. changeOrigin: true,
  15. pathRewrite: { '^': '' },
  16. },
  17. },
  18. pre: {
  19. '/api/': {
  20. target: 'your pre url',
  21. changeOrigin: true,
  22. pathRewrite: { '^': '' },
  23. },
  24. },
  25. };
  26. export default defineConfig({
  27. nodeModulesTransform: {
  28. type: 'none',
  29. },
  30. proxy: proxy[REACT_APP_ENV || 'dev'], // 依赖库: "cross-env": "^7.0.2"
  31. routes: [
  32. { path: '/test', component: '@/pages/test/test' }, // 测试页
  33. { path: '/', component: '@/pages/tabBar/tabBar' }, // tabbar
  34. { path: '/login', component: '@/pages/login/login' }, // 登录页
  35. { path: '/bindPhone', component: './bindPhone/bindPhone' }, // 绑定手机
  36. { path: '/loginCode', component: './loginCode/loginCode' }, // 验证码登录
  37. { component: '@/pages/404' },
  38. ],
  39. dva: {},
  40. antd: {},
  41. externals: {
  42. TCPlayer: 'window.TCPlayer',
  43. },
  44. locale: {
  45. default: 'zh-CN',
  46. },
  47. metas: [
  48. {
  49. name: 'apple-mobile-web-app-capable',
  50. content: 'yes',
  51. },
  52. {
  53. name: 'fullscreen',
  54. content: 'yes',
  55. },
  56. {
  57. name: 'x5-fullscreen',
  58. content: 'true',
  59. },
  60. ],
  61. styles: ['https://imgcache.qq.com/open/qcloud/video/tcplayer/tcplayer.css'],
  62. headScripts: [
  63. 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js',
  64. 'https://imgcache.qq.com/open/qcloud/video/tcplayer/libs/hls.min.0.13.2m.js',
  65. 'https://imgcache.qq.com/open/qcloud/video/tcplayer/tcplayer.v4.1.min.js',
  66. ],
  67. theme: {
  68. 'fill-grey': '#F9F9F9',
  69. 'color-text-base': '#4A4A4A', // 基本
  70. 'color-text-strong': '#404C56', //加重
  71. 'color-text-bold': '#3C5061', //粗体
  72. 'color-text-secondary': '#666666', // 辅助色
  73. 'color-text-caption': '#999999', // 辅助描述
  74. },
  75. });

其他

  • 函数组件与类组件

当使用到一些特殊的钩子函数的时候使用函数组件,比方umi的useMode、useSelector, useDispatch等
当运用了异步修改状态推荐使用类组件

  1. this.setState({
  2. ...
  3. }, () => {
  4. // 执行异步操作
  5. });
  • 页面之间传参方式(url传参与state传参)

当页面的入口有多个的时候,比如可分享的页面,建议使用url传参,通过从url读取参数,向后端请求数据
当参数较为简单,且入口固定可使用state传参

以umi的history举例

  1. // url 传参
  2. history.push(`/askDoctorForm?gid=${props.gid}&did=${doctor.id}`);
  3. const params = history.location.query; // 获取参数
  4. // state 传参
  5. history.push(`/askDoctorForm`, {
  6. gid: props.gid,
  7. did: doctor.id,
  8. });
  9. const params = history.location.state; // 获取参数
  • 持久状态、全局状态和局部状态的使用场景

持久状态:能够持久保存在浏览器中的数据,常用localStorage实现。使用场景:保存用户账户信息,登录态等数
全局状态:全局共享的常量数据,常用来保存一些配置、权限、类型枚举等信息
局部状态:单一组件或者部分组件用到的数据, 单一组件推荐使用react自有的state, 多组件推荐使用状态管理(redux等)

  • 依赖的引入顺序

    官方库>第三方库>自定义文件>自定义组件>样式

  1. // 库
  2. import React, { useState, useEffect, useRef } from 'react';
  3. import moment from 'moment';
  4. import { history, useLocation, useParams } from 'umi';
  5. import { Toast } from 'antd-mobile';
  6. // 自定义文件
  7. import { rightConfig, WECHAT_MP } from '@/utils/configData';
  8. import { OrderCreateRespType } from '@/utils/type';
  9. import newRequest from '@/utils/request';
  10. import isWeichat from '@/utils/isWeichat';
  11. import global from '@/utils/global';
  12. // 自定义组件
  13. import NavBar from '@/components/navbar/navbar';
  14. import DoctorConsult from '@/components/doctorConsult/doctorConsult';
  15. import VideoItem, { EpisodeProp } from '@/components/videoItem/videoItem';
  16. // 样式
  17. import styles from './courseDetail.less';
  • 类型检测(写接口)的必要性

建议使用接口(interface),使用接口有以下几个优点:

  1. 约束函数或者类的参数输入,提供了类型检测
  2. IDE能为编写代码提供警告和快捷输入
  3. 能够清晰明了的查到组件所需的数据以及类型
  4. 提高代码的严谨性
  1. interface UserProp {
  2. ownerAvatar?: string;
  3. ownerName?: string;
  4. ownerRole?: number;
  5. ownerIsDoctor?: boolean;
  6. createTime?: string;
  7. }
  8. interface TopicOwnerProp {
  9. hasOption?: boolean;
  10. hasZan?: boolean;
  11. hasAt?: boolean;
  12. sizeType?: string;
  13. user: UserProp;
  14. avatarClick?: () => void;
  15. optionClick?: (user: UserProp) => void;
  16. }
  17. export default (props: TopicOwnerProp) => {
  18. return <div>...</div>
  19. }

一些常用的文件命名

  • 全局变量:global.ts
  • 工具集:utils.ts
  • 配置数据:config.ts
  • 公共请求:commonRequest.ts(图片上传、登录校验等)
  • 类型接口:type.d.ts

Vue项目(TODO)

原生项目(TODO)

App(flutter)端(TODO)

代码规范

  • 包的导入顺序:dart: > package: > 项目相关
  • export 放在所有导入语句之后
  • 以驼峰命名,类名首字母大写, 私有变量以”_”开头
  • 使用///文档注释成员和类型
  • 避免缩写
  • 不要使用.length来判断集合为空(可以使用isEmpty)
  • 不要显示为参数设置null值
  • 推荐使用final关键字创建只读属性
  • 尽可能在定义变量的时候初始化变量值
  • 构造函数不要使用 new
  • async中需要存在有用效果
  • 使用Future作为无法回值异步成员的返回类型
  • 要注意var 和 const的使用时机
  • 方法名避免以”get”开头

切图规范

  • 凡是不能确地页面高度的都使用可滑动组件(ListView, SingleChildScroll…)
  • 使用materail主题都要考虑appbar返回键在Android和Ios的统一, 建议全部使用leading自定义返回图标, 并且注意返回图标与背景色区分开来
  • 使用TextField注意屏幕被撑起问题, 键盘类型, 是否自动更正等
  • 明确设计主题色, 并分离出单独的配置文件
  • 图片占位符问题, 确保图片请求时图片区域视觉友好
  • UI块抽离成组件,避免多层嵌套造成阅读障碍