我用 Vue 造了个 UI 框架

333 阅读6分钟

官方文档 GitHub

此 UI 框架基于 Vue2 实现。
现在也有 Vue3 版本:官方文档 GitHub

这是个不太一样的 UI 框架

此 UI 框架是一个「面向源码阅读者」的框架。

也就是说,这个框架能够让前端新人学习「造轮子」的思路,源码很值得新人学习。所有代码都追求可读性。

注意:不推荐在生产环境中使用此框架!
但是:代码值得新人学习。

制作历程

框架搭建

从空目录变成一个项目,需要做哪些事情?

  • 项目放哪?

    • 因为是我个人的项目,所以我放在github仓库
  • README.md

    • 介绍
  • 选择 LICENSE & 是否开源

  • 选择什么第三方的东西

    • npm
    npm init
    

    image.png

    然后目录就会有 package.json

  • 选择用什么底层代码

    • Vue
    npm install vue
    
  • 选择用什么构建工具

    • parcel(后面用webpack)

第一个组件:button 按钮

学到的知识点:

  1. parcel
  2. scss
  3. Vue 单文件组件
  4. WebStorm 的快捷键
  5. CSS变量和:root选择器
  6. Vue.component
  7. 插槽(slot)
  8. $emit
  9. props
  10. Headless Chrome
  11. Mock
  12. npm scripts

1. 需求分析

见 「用例图」
用户点击按钮,后会出现loading,或者不可点击,PC 端 还会有 hover 状态。

2. 用例图

image.png

3. 状态分析

见 「用例图」。

4. UI 设计

image.png

5. 写代码

  • 从一个空目录如何变成一个项目?
    • 见 「框架搭建 & 持续集成」。
  • 完成项目初始化
  • 使用插槽
  • 添加 icon
    • 使用 props image.png
    • 让用户选择 icon 位置 image.png
    • 让 undefined 去掉 设置默认值
    image.png
    • 如果把图标设置在其他方向,需要给一个报错 要么写 left,要么写 tight
      验证 iconPosition 为 left 或 right 中的一个
    image.png
    • 组件化 icon.vue
    • 添加 loading 状态

6. 单元测试

这个阶段,我先不用引入任何框架,我将徒手使用简单的库,之后再改为框架的单元测试

  • 使用 chai.expect 测试
  • 使用 chai-spies
  • 自动化测试
  • 写单元测试,一定要做的是:作用域隔离和断言

7. 自动化测试

使用 Karma + Mocha做单元测试

  1. Karma([ˈkɑrmə] 卡玛)是一个测试运行器,它可以呼起浏览器,加载测试脚本,然后运行测试用例
  2. Mocha([ˈmoʊkə] 摩卡)是一个单元测试框架/库,它可以用来写测试用例
  3. Sinon(西农)是一个 spy / stub / mock 库,用以辅助测试(使用后才能理解)

8. 持续集成

使用 TravisCI 做持续集成

什么叫持续集成:

我们一开始要自己打开 Chrome 测试我们的代码
后来使用 Karma 可以做到一行命令测试我们的代码

想一想,还能不能再自动化一点。

这就是持续集成

补充:这个好像收费了

9. 发布 npm 包

npm run test 全通过才行。

  1. 更新 package.json

    1. 在 package.json 里将版本号改为 0.0.1,等我们做完了再改成 1.0.0
    2. 创建 index.js,在 index.js 里将你想要导出的内容全部导出
  2. 去 www.npmjs.com/ 注册一个账户

  3. 确认一下邮箱(必须)

  4. 在项目根目录运行 npm adduser

    • 记得将 npm 源目前为更换为 npm 官方源!!!

    image.png

  5. 运行 npm publish

最难的步骤结束了,也是一整个项目的刚开始,接下来的 UI 组件的开发会变得非常轻松

第二个组件:文本输入框

1. 用例图 & 需求分析

用户行为:
  • 输入
    • 提示
    • 报错
    • 清空
  • 复制 / 粘贴
  • 键盘、Tab、空格
  • 回车
  • 不可输入
