Vue前端开发规范

概述

如果开发团队就一个人的话,那么自己写的代码就是规范,随着公司业务的扩展,团队不断壮大,这时候就要开始考虑协作和编码规范问题了。

一个人走的更快,一群人可以走的更远,前提是统一的策略,还要不断地反省和优化。

为什么要有规范?

  • 降低新成员融入团队的成本, 同时也一定程度避免挖坑;
  • 提高开发效率、团队协作效率, 降低沟通成本;
  • 实现高度统一的代码风格,方便review, 另外一方面可以提高项目的可维护性;
  • 规范是实现自动化的基础;
  • 规范是一个团队知识沉淀的直接输出;

项目结构

node_nodules/   -------------- 这个目录存放的是项目的所有依赖,即 npm install 命令下载下来的文件
build   ---------------------- 文件夹,用来存放项目构建脚本
public/ ---------------------- 放置一些静态资源,而且在项目打包的时候webpack不会编译这个文件夹
mock  ------------------------ mock数据的文件夹 模拟一些假的数据mock.js实现的,因为实际开发的时候,利用的是真实接
src/    ---------------------- 这个目录下存放项目的源码,即开发者写的代码放在这里
|- api  ---------------------- 统一接口目录
|- assets  ------------------- 里面放置一些静态资源(一般共享的),放在assets文件夹里面静态资源,会进行编译
|- components  --------------- 公共组件目录
|- directives  --------------- 自定义指令目录
|- router  ------------------- VueRouter目录
|- store  -------------------- Vuex目录
|- icons  -------------------- 放置了一些svg矢量图
|- styles  ------------------- 样式文件目录
|- utils  -------------------- 工具目录
|- layouts  ------------------ 如果是管理类软件, 放置公共布局类组件 如:Container, SideMenu、SideMenu.vue。
|- views  -------------------- 页面组件目录
|- App.vue  ------------------ 根组件
|- main.js  ------------------ 入口文件
|- permission.js  ------------ 与导航守卫相关
|- settings ------------------ 项目的配置项文件
.browserslistrc
.env.development
.env.production
.eslintrc.js
.gitinore
babel.config.js
package.json
README.md
vue.config.js

目录,文件,组件,组件结构命名规范

目录命名

全部采用小写方式, 以中划线分隔,有复数结构时,要采用复数命名法, 缩写不用复数。

项目目录与其项目一级导航菜单统一,便于管理,二级导航放在一级导航文件夹下,以此类推。

复数命名法:文件夹可缩写,文件尽量不缩写,变量可缩写(但需备注全称)。
原因:一个项目,目录不会很多,文件会很多,变量会更多,变量的缩写可以备注,但文件的缩写无法备注,需要让人直观的了解到文件的作用,

//正例
/center/supplier/abs-page.vue,

//反例
/center/sup/abs_page.vue',

文件命名

JS、CSS、SCSS、HTML、PNG命名,全部采用小写方式, 以中划线分隔。

//正例
@/assets/img/logo-white.png,

//反例
@/assets/img/logoWhite.png

组件命名

组件名以单词大写开头,当多个单词拼写成的组件时,采用驼峰式命名规则 (PascalCase)。一般是多个单词全拼,减少简写的情况,这样增加可读性。

components/
|- MyComponent.vue

