分支规则

主分支: master

开发分支: develop

功能开发以 `feature/功能名` 命名

组件开发以 `components/组件名` 命名

修复 bug 以 `bugfix/bug(bugId或简短名)` 命名

紧急修复以 `hotfix/bug` 命名

文档开发以 `docs/功能名` 命名

命名规则

统一命名规则
  • 动态组件 统一使用 `tag` 属性来指定生成的标签类型
  • 状态对应属性应该为直接的状态名
    如: `loading` 状态对应属性名应该为 `loading`、`disabled` 状态对应属性名应该为 `disabled`
  • 分子以上组件,内部出现多个组件有相同状态则以 [组件名][状态名] 小驼峰形式对外暴露
  • 内部组件对外暴露 `class` 属性以 `[组件名][Class]` 小驼峰形式命名
  • `script`、`js` 中驼峰命名,文档、文件夹、模板中以 - 连接
  • 数组类型以复数形式命名
    例如: `options` 对应为 `array` 类型, `option` 对应为 `object` 类型
  • 内部组件命名也应该符合命名规范
  • 内部组件属性透传命名建议以 `[组件名]Props` 名称命名
    例如: 导航组件使用 `logoProps` 属性对 `logo` 标签进行属性传递
  • 内部响应事件函数应该以 `handle[EventName]` 命名, `update` 事件以 `update[PropName]` 命名,如果内部有多个相同的事件名,则以 `handle[Element/ComponentName][EventnName]` 命名
  • 子组件有更改属性需求时,对外发送 `update:PropName` 事件,并且将新值当做第一个参数

    代码块 Vue.js Component





<template>复制代码
<div></div>复制代码
</template>复制代码
<script>复制代码
export default {复制代码
props: {复制代码
visible: Boolean,复制代码
},复制代码
methods: {复制代码
toggle () {复制代码
this.$emit('update:visible', !this.visible);复制代码
}复制代码
}复制代码
}复制代码
</script>复制代码
  • slot 命名应该明确表明该 slot 对应元素的意义
    例如: <slot name='loading' /> 表明此插槽用来显示自定义的 loading 元素

代码块



Vue.js Component







// only an demo 复制代码
<script>复制代码
export default {复制代码
name: 'MtdButton',复制代码
props: {复制代码
// logo 地址复制代码
logo: String, 复制代码
// [组件/模块名]Props复制代码
logoProps: Object, 复制代码
// [组件/模块名]Class复制代码
logoClass: String, 复制代码
// 数组类型命名复数复制代码
options: Array, 复制代码
option: Object, 复制代码
},复制代码
methods: {复制代码
// handle[ComponentName][EventName]复制代码
handleInputClick () {复制代码
}复制代码
}复制代码
}复制代码
</script>复制代码




Props

  • 样式相关枚举类型属性不做强校验、功能相关强校验
    用户可能自己定义了其他样式并将改属性传入,所以对样式方面的枚举类型不做强校验,但是功能方面需要内部的支持,传入一个不支持的对于用户来说没有任何意义。

    代码块 Vue.js Component






// tooltip component 复制代码
<script>复制代码
export default {复制代码
name: 'MtdTooltip',复制代码
props: {复制代码
// 此属性用于生成对应的 class,内部样式只支持 dark、 light,但是不能排除用户提供了其他样式的可能,所以此处不校验复制代码
theme: String, 复制代码
// 此属性用于 tooltip 的显示触发方式,由于内部只实现了 hover,click 所以对于用户来说传递一个其他方式并没有意义复制代码
trigger: { 复制代码
type: String,复制代码
validator: function (v) { 复制代码
return ['hover', 'click'].includes(v);复制代码
}复制代码
}复制代码
// ...other复制代码
}复制代码
// ...复制代码
}复制代码
</script>复制代码
  • 表单需要支持 `v-model`, 使用 .sync 修饰符表达更新 props 意图

    代码块 Vue.js Component






// switch component 复制代码
<script>复制代码
export default {复制代码
name: 'MtdSwitch',复制代码
model: {复制代码
prop: 'actived',复制代码
},复制代码
props: {复制代码
actived: Boolean,复制代码
},复制代码
methods: {复制代码
handleClick () {复制代码
this.$emit('input', this.actived);复制代码
}复制代码
}复制代码
}复制代码
</script>复制代码
  • 上层组件需要支持内部组件属性透传,特别是要提供内部组件 `class` 传递
    有些时候需要对内部进行样式的覆盖,如果不提供 `class` 支持,外部只能通过选择器的优先级完成.

    代码块 Vue.js Component






// 分页组件分为 Pagination, Pager复制代码
// Pagination component 复制代码
<template>复制代码
<ss-pager v-bind="$attrs" :class="pagerClass"></ss-pager>复制代码
// or复制代码
<ss-pager v-bind="pagerProps"></ss-pager>复制代码
// ...复制代码
</template>复制代码
<script>复制代码
export default {复制代码
name: 'MtdPagination',复制代码
props: {复制代码
pagerClass: string,复制代码
}复制代码
}复制代码
</script>复制代码
复制代码
  • 组件作用对应某一个原生标签时,需要使用 `v-bind="$attrs"` ,对应的也可以使用 `v-on="$lisenters"`
    这样做可以不用显示的定义全原生标签属性,而且当原生属性扩展时不需要更变

    代码块 Vue.js Component