状态
  • normal
  • focused
  • hovered
  • error / error + focused / hovered
  • success
  • disable
  • readonly

2. 写代码

  • 引入 scoped
    • 加上这个,我的组件就是独特的,唯一的
    • 引入 scoped,我这个类就可以随便写,不会和其他组件引起冲突
  • css 使用变量
  • 测试驱动开发
    • 不太适宜
    • 代码:通过描述的方法把所有功能都说一遍
  • 双向绑定

第三个组件:Grid 布局

测试多了个知识点:done 的使用

什么是 网格系统 / 栅格化设计?

就是把一个 div 分成 N 个部分(N = 12,16,24...),每个部分无空隙或者有空隙。
完。

知乎回答:在一个有限的、固定的平面上,用水平线和垂直线(虚拟的线,“参考线”),将平面划分成有规律的一系列“格子”(虚拟的格子),并依托这些格子、或以格子的边线为基准线,来进行有规律的版面布局。

使用 git 分支

两个命令:

  • git branch
  • git checkout

api 设计

  • row 行

  • col 列

  • 发现了 Vue 一个规则

    • 不能在 template,或者初始化的 div 里面加 style 标签,加了不会生效
  • 左右结构:display: flex; 两个元素都写 宽度50%

  • 使用 scss

    • scss for loop
  • 数据绑定不加冒号也不报错

    • 那就在 props 设置 Number 和 String 都可以接受

    image.png

  • 需求:支持空隙

  • 使用 counted 钩子

    • created 和 counted 的区别
    • created:在内存里创建这个组件(对象),但并没有放到页面上
    • counted:把这个组件(对象)挂载到页面上面
  • 重构代码

    • 重构 & 重写
      • 重构:微小的调整 - 每天都需要做
          1. 重复两次以上的代码
          1. 一眼看不懂的代码
      • 重写:大调整 - 隔一段时间做
  • 响应式

    pc 上为左,手机上为右

image.png

  • 默认移动端优先 Mobile First

第四个组件:Layout 布局

  • 这个是很常用的布局方式
  • 参考各 ui 组件库样式
  • 使用 Vue 动画

第五个组件:Toast

  • 需求用例

    image.png

  • UI

  • 代码

    • 使用 Vue 的 install
    • 自动关闭 image.png
    • 不要自动关闭
    • 如果已经有一个 Toast,那我再次点击就把之前的kill,然后再创建新的
    • 添加动画 image.png
  • 测试

第六个组件:Tab 标签

  • 需求分析 image.png
  • UI
  • 代码
  • 测试

第七个组件:Popover 弹出气泡

代码有很多细节

  • 代码
    • 点击按钮之外的区域关闭气泡:不要监听 body,要监听 document 因为 body 的高度并不一定是最大高度 image.png
    • 监听后要移除监听 如果不移除,会一直积累,最后点一下会很多个监听器一起响应 image.png
    • 阻止事件冒泡
      • 在点击按钮关闭的时候,其实 document 和 vm 都执行了关闭,这是事件冒泡引起的 image.png
      • 点击气泡的时候,也会被隐藏,本不应该这样,这也是事件冒泡引起的 image.png
    • 解决当容器有 overflow hidden 造成的 bug image.png
    • 表驱动编程法重构代码 重构前: image.png 重构后: image.png
    • 防止内存泄漏 用完后 remove 掉 image.png

第八个组件:Collapse 折叠面板

构建官网

使用 VuePress

总结

  1. JS、CSS、SVG 非常了解才能造 UI 轮子
  2. 没有需求就不要写代码
    没有设计稿不要写代码
  3. 单元测试是重构的前提
  4. 学 ES6+/SCSS/Webpack 这种工具类的知识能用就行
  5. 设计模式
    1. 发布订阅模式
      eventBus
      emit/on/off
    2. 单向数据流
    3. 正交
    4. 可测试的代码
    5. 不要让人思考
    6. 面向离职写代码
      1. 文档化
      2. 被观察感 → 严格要求
      3. 团队中表现优异

程序员的工作,50% 以上不是写代码。
其实,我们是工程师,而不是程序员