应用特定样式和约定的基础组件 (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App。

components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue

组件应该都放到components文件夹下,单个页面独立一个文件夹,用来放相对应的VUE文件以及页面相关的样式文件,样式少可直接写到页面组件里边,这样更符合组件化的思想。

组件结构

组件结构遵循从上往下template,script,style的结构。

<script>的import顺序,分模块,拆分来写

首先引入npm包里的内容

其次引入全局的一些组件、方法

最后引入当前业务模块的组件、方法

data里面的数据,按模块顺序,分开书写

用空格隔开

data (){
  return {
    //模块一
    xx1,
    xx2,

    //中间用空一行
    //模块二
    qq1,
    qq2
  }
}
vue2 的option对象,属性需要按顺序排列
  1. name
  2. mixins
  3. components
  4. props
  5. data
  6. filters
  7. directive
  8. computed
  9. watch
  10. 生命周期(按执行顺序)
  11. methods

代码规范

Template 规范

  1. 尽量使用以.vue结束的单文件组件,方便管理,结构清晰。

  2. 标签语义化,避免清一色的div元素

  3. DOM的层级数尽可能少,优化渲染速度。

  4. 多特性,分行写,提高可读性。即一个标签内有多个属性,属性分行写。

  5. 自定义标签:使用自闭标签的写法。例如:,如果自定义标签中间需要传入slot,则写开始标签和结束标签,结束标签必须加/。

  6. v-slot:在vue2.6版本中,slot与slot-scope已被弃用,统一使用v-slot指令。

  7. 不使用v-html指令

  8. 不写过于复杂的表达式,使用计算属性来代替

  9. 相同的卡片布局,首先整合数据,尽量使用循环方式去增加,避免变更多处的问题。

  10. v-for 循环必须加上 key 属性,在整个 for 循环中 key 需要唯一,key一般使用index或者todo.id。

    <ul>
    <li
    v-for="todo in todos"
    :key="todo.id"
    >
    {{ todo.text }}
    </li>
    </ul>

  11. 避免 v-if 和 v-for 同时用在一个元素上(性能问题),以下为两种解决方案:

    1. 将数据替换为一个计算属性,让其返回过滤后的列表。
    2. 将 v-if 移动至容器元素上 (比如 ul, ol)。

注释规范

<!-- 房间信息模块 -->

<div class="room">

......

</div>

<!-- 房间信息模块 -->

JS规范

  1. 在 Script 标签中,应该遵守 JS的规范和ES6规范。

  2. 创建公共的JS,封装公用的方法和工具类。

  3. 声明变量必须赋值

  4. 使用let、const替代var

    由于变量提升、无块级作用域等原因,var基本上已经退出了历史的舞台

  5. 匿名函数使用箭头函数

// 反例
const _this = this
setTimeout(function() {
  _this.xxx()
}, 10)

// 正例
setTimeout(() => {
  this.xxx()
}, 10)
  1. 避免回调地狱,使用以下为两种解决方案:

  2. 方法返回Promise,方便可以通过 .then 的方式进行链式调用

  3. 获取异步的数据,按具体情况使用 async/await 操作

  4. 三元运算符不嵌套

三元运算符只用作单行操作,如果嵌套过深的话,会增加阅读难度

  1. 使用map、object替代if、switch case条件取值
// 反例
let statusName = ''
if (type === 1) {
    statusName = '草稿'
} else if (type === 2) {
    statusName = '已发布'
} else if (type === 3) {
    statusName = '已删除'
}
// 正例
let statusName = {
    1: '草稿',
    2: '已发布',
    3: '已删除'
}[type] || ''

9.慎用setTimeout

禁止通过 setTimeout 来获取异步接口的数据
能通过 this.$nextTick实现的,不用 setTimeout

  1. 无特殊情况不允许使用原生API操作DOM,谨慎使用this.$refs直接操作DOM

    操作DOM是及其损耗性能得, 代码的质量会降低,出现一些多余得代码;

    经常直接操作DOM 会导致一些不可预测得问题,当你在一个组件当中直接操作全局得DOM时,有可能会影响到其他页面,一旦报错,定位问题会比较困难。

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

  3. 尽量使用”===“和”!==“

  4. 整合数据时尽量使用ES6,Object.assign和 … 扩展符(ps:Object.assign() 为浅复制)

  5. 若循环中需使用函数,请将函数定义在循环外部而非内部,这样可以避免函数的反复创建。

  6. Props定义:提供默认值,使用Type属性校验类型,使用Props之前先检查Prop是否存在。

    //正确
    props: {
         status: String
    }
    // 更好的做法!
    props: {
        status: {
            type: String,
            required: true,
            validator: function (value) {
                return [
                        'syncing',
                        'synced',
                        'version-conflict',
                        'error'
                        ].indexOf(value) !== -1
            }
        }
    }
    // 反例
    // 这样做只有开发原型系统时可以接受
    props: ['status']
    
  1. 当在组件中使用 data 属性的时候 (除了 new Vue 外的任何地方),它的值必须是返回一个对象的函数。

    export default {
        data () {
            return {
                foo: 'bar'
            }
        }
    }
    
  1. JS中统一使用反引号(``)或是单引号(''), 不使用双引号("")。

  2. 避免 v-if 和 v-for 用在一起

    <ul v-if="shouldShowUsers">
        <li
            v-for="user in users"
            :key="user.id"
        >
            {{ user.name }}
        </li>
    </ul>
    
  1. 函数中统一使用_this=this来解决全局指向问题。

  2. 导入模块时不要省略后缀(js 除外),这样有利于 IDE 感知(特别是 .vue)。

  3. 弹框、select等需要大量代码去实现,要以组件的方式引入。

  4. 应该把复杂计算属性分割为尽可能多的更简单的属性。

  5. 使用路由懒加载(延迟加载)机制

    //路由懒加载
    const HelloWorld = ()=>import("@/components/HelloWorld")
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component:HelloWorld
        }
      ]
    })
    
  6. 组件懒加载,较复杂的组件可使用,建议多使用

    <template>
      <div class="hello">
      <One-com></One-com>
      1111
      </div>
    </template>
    
    <script>
    //懒加载组件
    const One = ()=>import("./one");
    export default {
      components:{
        "One-com":One
      },
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        }
      }
    }
    </script>
    
  7. 调试信息console.log() ; debugger 使用完及时删除