// input component复制代码
<template>复制代码
// ...复制代码
<input v-bind="$attrs"  />复制代码
</template>复制代码
  • 组件避免出现不同属性控制相同功能、样式

    代码块 Vue.js Component






// pager component复制代码
// 不推荐复制代码
<script>复制代码
export default {复制代码
props: {复制代码
total: Number,复制代码
pageCount: Number,复制代码
pageSize: Number,复制代码
}复制代码
}复制代码
</script>复制代码
复制代码
// 推荐复制代码
<script>复制代码
export default {复制代码
props: {复制代码
total: Number,复制代码
pageSize: Number,复制代码
}复制代码
computed: {复制代码
pageCount () {复制代码
return Math.ceil(total/pageSize) || 0;复制代码
}复制代码
}复制代码
}复制代码
</script>复制代码

Data / State

  • 组件无状态,控制权交与使用者

    代码块 Vue.js Component






// switch component复制代码
<script>复制代码
export default {复制代码
props: {复制代码
actived: Boolean,复制代码
},复制代码
methods: {复制代码
handleClick () {复制代码
this.$emit('input', !this.actived); // 此时如果外部没有改变 actived 属性的值,显示依然会是原来的状态复制代码
}复制代码
}复制代码
}复制代码
</script>复制代码
  • 优先使用计算方式得出当前所需内部属性 (vue 中的 computed)
    例如: tabs 组件中,tab 组件会有 active 的状态,active 的状态应该由计算属性得出来,而不是通过 watch 来改变内部变量

    代码块 JavaScript






// better 复制代码
get active () {     复制代码
return tabsValue === this.value 复制代码
} 复制代码
// not 复制代码
watch {     复制代码
tabsValue (n) {         复制代码
this.active = n === this.value     复制代码
} 复制代码
} 复制代码
  • 避免出现内部属性的使用 (vue 的 data 函数, react 的 state)

Event

  • 在父子组件通信、属性方法定义时,当不需要方法的返回值时,原则上都应该使用事件的方式 ( Vue )

    代码块 JavaScript






// 不推荐复制代码
export default {复制代码
name: 'MtdInput',复制代码
props: {复制代码
onChange: Function,复制代码
},复制代码
methods: {复制代码
handleInput (v) {复制代码
this.onChange(v);复制代码
}复制代码
}复制代码
}复制代码
复制代码
// 推荐复制代码
export default {复制代码
name: 'MtdInput',复制代码
methods: {复制代码
handleInput (v) {复制代码
this.$emit('input', v);复制代码
}复制代码
}复制代码
}复制代码
  • 组件应该支持常用的原生事件,原生事件第一个参数应该是 event 对象

    代码块 Vue.js Component






<template>复制代码
<div>复制代码
<input v-bind="$attrs" v-on="$lisenters" :value="value" @input="handleInput" />  复制代码
</div>复制代码
</template>复制代码
<script>复制代码
export default {复制代码
name: 'MtdInput',复制代码
props: {复制代码
value: [String, Number]复制代码
},复制代码
// ...other复制代码
}复制代码
</script>复制代码
  • 原生类型事件,其行为应该同原生事件 例如: compositionstart、compositionend 事件,应该表现同原生,不应该对外发送 change 类型事件
  • change、update 类型事件第一个参数是 新值,第二个参数是 旧值

    代码块 Vue.js Component





<template>复制代码
<div></div>复制代码
</template>复制代码
<script>复制代码
export default {复制代码
props: {复制代码
visible: Boolean,复制代码
},复制代码
methods: {复制代码
handleClose () {复制代码
this.$emit('update:visible', false, this.visible);复制代码
}复制代码
}复制代码
}复制代码
</script>复制代码
  • 事件、方法参数应该避免超过3个,且越常用的参数应该越靠前
  • 方法中最后一个参数不应该是 bool 类型,应该将所有 bool 类型参数改为 object

    代码块 JavaScript





// 不推荐: 复制代码
function doSomthing (param, replace /* bool */) 复制代码
// 推荐: 复制代码
function doSomthing (param, { replace /* bool */ }) 复制代码

组件通信

  • 统一使用 事件 方式向父级通信,父级通过更改 prop 做出回应
  • 避免使用 refs
  • 避免使用 $parentVue.js 支持组件嵌套,并且子组件可访问父组件的上下文。访问组件之外的上下文违反了基于模块开发的第一原则。因此你应该尽量避免使用 this.$parent

其他

  • 组件内部不要出现魔数,如果确实有需求需要使用,必须添加注释,描述清楚数值的作用及来源,如果可能更改(该值可能出现自定义的需求),则将其作为属性,默认值为当前值
  • 样式相关需求优先考虑 `css` 或 `scss` 变量方式,如果 `css`、`scss` 实现不了,则需要在 `js` 实现时添加注释说明原因
    将样式与 `js` 分离,方便用户做样式覆盖,如果写在了 `js` 中则很大概率会使用 `style` 方式来生成样式,对于用于自定义样式来说非常困难,而且,各个页面、组件之间样式很可能有一定的关联性,一部分在 `css` 中,一部分在 `js` 中不利于管理