uniapp开发规范

结构化规范+组件规范+编码规范+注释规范+css规范

🍢uniapp开发规范

为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:

  • 页面文件遵循 Vue 单文件组件 (SFC) 规范
  • 组件标签靠近小程序规范,详见uni-app 组件规范
  • 接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni,详见uni-app接口规范
  • 数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生命周期
  • 为兼容多端运行,建议使用flex布局进行开发

🍢结构化规范

🍙默认模板:

┌─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,ps:静态资源只能存放于此
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见

├─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见
└─uni.scss uni-app内置的常用样式变量

🍙添加目录文件夹及子文件规范:

├─ api 接口,统一管理

├─components 符合vue组件规范的uni-app组件目录
│ └─comp-a.vue 可复用的a组件

├─filters 过滤器,全局工具

├─mock 模拟接口,临时存放

├─store vuex, 统一管理

├─utils 存放自己封装的工具类函数

🍙文件命名:

  • 尽量是名词,且使用驼峰命名法
  • 开头的单词就是所属模块名字(workbenchIndex、workbenchList、workbenchEdit)
  • 名字至少两个单词(good: workbenchIndex)(bad:workbench)

🍢组件规范

🍙组件文件:

只要有能够拼接文件的构建系统,就把每个组件单独分成文件。
当你需要编辑一个组件或查阅一个组件的用法时,可以更快速的找到它。

  • vue组件

    • import导入组件
    • components里注册组件
    • template中使用组件
  • easycom组件

    组件安装在项目的components目录下或uni_modules目录下,并符合components/组件名称/组件名称.vue目录结构

    PS:easycom打包后会自动剔除没有使用的组件,对组件库的使用尤为友好

🍙组件命名规范:

  • 有意义的: 不过于具体,也不过于抽象
  • 简短: 2 到 3 个单词
  • 具有可读性: 以便于沟通交流

同时还需要注意:

  • 必须符合自定义元素规范: 使用连字符-分隔单词,切勿使用保留字(可区分页面和组件)

  • 组件里面的name要和组件的名字保持一致

  • app-前缀作为命名空间: 如果非常通用的话可使用一个单词来命名,这样可以方便于其它项目里复用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!-- 推荐 -->
    <app-header></app-header>
    <user-list></user-list>
    <range-slider></range-slider>

    <!-- 避免 -->
    <btn-group></btn-group> <!-- 虽然简短但是可读性差. 使用 `button-group` 替代 -->
    <ui-slider></ui-slider> <!-- ui 前缀太过于宽泛,在这里意义不明确 -->
    <slider></slider> <!-- 与自定义元素规范不兼容 -->

🍙组件数据:

组件的 data 必须是一个函数。
当在组件中使用 data 属性的时候 (除了 new Vue 外的任何地方),它的值必须是返回一个对象的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- 推荐 -->
// In a .vue file
export default {
data () {
return {
foo: 'bar'
}
}
}
// 在一个 Vue 的根实例上直接使用对象是可以的,
// 因为只存在一个这样的实例。
new Vue({
data: {
foo: 'bar'
}
})

🍙组件 props 原子化

为什么?

  • 使得组件 API 清晰直观

  • 只使用原始类型和函数作为 props 使得组件的 API 更接近于 HTML(5) 原生元素

  • 其它开发者更好的理解每一个 prop 的含义、作用

  • 传递过于复杂的对象使得我们不能够清楚的知道哪些属性或方法被自定义组件使用,这使得代码难以重构和维护。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <!-- 推荐 -->
    <range-slider
    :values="[10, 20]"
    :min="0"
    :max="100"
    :step="5"
    @on-slide="updateInputs"
    @on-end="updateResults">
    </range-slider>

    <!-- 避免 -->
    <range-slider :config="complexConfigObject"></range-slider>

🍙将 this 赋值给 component 变量

在 Vue.js 组件上下文中,this指向了组件实例。因此当你切换到了不同的上下文时,要确保 this 指向一个可用的 component 变量。

换句话说,如果你正在使用 ES6 的话,就不要再编写 var self = this; 这样的代码了,你可以安全地使用 Vue 组件。

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
<!-- 推荐 -->
<script type="text/javascript">
export default {
methods: {
hello() {
return 'hello';
},
printHello() {
console.log(this.hello());
},
},
};
</script>
<!-- 避免 -->
<script type="text/javascript">
export default {
methods: {
hello() {
return 'hello';
},
printHello() {
const self = this; // 没有必要
console.log(self.hello());
},
},
};
</script>

🍢编码规范

🍙变量命名要求

  • 定义变量使用 let ,定义常量使用 const
  • 命名方法 : 变量使用驼峰命名法

🍙常量命名要求

  • 命名方法: 全部大写
  • 命名规范: 使用大写字母和下划线来组合命名,下划线用以分割单词