注释规范

  1. 文件顶部注释(多行)

    /**
    
        @description: 文件中文说明
    
        @author: 作者
    
        @update: 作者 (2016-03-7 15:00)
    
    **/
    
  1. 行级注释(注意//后面空格):// 正确的注释

  2. 变量声明注释:如果是在类似 Vue 项目的 data 属性中的变量,直接用行级样式跟在后面。

    data(){
     return {
             foo: 'bar' // 注释直接写这里
        }
    }
    
  3. 如果是在类,构造函数,或者常量定义中的变量,使用块级注释。/ comment /

    函数声明注释:不必要在每一个函数都写注释,但是在公共函数,还是建议补全注释,让后面的人不需要重复造轮子。

  4. 复杂的业务逻辑处理说明、特殊情况的代码处理说明,对于特殊用途的变量、存在临界值、使用了某种算法思路进行注释说明

CSS规范

  1. 需要加上scoped作用域

  2. 避免使用标签选择器(效率低、损耗性能)。

  3. CSS 属性书写顺序:先决定定位宽高显示大小,再做局部细节修饰!推荐顺序:定位属性(或显示属性,display)->宽高属性->边距属性(margin, padding)->字体,背景,颜色等,修饰属性的定义。

注释规范

注意在注释的前后各有一个空格。

图片规范

  1. 每个模块都要增加一个图片文件夹方便后期维护和处理,图片文件命名尽量跟模块意义的相同,尽量使用小写单词命名。
  2. 图片格式常用png,jpg,gif。
  3. 命名全部用小写字母,数字及中划线组合,其中不包含汉字、空格和特殊字符;尽量用易懂的词汇,便于团队其他成员理解;命名分头尾两部分,用中划线隔开,(例如:ad-left01.png、btn-submit.png)。
  4. 在保证视觉效果的情况下选最小的图片格式与图片质量,减少加载时间。
  5. PC端img图片必须填写width、height、alt属性
  6. 需要变动的文字禁止切到图片中,如果不确定是否需要变动,请咨询接口人
  7. 需要程序后台动态生成的图片,如道具图片、头像、奖品,必须单独切割出来
  8. 装饰性图片合并成精灵图,减少页面请求

API规范

1、API接口地址统一管理,接口较少时可以单独写一个接口文件JS,页面中使用哪些引入哪些。

2、接口较多时,可对接口按模块进行分类,一个模块对应一个接口文件。

其他

1、文字超出容器需要进行 '...' 省略。

2、图片显示 无特殊要求时,按原图宽高比显示,尽量不要变形。

3、涉及数据处理功能按钮,增加防频繁点击处理。

4、小图标尽量使用UI框架自带的icon图标。

5、页面按钮颜色,样式,功能尽量统一。

6、不同页面相同功能的提示文字尽量统一。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容