# 控件开发流程

# 1. 安装依赖

全局安装 lerna

npm i lerna -g

后续以新建控件 test 为例。

# 2. 创建 npm 包

packages 下新建文件夹 test

cd .\packages\
md test

进入控件目录,后续操作均在该文件目录下进行

cd .\test\

执行命令

npm init

生成 package.json

{
  // @hui-pro 为 scope 名
  "name": "@hui-pro/test",
  // 新增控件版本号默认为 1.0.0,版本升级时会自动提升
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  // 作者名写开发者名字
  "author": "author",
  "license": "ISC"
}

# 当前的目录结构

├── packages      
│   └── test
│      └── package.json

# 3. 创建代码逻辑

新建文件夹 src

md src

新建文件 src/test.vuetest.vue 里写控件代码逻辑。

新建文件夹 index.js,注册并抛出 test 控件

// index.js
import Test from './src/test';

const install = function(Vue) {
  Vue.component(Test.name, Test);
};

export default {
  install
};

# 当前的目录结构

├── packages
│   └── test
│      ├── src
│      │  └── test.vue
│      ├── index.js
│      └── package.json

# 4. 创建样式

新建文件夹 theme

md theme

新建文件 theme/index.scss,在文件顶部引入公共样式

@import '~@hui-pro/theme/index.scss';

现在可以开始写控件样式,推荐使用 BEM 的命名规范来创建控件的样式名,也可以参考:https://segmentfault.com/a/1190000012705634

// theme/index.scss
@import '~@hui-pro/theme/index.scss';

@include b(test) {
  ...
  @include e(input) {
    ...
    @include m(success) {
      ...
    }
  }
  @include when(active) {
    ...
  }
}

# 更改 package.json

由于依赖了 @hui-pro/theme,因此需要在 package.json 中加上该依赖包

{
  "name": "@hui-pro/test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "author": "author",
  "license": "ISC",
  "dependencies": {
    // 具体查看 theme 的实际版本
    "@hui-pro/theme": "^1.0.0"
  }
}

# 当前的目录结构

├── packages
│   └── test
│      ├── src
│      │  └── test.vue
│      ├── theme
│      │  └── index.scss
│      ├── index.js
│      └── package.json

# 5. 引入字体图标(可选)

如果你的控件里有字体图标,需要在控件样式中单独引入。

新建文件夹 theme/fonts

md theme/fonts

将字体图标文件放入到 theme/fonts ,然后创建文件 theme/fonts.scss,里面放字体图标的样式。

控件的样式文件需要定义字体图标路径变量 $--[控件名]-font-path,注意务必加上后缀 !defalut

// theme/index.scss
@import '~@hui-pro/theme/index.scss';
$--test-font-path: 'fonts' !default;
@import './fonts.scss';

@include b(test) {
  ...
}

theme/fonts.scss 进行改造,引入字体图标路径变量

// theme/fonts.scss
@font-face {
  font-family: 'batchSelectorFont';
  font-style: normal;
  font-weight: normal;
  src: url('#{$--test-font-path}/testFont.eot?kfk1j9');
  src: url('#{$--test-font-path}/testFont.eot?kfk1j9#iefix')
      format('embedded-opentype'),
    url('#{$--test-font-path}/testFont.ttf?kfk1j9') format('truetype'),
    url('#{$--test-font-path}/testFont.woff?kfk1j9') format('woff'),
    url('#{$--test-font-path}/testFont.svg?kfk1j9#batchSelectorFont')
      format('svg');
}

在项目中使用控件时,需要手动修改字体图标路径,需要在 Demo 网站上进行说明,参考 Plan 计划模板控件

# 当前的目录结构

├── packages
│   └── test
│      ├── src
│      │  └── test.vue
│      ├── theme
|      │  ├── fonts
│      │  |  └── testFont.eot
│      │  |  └── testFont.svg
│      │  |  └── testFont.ttf
│      │  |  └── testFont.woff
│      │  └── fonts.scss
│      │  └── index.scss
│      ├── index.js
│      └── package.json

