Skip to content

组件开发指南

GU Yiling edited this page Aug 31, 2017 · 11 revisions

代码规范

VEUI 配置的 ESLint 检查规则对应 Vue.js 社区的主流规范:JavaScript Standard Style

和百度规范相比主要区别:

  • 2 空格缩进
  • 行尾非必要不加分号
  • function 参数列表的 ( 前始终有一个空格

其他的根据开发工具的提示很快就能掌握。

组件设计

组件样式

VEUI 的组件库和样式是分离的 npm 包。样式代码单独维护,在 veui 中的单文件组件中不允许编写样式代码。

VEUI 用 class 来描述组件的类型,用 ui 属性表达组件在样式上的变种,如:

// 组件内部实现时的 class
<button class="veui-button">...</button>

// 使用组件时通过 ui 属性传入样式变种
<veui-button ui="primary large">确定</veui-button>

书写样式时,项目配置已加入了 Less 编译,并且自动注入了 est 提供的 mixin。通过属性选择器来查找为组件配置的 ui 属性,并设置对应的样式:

// veui-theme-dux/components/button.less
@import "../lib.less"; // 引入 VEUI 定义的变量和 mixin

.veui-button {
  color: @veui-theme-color-primary; // 定义在 veui-theme-dux/variables.less 中
  // ...

  &[ui~="primary"] {
    .veui-shadow(); // 定义在 veui-theme-dux/mixins.less 中
  }
}

然后通过 veui-loaderveui-babel-plugin 来在引入组件文件(.vue 或者 .js)时自动引入样式包中对应的样式文件。

组件行为

使用 Vue.js 中的 props 来传递控制逻辑的数据。

<veui-button ui="primary" :loading="loading">确定</veui-button>

如果组件有对应的原生 DOM 控件,那么实现组件时,应该尽可能接近原生 DOM 的行为,例如原生 <button> 可以通过 namevalue 属性作为 <form> 提交数据的来源,那么在实现组件是应尽量支持此逻辑,将这样的 prop 透传给原生组件。

第三方库

目前确定使用的第三方库有 Moment.js、Lodash 和 Tether。

对于 Lodash,引入方式如下:

import { includes, pick } from 'lodash'

由于启用了 babel-plugin-lodash,以上代码会被转换为:

import includes from 'lodash/includes'
import pick from 'lodash/pick'

使用 Lodash 的原则一般是先尽量用 ES5 原生方法,如果功能不满足需求,才引 Lodash 相关的方法。ES Next 对原生对象的扩展,全部优先使用 Lodash,禁止使用 ES Next 新增的原型方法(因为没有类型推断的情况下,Babel 无法正确 polyfill 原型方法)。

开发约定

props

  • 尽量选择简单直接的词汇
  • 足够表达时,对于 Boolean 型的 prop使用 is/has 前缀,用更接近 HTML 原生属性的方式提高一致性
  • 对于 Boolean 型的 prop,逻辑应设计为默认逻辑取 false 值,例如 disabledautofocus,这样在传递参数时可以直接省略以取默认值
  • 对于输入组件,应当实现 v-model 所需的逻辑
  • 对于需要和外部保持同步的 prop,应当实现 .sync 修饰符必须的 $emit('update:prop', value) 逻辑

data

  • prop 的本地副本,命名需带 local 前缀,例如 valuelocalValue,须要 watch 对应 prop 变化并同步本地值

computed

  • propdata 中数据项的计算后版本(具有很接近的语义时),需有 real 前缀,例如 keysrealKeys

methods

  • 方法仅在必要时提供,只读项可以考虑以 computed 的形式提供,已利用 Vue 自带的缓存机制

事件命名

  • 不使用过去式如:changedselected
  • 事件名采用全小写的动词,参考大多数 DOM 原生事件。少数必须表明触发时机的,参考 beforeunload

组件

  • 每个组件必须提供带 veui-${componentName} 前缀的 name 属性
  • 组件容器必须带有名为 veui-${componentName}class,内部元素尽量也使用以此为前缀的 class

输入组件

  • 每个输入组件必须实现 v-model
  • 每个输入组件必须混入 mixin/input.js
  • 每个组件的 name/disabled/readonly 属性最终状态依赖外层控制,主要是 Form 系列组件,可以对其下层的所有 InputComponent 进行状态控制,参考 realName/realDisabled/realReadonly 属性,特殊 name 情况,比如需要唯一 name,参考 Radiobox 组件
  • 组件的校验会在 Form 系列组件中进行,具体参考 Form/Fieldset/Field
  • Field 中需要 lable[for=id] 功能的组件,需要自己实现 methods.activate