1
2
const MAX_COUNT = 10
const URL = 'https://www.baidu.com/'

🍙解构赋值

  • 数组成员对变量赋值时,优先使用解构赋值

    1
    2
    3
    4
    5
    6
    7
    8
    // 数组解构赋值
    const arr = [1, 2, 3, 4]
    // bad
    const first = arr[0]
    const second = arr[1]

    // good
    const [first, second] = arr
  • 函数的参数如果是对象的成员,优先使用解构赋值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 对象解构赋值
    // bad
    function getFullName(user) {
    const firstName = user.firstName
    const lastName = user.lastName
    }

    // good
    function getFullName(obj) {
    const { firstName, lastName } = obj
    }

    // best
    function getFullName({ firstName, lastName }) {}
  • 拷贝数组

    使用扩展运算符(…)拷贝数组。

    1
    2
    3
    4
    5
    6
    7
    const items = [1, 2, 3, 4, 5]

    // bad
    const itemsCopy = items

    // good
    const itemsCopy = [...items]
  • 箭头函数

    需要使用函数表达式的场合,尽量用箭头函数代替。因为这样更简洁,而且绑定了 this

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // bad
    const self = this;
    const boundMethod = function(...params) {
    return method.apply(self, params);
    }

    // acceptable
    const boundMethod = method.bind(this);

    // best
    const boundMethod = (...params) => method.apply(this, params);
  • 模块

    • 如果模块只有一个输出值,就使用 export default,如果模块有多个输出值,就不使用 export default,export default 与普通的 export 不要同时使用

      1
      2
      3
      4
      5
      // bad
      import * as myObject from './importModule'

      // good
      import myObject from './importModule'
    • 如果模块默认输出一个函数,函数名的首字母应该小写

      1
      2
      3
      4
      5
      function makeStyleGuide() {

      }

      export default makeStyleGuide;
    • 如果模块默认输出一个对象,对象名的首字母应该大写

      1
      2
      3
      4
      5
      6
      const StyleGuide = {
      es6: {
      }
      };

      export default StyleGuide;