# 6. 创建多语言(可选)

如果当前控件有多语言,需要在控件中创建并引入。

新建文件夹 lang

md lang

新建文件 lang/zh_CN.jslang/en_US.js 文件

// zh_CN.js
module.exports = {
  h: {
    test: {
      save: '保存',
      cancel: '取消'
    }
  }
}
// en_US.js
module.exports = {
  h: {
    test: {
      save: 'save',
      cancel: 'cancel'
    }
  }
}

src/test.vue 中的用法

<!-- src/test.vue -->
<template>
  <div class="h-test">
    <el-button>{{ t('h.test.save') }}</el-button>
    <el-button>{{ t('h.test.cancel') }}</el-button>
  </div>
</template>

<script>
  import { t } from '@hui-pro/locale'

  export default {
    // 如果 template 中有使用 t 方法,需要在 data 中进行申明,没有则不需要
    data() {
      t
    },

    computed: {
      test() {
        return `${t(`h.batchSelector.hasSelect`)}`;
      }
    }
  }
</script>

# 更改 package.json

由于依赖了 @hui-pro/locale,因此需要在 package.json 中加上该依赖包

{
  "name": "@hui-pro/test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "author": "author",
  "license": "ISC",
  "dependencies": {
    "@hui-pro/theme": "^1.0.0",
    // 具体查看 locale 的实际版本
    "@hui-pro/locale": "^1.0.0"
  }
}

# 当前的目录结构

├── packages
│   └── test
│      ├── lang
│      │  └── en_US.js
│      │  └── zh_CN.js
│      ├── src
│      │  └── test.vue
│      ├── theme
│      │  └── index.scss
│      ├── index.js
│      └── package.json

# 7. 内部控件依赖(可选)

如果当前控件依赖 HUI-Pro 的内部控件,需要在自身控件注册时,一起注册依赖的控件,并在样式中引入依赖控件的样式。

比如 test 依赖控件 highlight,改造 index.jstheme/index.scss

// index.js
import Highlight from '@hui-pro/highlight/src/highlight.vue';
import Test from './src/test';

const install = function(Vue) {
  Vue.component(Highlight.name, Highlight);
  Vue.component(Test.name, Test);
};

export default {
  install
};
// theme/index.scss
@import '~@hui-pro/theme/index.scss';
@import '~@hui-pro/highlight/theme/index.scss';

@include b(test) {
  ...
}

# 更改 package.json

由于依赖了 @hui-pro/highlight,因此需要在 package.json 中加上该依赖包

{
  "name": "@hui-pro/test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "author": "author",
  "license": "ISC",
  "dependencies": {
    "@hui-pro/theme": "^1.0.0",
    "@hui-pro/locale": "^1.0.0",
    // 具体查看依赖控件的实际版本
    "@hui-pro/highlight": "^1.0.0"
  }
}

# 8. 关联控件

此时需要将该控件(npm包)link 到根目录的 node_modules,执行以下命令

npm run bootstrap

然后你可以查看根目录下的 node_modules 文件夹中是否存在你所迁移的 npm 包,路径为 node_modules/@hui-pro/test

如果发现link不上,那么先执行 lerna clean,然后执行 lerna bootstrap

# 9. 创建Demo

docs/zh/widget 下对应分类,创建文件 test.md

打开 docs/vuepress/zh.sidebar.json,按照其中的规范添加控件路径 /zh/widget/.../test

test.md 中书写 Demo 和 API,具体规范参考 Demo文档书写规范

# 10. 提交代码

.cz-config.js 文件中添加 scope,然后再提交代码。

// .cz-config.js
scopes: [
  ...
  { name: 'test' },
  ...
]

具体规范参考:代码提交规范

# 11. 自测用例

即将上线