IDE 配置(Webstorm)
Shift + Shift
快速搜索Ctrl + V
打开VCS快捷选择器- 关闭 Safe Write 功能
Appearance... → Use "safe write"...
- 勾选允许未授权的HTTP请求
Build... → Debugger → Allow unsigned requests
- 设置CSS颜色背景
- emmet快捷模糊搜索
项目搭建
- Parcel打包
- 全局或项目安装parcel:
npm install -g parcel-bundler
- Webpack打包
html引用
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<title>Cyberpunk-ui base vue.js</title>
</head>
<body>
<div id="app">
<c-button>测试</c-button>
</div>
<script src="./src/app.js"></script>
</body>
</html>
button/index.js 注册Button组件
import CButton from './button';
CButton.install = function(Vue) {
Vue.component(CButton.name, CButton);
};
export default CButton;
app.js 直接使用注册的组件
import Vue from 'vue';
import Button from './components/button'
Vue.use(Button);
new Vue({
el: '#app',
});
初始化目录
.
├── app.js
└── components
└── button
├── button-group.vue
├── button.vue
└── index.js
对比其它UI库
Ant Design Vue 实现
- 按照类React风格实现
- 类型支持原生JS引用和TypeScript使用
- HTML模板使用Vue的JSX实现
- CSS样式使用Less编译,且放在组件目录下,便于管理
- 整体风格偏向React & JSX
- 测试用例写在组件目录
__test__
下
Element UI 实现
- 使用vue-loader关注点分离原则实现
- 类型系统采用Vue自带的props配置
- HTML模板使用Vue 原生的template编译引擎
- CSS样式使用Scss编译
- 在
/packages/theme-chalk/
目录下单独作为一个主题项目存在 - 使用gulp处理scss和font,使其自动补全浏览器前缀,压缩代码,并放入lib文件夹
- 在
- 整体风格比较纯正的Vue
- 测试用例放在
/test/unit/specs/
下
代码测试
- BDD 行为驱动开发:是一种敏捷软件开发的技术,它鼓励软件项目中的开发者、QA和非技术人员或商业参与者之间的协作。行为驱动开发的根基是一种“通用语言”,由于客户和开发者使用同一种“语言”来描述同一个系统,可以最大程度避免表达不一致带来的问题。
- TDD 测试驱动开发:倡导先写测试程序,然后编码实现其功能,测试驱动开发的目的是取得快速反馈,并使用“illustrate the main line”(说明主线)方法来构建程序。开发过程:首先,驱动代码的设计和功能的实现;其后,驱动代码的再设计和重构。
- Assert 断言:目的是为了标示与验证程式开发者预期的结果
- 前端测试常用工具:
- Karma(
[ˈkɑrmə]
卡玛)是一个测试运行器,它可以呼起浏览器,加载测试脚本,然后运行测试用例 - Mocha(
[ˈmoʊkə]
摩卡)是一个单元测试框架/库,它可以用来写测试用例 - Sinon(西农)是一个 spy / stub / mock 库,用以辅助测试(使用后才能理解)
- Chai.js 断言库
- Karma(
持续集成
.travis.yml
配置文件模板:
language: node_js
node_js:
- "12"
addons:
chrome: stable
sudo: required
before_script:
- "sudo chown root /opt/google/chrome/chrome-sandbox"
- "sudo chmod 4755 /opt/google/chrome/chrome-sandbox"
发布NPM包
- 更新 package.json
- 在 package.json 里将版本号改为 0.0.1,并随代码库更新版本
- 创建 index.js,在 index.js 里将你想要导出的内容全部导出
- 去 https://www.npmjs.com/ 注册一个账户
- 在项目目录下运行
npm adduser
- 如果错误提示里面含有 https://registry.npm.taobao.org 则说明你的 npm 源目前为淘宝源,需要更换为 npm 官方源
- 运行
npm publish
造轮子总结
Button 按钮组件
任务清单
第一期API:
- [x] Button 基本样式
- [x] Button
icon
属性 - [x] Button
iconPosition
属性 - [x] Button
loading
属性 - [x] Button
onClick
回调 - [x] ButtonGroup 组件
第二期API:
- [ ] Button
disable
属性 - [ ] Button
type
属性 - [ ] Button
size
属性 - [ ] Button
shap
属性 - [ ] Button
ghost
属性 - [ ] Button
htmlType
属性
第三期API:
- [ ] Button Link类型
- [ ] Button
href
属性 - [ ] Button
target
属性
实现要点
- ButtonGroup间距合并需要
margin-left
+:not(:first-child)
实现 - Button的icon顺序可以利用
flex + order
实现,也可以用float
实现,不过以防万一还是要清除浮动
Button的loading动画,按实际开发应该交给Icon组件,不要在button中实现,实现方法:
.c-button-loading-icon {
animation: spin 1.2s infinite linear;
}
@keyframes spin {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
Inpu 按钮组件
任务清单
第一期API:
- [x] Input 基本样式
- [x] Input
placeholder
参数 - [x] Input
size
参数 - [x] Input
disabled
参数 - [x] Input
readonly
参数 - [x] Input
change
事件监听 - [x] Input
input
事件监听 - [x] Input
focus
事件监听 - [x] Input
blur
事件监听
第二期API:
- [ ] Input
type
参数 - [ ] Input + Form 表单验证
实现要点
- 测试change/input/focus/blur事件可以使用循环的方式测试,利用spy函数测试是否被触发
- 测试触发事件可以用
new Event('input')
, 测试传参可以用Object.defineProperty添加
['change', 'input', 'focus', 'blur'].forEach((eventName) => {
vm = new Constructor({}).$mount()
const callback = sinon.fake();
vm.$on(eventName, callback)
//触发input的change 事件
let event = new Event(eventName);
Object.defineProperty(
event, 'target', {
value: {value: 'hi'}, enumerable: true
}
)
let inputElement = vm.$el.querySelector('input')
inputElement.dispatchEvent(event)
expect(callback).to.have.been.calledWith('hi')
})
Grid 网格组件
任务清单
第一期API:
- [x] Row 基本样式
- [x] Row
gutter
属性 - [x] Row
align
属性 - [x] Col 基本样式
- [x] Col span 属性
- [x] Col offset 属性
- [x] Col 响应式属性
xs, sm, md, lg, xl, xxl
第二期API:
- [ ] Row
gutter
响应式属性xs, sm, md, lg, xl, xxl
- [ ] Row
gutter
数组传参,设置上下边距 - [ ] Col
order
属性
实现要点
- 测试Row的样式必须要创建一个dom元素并挂载在
document
上,才能测到实际元素的计算样式,可以用getComputedStyle
API获取
测试Row和Col的gutter
属性,需要先创建一个dom,并用innerHTML
的方式写入row和col标签结构,然后通过vue创建vm实例,然后进行用异步测试dom中的计算样式
Vue.component('c-row', Row)
Vue.component('c-col', Col)
const div = document.createElement('div');
document.body.append(div);
div.innerHTML = `
<c-row gutter="20">
<c-col span="12"></c-col>
<c-col span="12"></c-col>
</c-row>
`;
const vm = new Vue({
el: div
});
setTimeout(() => {
const row = vm.$el.querySelector('.c-row');
expect(getComputedStyle(row).marginLeft).to.eq('-10px');
expect(getComputedStyle(row).marginRight).to.eq('-10px');
const col = vm.$el.querySelectorAll('.c-col');
expect(getComputedStyle(col[0]).paddingLeft).to.eq('10px');
expect(getComputedStyle(col[0]).paddingRight).to.eq('10px');
})
Layout 布局组件
任务清单
第一期API:
- [x] Layout / Header / Footer / Main / Aside 组件基本样式
- [x] Header、Footer
height
参数 - [x] Aside
width
参数
第二期API:
- [ ] Layout
direction
参数,接受horizontal / vertical
- [ ] 添加相关测试用例
实现要点
- 该组件主要利用flex实现,利用Layout组件的flex属性给包裹的子组件设置水平或者垂直排列
- 参考Element UI Container
Tabs 标签页组件
任务清单
第一期API:
- [x] Tabs / TabsItem / TabsHead / TabsBody / TabsPane 组件基本样式
- [x] TabsItem、TabsBody name参数
- [x] Tabs selected参数
第二期API:
- [ ] 测试用例待完善
- [ ] 三层组件优化为两层组件
- [ ] 添加
direction
属性 - [ ] 添加多个标签时左右滑动的功能
- [ ] 重构样式
实现要点
- Tabs组件核心主要用到了Vue的依赖注入和发布订阅模式实现,根节点作为派发节点
- 可以在组件上绑定data-xxx用于测试
Popover 弹出框组件
任务清单
第一期API:
- [ ] position:上下左右弹出功能
- [ ] trigger:事件触发方式 click / hover
第二期API:
- [ ] 完善左上右上左下右下八个位置
实现要点
- 利用slot插槽绝对定位弹窗的位置,同时用
getBoundingClientRect
API获取详细的位置 - 点击的时候在文档末尾插入弹窗的dom节点
- 同时在document上绑定关闭事件,点关闭的时候清除自身绑定
Collapse 折叠面板组件
任务清单
第一期API:
- [x] collapse
selected
属性 - [x] collapse-item
name
属性 - [x] collapse-item
title
属性
第二期API:
- [ ] 完善测试用例
实现要点
- 可以取父元素最后一个元素中的title去除最后一个元素的border
- 实现手风琴模式可以用eventBus和props/事件回调两种方法实现
本篇已被阅读 次