简介

本文介绍了项目中最基本的开发规范,这些都是最基本要求,当然,开发中,还应根据项目具体要求的规范进行开发。后续规范将会持续更新中。

代码风格

缩进

  1. [强制] 使用 4 个空格做为一个缩进层级,不允许使用 2 个空格或 tab 字符
  2. 单行最长限制,每行不得超过 120 个字符
  3. 模块书写顺序 [建议] template -> script -> style

template

根节点:

template 根节点只允许包含一个直接子节点,以下情况都是不允许的:

  • 根结点为空;
  • 根结点是文字;
  • 根结点有多个元素;
  • 在根结点使用循环;
  • 在根结点使用 template 和 slot;
  • 在根结点使用 v-if,但是没有 v-else;
// bad
<template></template>
<template>hello</template>
<template><div>one</div><div>two</div></template>
<template><div v-for="x in list"></div></template>
<template><template>hello</template></template>
<template><div v-if="title"></div></template>

// good
<template><div>one</div></template>

标签:

1.自定义组件的标签名不得使用 HTML 中默认已定义的标签,要求至少由两个单词组成,并且符合 kebab-case

<template>
    <other-component/>
</template>

<script>
import OtherComponent from './OtherComponent.vue';

export default {
    components: {
        OtherComponent
    }
}
</script>
  1. HTML Void Element 不需要闭合,其它类型标签都需要闭合
<input>
<br>

非根结点的 template 标签里必须有一个以上的子结点

// good
<ul>
    <template>
        <li></li>
        <li></li>
    </template>
</ul>
  1. template 标签上不能带有 key 属性
// bad
<template>
    <div>
        <template key="x"></template>
        <template v-bind:key="y"></template>
        <template :key="z"></template>
    </div>
</template>

4.如果自定义标签中没有内容,需要以自闭合标签形式出现

// good
<c-title :url="url" :label-type="type"/>

5.标签右括号 > 的位置:

  • 元素只有一行时,右括号与元素保持在同一行。
  • 多行元素(元素最后一个属性与左括号 < 不在同一行)时,右括号 > 需要另起一行,缩进与左括号 < 保持对齐。
// good
<div id="foo" class="bar"></div>

// good
<div
    id="foo"
    class="bar"
>
    some message
</div>

// good
<c-title
    :text="text"
    :url="url"
    :label-type="type"
/>
  1. 自闭合标签的 /> 前不用添加空格
// bad
<c-title :url="url" :label-type="type" />(这有一个空格,不推荐加)

属性:

1.属性值必须用双引号

<div class="c-color"></div>

2.模板中属性命名kebab-case
slot 命名采用 kebab-case
ref 命名采用 PascalCase(驼峰)

模板
<my-component greeting-text="hi"/>
solt
<slot name="header-left"></slot>

<div slot="header-left"></div>
ref
<div ref="userInfo"></div>

3.class / style 属性值不能设置空字符串

// bad
<div class=""></div>
<div style=""></div>

// good
<div></div>

4.布尔类型的属性值为 true 时,建议不添加属性值

// bad
<c-title text="带箭头标题" :arrow="true"/>

// good
<input type="text" disabled>
<c-title text="带箭头标题" arrow/>
<c-title text="带箭头标题" :arrow="false"/>

5.当组件的属性多于 2 个时,必须分成多行,每行写一个属性;只有属性个数小于或等于 2 个时,可以写在一行内

// bad
<c-title :text="text" :url="url" :label-type="type"/>
// good
<c-title :text="text" :url="url"/>
<c-title
    :text="text"
    :url="url"
    :label-type="type"
/>

6.不能有重复的属性,classstyle 除外

7.当元素有多个属性时,应该按照统一的顺序书写

  1. 定义(提供组件的选项)
    • is
  2. 列表渲染(创建多个变化的相同元素)
    • v-for
  3. 条件渲染(元素是否渲染/显示)
    • v-if
    • v-else-if
    • v-else
    • v-show
    • v-cloak
  4. 渲染方式(改变元素的渲染方式)
    • v-pre/v-once
  5. 全局感知(需要超越组件的知识)
    • id
  6. 唯一的特性(需要唯一值的特性)
    • ref
    • key
    • slot
  7. 双向绑定(把绑定和事件结合起来)
    • v-model
  8. 未绑定的属性
  9. 其它绑定(所有普通的绑定)
    • v-bind
  10. 事件(组件事件监听器)
    • v-on
  11. 内容(覆写元素的内容)
    • v-html
    • v-text

指令:

1.v-for
在使用 v-for 的元素上添加 key,以便维护内部组件及其子树的状态。

 <ul>
        <li class="techer-li"
            v-for="(item,index) in teacherList"
            :key="index"
            @click="viewInformation(item.id)">
          <img class="teacher-img"
               :src="item.teacherImage"
               alt="">
          <span class="teacher-name">{{item.teacherName}}</span>
        </li>
      </ul>