🍙method 方法命名命名规范

  • 驼峰式命名,统一使用动词或者动词+名词形式

    1
    2
    3
    4
    <!-- 推荐 -->
    jumpPage、openCarInfoDialog
    <!-- 避免 -->
    go、nextPage、show、open、login
  • 如果是请求什么数据的需要以data来结尾

    1
    2
    3
    4
    <!-- 推荐 -->
    getListData、postFormData
    <!-- 避免 -->
    takeData、confirmData、getList、postForm
  • 尽量使用常用单词开头(set、get、go、can、has、is)

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    get 获取/set 设置,
    add 增加/remove 删除
    create 创建/destory 移除
    start 启动/stop 停止
    open 打开/close 关闭,
    read 读取/write 写入
    load 载入/save 保存,
    create 创建/destroy 销毁
    begin 开始/end 结束,
    backup 备份/restore 恢复
    import 导入/export 导出,
    split 分割/merge 合并
    inject 注入/extract 提取,
    attach 附着/detach 脱离
    bind 绑定/separate 分离,
    view 查看/browse 浏览
    edit 编辑/modify 修改,
    select 选取/mark 标记
    copy 复制/paste 粘贴,
    undo 撤销/redo 重做
    insert 插入/delete 移除,
    add 加入/append 添加
    clean 清理/clear 清除,
    index 索引/sort 排序
    find 查找/search 搜索,
    increase 增加/decrease 减少
    play 播放/pause 暂停,
    launch 启动/run 运行
    compile 编译/execute 执行,
    debug 调试/trace 跟踪
    observe 观察/listen 监听,
    build 构建/publish 发布
    input 输入/output 输出,
    encode 编码/decode 解码
    encrypt 加密/decrypt 解密,
    compress 压缩/decompress 解压缩
    pack 打包/unpack 解包,
    parse 解析/emit 生成
    connect 连接/disconnect 断开,
    send 发送/receive 接收
    download 下载/upload 上传,
    refresh 刷新/synchronize 同步
    update 更新/revert 复原,
    lock 锁定/unlock 解锁
    check out 签出/check in 签入,
    submit 提交/commit 交付
    push 推/pull 拉,
    expand 展开/collapse 折叠
    begin 起始/end 结束,
    start 开始/finish 完成
    enter 进入/exit 退出,
    abort 放弃/quit 离开
    obsolete 废弃/depreciate 废旧,
    collect 收集/aggregate 聚集
  • props 命名

    在声明 prop 的时候,其命名应该始终使用 camelCase,而在模板中应该始终使用 kebab-case

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <!-- bad -->
    <script>
    props: {
    'greeting-text': String
    }
    </script>

    <welcome-message greetingText="hi"></welcome-message>

    <!-- good -->
    <script>
    props: {
    greetingText: String
    }
    </script>

    <welcome-message greeting-text="hi"></welcome-message>

    PS:特殊情况

    • 作用域不大临时变量可以简写,比如:str,num,bol,obj,fun,arr。
    • 循环变量可以简写,比如:i,j,k 等。
  • 为v-for设置键值

    总是用 key 配合 v-for。
    在组件上_总是_必须用 key 配合 v-for,以便维护内部组件及其子树的状态。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!-- 推荐 -->
    <ul>
    <li
    v-for="todo in todos"
    :key="todo.id"
    >
    {{ todo.text }}
    </li>
    </ul>
  • 避免 v-if 和 v-for 用在一起

    永远不要把 v-if 和 v-for 同时用在同一个元素上。
    一般我们在两种常见的情况下会倾向于这样做:

    • 为了过滤一个列表中的项目 (比如 v-for=”user in users” v-if=”user.isActive”)。在这种情形下,请将 users 替换为一个计算属性 (比如 activeUsers),让其返回过滤后的列表。
    • 为了避免渲染本应该被隐藏的列表 (比如 v-for=”user in users” v-if=”shouldShowUsers”)。这种情形下,请将 v-if 移动至容器元素上 (比如 ul, ol)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!-- 推荐 -->
    <ul v-if="shouldShowUsers">
    <li
    v-for="user in users"
    :key="user.id"
    >
    {{ user.name }}
    </li>
    </ul>
  • 指令缩写

    都用指令缩写 (用 : 表示 v-bind: 和用 @ 表示 v-on:)

    1
    2
    3
    4
    5
    6
    7
    // bad
    v-bind:class="{'show-left':true}"
    v-on:click="getListData"

    // good
    :class="{'show-left':true}"
    @click="getListData"
  • 多个特性的元素规范

    多个特性的元素应该分多行撰写,每个特性一行。(增强更易读)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!-- bad -->
    <img src="https://vuejs.org/images/logo.png" alt="Vue Logo">
    <my-component foo="a" bar="b" baz="c"></my-component>

    <!-- good -->
    <img
    src="https://vuejs.org/images/logo.png"
    alt="Vue Logo"
    >
  • 元素特性的顺序

    原生属性放前面,指令放后面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    - class
    - id,ref
    - name
    - data-*
    - src, for, type, href,value,max-length,max,min,pattern
    - title, alt,placeholder
    - aria-*, role
    - required,readonly,disabled
    - is
    - v-for
    - key
    - v-if
    - v-else-if
    - v-else
    - v-show
    - v-cloak
    - v-pre
    - v-once
    - v-model
    - v-bind,:
    - v-on,@
    - v-html
    - v-text

🍙其他

  • 避免 this.$parent
  • 调试信息 console.log() debugger 使用完及时删除
  • 除了三目运算,if,else 等禁止简写

🍢注释规范

​ 代码注释在一个项目的后期维护中显的尤为重要,所以我们要为每一个被复用的组件编写组件使用说明,为组件中每一个方法编写方法说明

🍙务必添加注释列表

  • 公共组件使用说明
  • 各组件中重要函数或者类说明
  • 复杂的业务逻辑处理说明
  • 特殊情况的代码处理说明,对于代码中特殊用途的变量、存在临界值、函数中使用的 hack、使用了某种算法或思路等需要进行注释描述
  • 多重 if 判断语句
  • 注释块必须以/**(至少两个星号开头)**/
  • 单行注释使用//

🍢CSS规范

  • 统一使用-连字符

  • 省略值为 0 时的单位

  • 如果 CSS 可以做到,就不要使用 JS

  • 建议并适当缩写值,提高可读性,特殊情况除外

    “建议并适当”是因为缩写总是会包含一系列的值,而有时候我们并不希望设置某一值,反而造成了麻烦,那么这时候你可以不缩写,而是分开写。

    当然,在一切可以缩写的情况下,请务必缩写,它最大的好处就是节省了字节,便于维护,并使阅读更加一目了然

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // bad
    .box{
    border-top-style: none;
    font-family: palatino, georgia, serif;
    font-size: 100%;
    line-height: 1.6;
    padding-bottom: 2em;
    padding-left: 1em;
    padding-right: 1em;
    padding-top: 0;
    }

    // good
    .box{
    border-top: 0;
    font: 100%/1.6 palatino, georgia, serif;
    padding: 0 1em 2em;
    }
  • 分类的命名方法

    • 使用单个字母加上-为前缀
    • 布局(grid)(.g-)
    img
    • 模块(module)(.m-)

    img

    • 元件(unit)(.u-)
    • 功能(function)(.f-)
    img
    • 皮肤(skin)(.s-)
    img
    • 状态(.z-)

      img
查看评论