使用建议:
1. v-for绑定数组对象时,如果往数组中添加对象时。
a. 每次都在数组的末尾添加,则key可以使用index
b. 如果不确定添加到哪个位置,为每一个制定一个编号,用对象的编号作为key
2. v-for和v-if不建议同时使用
a. 当 Vue 处理指令时,v-for比 v-if具有更高的优先级。
b. 所以如果想要使用 v-if判断 v-for元素列表是否显示,将两个指令同时应用在同一个元素的方法就是错误的。
解决办法:

// bad
<ul>
    <li
        v-for="user in users"
        v-if="user.isActive"
        :key="user.id"
    >
        {{ user.name }}
    </li>
</ul>

// good
<template>
    <ul>
        <li
            v-for="user in activeUsers"
            :key="user.id"
        >
            {{ user.name }}
        </li>
    </ul>
</template>
<script>
export default {
    computed: {
        activeUsers: function () {
            return this.users.filter(function (user) {
                return user.isActive;
            });
        }
    }
}
</script>

指令缩写
建议一下指令使用缩写
v-bind——> :
v-on——> @

插值:

建议:左右各插一个空格

// bad
<div>{{   text   }}</div>
<div>{{text}}</div>

// good
<div>{{ text }}</div>

空格:

不能含有多余空格

// bad
<div     class="foo"
      :style="bar"         >   </div>

// good
<div class="foo" :style="bar"></div>

变量:

1.不能使用多余的变量
2.禁止在插值中使用this

// bad
<a :href="this.url">
    {{ this.text }}
</a>

// good
<a :href="url">
    {{ text }}
</a>

js

props

1.指定 props 类型

// bad
<script>
export default {
    props: ['status']
};
</script>

// good
<script>
export default {
    props: {
        status: String
    }
};
  1. 如果 props 没有指定为 required 或者 requiredfalse,则需要指定默认值
// bad
<script>
export default {
    props: {
        a: Number,
        b: [Number, String],
        c: {
            type: Number
        },
        d: {
            type: Number,
            required: false
        }
    }
};
</script>

// good
<script>
export default {
    props: {
        a: {
            type: Number,
            required: true
        },
        b: {
            type: [Number, String],
            default: 0
        },
        c: {
            type: Number,
            default: 0,
            required: false
        }
    }
};
</script>

3.props 提供的默认值必须满足校验条件

// bad
<script>
export default {
    props: {
        propA: {
            type: String,
            default: {}
        },
        propB: {
            type: String,
            default: []
        },
        propC: {
            type: Object,
            default: []
        },
        propD: {
            type: Array,
            default: []
        },
        propE: {
            type: Object,
            default: {
                message: 'hello'
            }
        }
    }
};
</script>

// good
<script>
export default {
    props: {
        propA: Number,
        propB: [String, Number],
        propD: {
            type: Number,
            default: 100
        },
        propE: {
            type: Object,
            default() {
                return {
                    message: 'hello'
                };
            }
        }
    }
};

4.在 props 中声明的属性,其属性名应该始终符合 camelCase(驼峰命名)

// bad
<script>
export default {
    props: {
        'greeting-text': String
    }
};
</script>

// good
<script>
export default {
    props: {
        greetingText: String
    }
};
</script>

data

1.data必须是一个函数

<script>
export default {
    data() {
        return {
            b: 1
        };
    }
}
</script>

2.data 中禁止使用 computed 中的变量

// bad
<script>
export default {
    props: {
        a: {
            type: String,
            default: 0
        }
    },
    data() {
        return {
            d: this.f
        };
    },
    computed: {
        f() {
            return this.a * 10;
        }
    }
};
</script>

3.props, data, computed, methods 中不能有重复的 key

// bad
<script>
export default {
    props: {
        foo: String
    },
    data() {
        return {
            foo: null
        };
    },
    computed: {
        foo() {
            return 'foo';
        }
    }
}
</script>

// good
<script>
export default {
    props: {
        foo: String
    },
    data() {
        return {
            bar: null
        };
    },
    computed: {
        baz() {
            return foo + bar;
        }
    }
}
</script>

变量

1.不能使用 Vue 中的保留字段命名变量

  1. vue使用_来定义自身的私有属性,
  2. 对于 $ 前缀来说,其在 Vue 生态系统中的目的是暴露给用户的一个特殊的实例属性,所以把它用于私有属性并不合适。
    推荐:
    使用_和$结合来作为一个用户定义的私有属性的约定

$emit

组件中使用 $emit 事件时携带的参数,个数不应该超过 2 个。建议将数据参数以 Object 形式传递,将事件参数 event 放在最后

// bad
onClick(event) {
    this.$emit('click', this.value1, this.value2, event);
}

// good
onClick(event) {
   this.$emit(
       'click',
       {
           value1: this.value1,
           value2: this.value2
       },
       event
   );
}

// good
onClick(event) {
   this.$emit('click', event);
}

style

1.为组件样式设置作用域

<style scoped>
.button {
    border: none;
    border-radius: 2px;
}
</style>

2.深度选择器/deep/ 建议前面加div,解决编辑器爆红问题。

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