前言
隨着前端的三大框架的出現,組件化的思想愈來愈流行,出現許多組件庫.它可以幫助開發者節省時間提升效率,
如React的Ant-design,Vue的iView,Element等,它們的功能已經很完善了.
我寫這遍文章的目的:記錄本身搭建UI庫的過程(對Vue的理解加深了好多)演示地址
首先講一下思路:
日常寫組件時,寫一個組件要用時直接導入就好了,如你寫了一個time.vue,用的時候javascript
import time from '路徑'
如今要寫一個組件庫,是否是把全部組件一個文件夾裏(如button.vue
,icon.vue
,input.vue
...),經過Vue.components
註冊全部組件,再經過Vue.use()
安裝一下就實現了,這就是因此的vue
插件的思路,沒有那麼神祕css
1.環境準備
前面說要把全部的組件放在一個文件夾裏,最簡單就是用腳手架搭一個項目目錄結構,
同時還須要添加示例文檔----方便調試和展現:
按鈕的示例效果
html
如今要考慮比較重要的兩點:目錄結構和示例文檔
1.目錄結構
直接用vue-cli創建項目結構, 在基礎上修改一下就好了(以知足咱們示例的展現)
目錄結構前端
. ├── build -------------------------webpack相關配置文件 │ ├── build.js │ ├── check-versions.js │ ├── logo.png │ ├── strip-tags.js │ ├── utils.js │ ├── vue-loader.conf.js │ ├── webpack.base.conf.js -------配置markdown設置時會用到它 │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── config ------------------------vue的基本配置 │ ├── dev.env.js │ ├── index.js │ └── prod.env.js ├── examples -----------------------放置例子 │ ├── App.vue --------------------根文件 │ ├── assets ---------------------靜態資源 │ │ ├── css --------------------css │ │ ├── img --------------------圖片 │ │ └── logo.png ---------------vue的logo │ ├── components -----------------公共組件 │ │ ├── demo-block.vue ---------盒子組件 │ │ ├── footer.vue -------------footer組件 │ │ ├── header.vue -------------header組件 │ │ └── side-nav.vue -----------側邊欄組件 │ ├── docs -----------------------例子模塊的文檔 │ │ ├── breadcrumb.md ----------麪包屑組件文檔 │ │ ├── button.md --------------按鈕組件文檔 │ │ ├── card.md ----------------卡片組件文檔 │ │ ├── guide.md ---------------簡介文檔 │ │ ├── icon.md ----------------圖標文檔 │ │ ├── install.md -------------安裝文檔 │ │ ├── layout.md --------------佈局文檔 │ │ ├── logs.md ----------------更新日誌文檔 │ │ ├── message.md -------------消息文檔 │ │ ├── start.md ---------------快速開始1文檔 │ │ ├── tag.md -----------------標籤文檔 │ │ └── twotable.md ------------二維表格文檔 │ ├── icon.json ------------------圖標數據 │ ├── main.js --------------------入口文件 │ ├── nav.config.json ------------側邊欄數據 │ └── router ---------------------路由 │ └── index.js ---------------路由配置 ├── packages -----------------------組件庫源代碼 │ ├── README.md ------------------README │ ├── breadcrumb -----------------麪包屑源碼 │ │ ├── index.js │ │ └── src │ ├── breadcrumb-item ------------麪包屑源碼 │ │ └── index.js │ ├── button ---------------------按鈕源碼 │ │ ├── index.js │ │ └── src │ ├── card -----------------------卡片源碼 │ │ ├── index.js │ │ └── src │ ├── col ------------------------列布局源碼 │ │ ├── index.js │ │ └── src │ ├── message --------------------消息源碼 │ │ ├── index.js │ │ └── src │ ├── two-dimensional-table -----二維表格源碼 │ │ ├── index.js │ │ └── src │ ├── row -----------------------行源碼 │ │ ├── index.js │ │ └── src │ ├── tag -----------------------標籤源碼 │ │ ├── index.js │ │ └── src │ ├── theme-default --------------樣式表 │ │ └── lib │ ├── package.json │ └── index.js -------------------組件庫入口 ├── index.html ---------------------主頁 ├── package.json ├── static └── README.md
以上是已經修改過的目錄結構,將腳手架生成的src目錄改成examples用來放示例文檔,因此相應的你要修改build目錄下的webpack.base.conf.js ,讓它指向examples,webpack才能正確進行打包
示例文檔,編寫文檔使用markdown最適合了,要讓vue可以實現markdown文檔能夠用vue-markdown-loader,配置相關文件在webpack.base.conf.js 的rules裏添加
就能夠開始寫文檔,測試一下vue
{ path: '/hello', name: 'hello', component: r => require.ensure([], () => r(require('../docs/hello.md'))) }
npm run dev 跑項目打開http://localhost:8080/#/hello, 能夠顯示,初步成功(基本實現)
接下來就要實現示例文檔的效果: 既能演示又有代碼展現(以下圖)
java
如上圖的示例文檔是button.md, 要讓它在button.md一個文件裏想顯示代碼的地方顯示代碼,想顯示按鈕的地方顯示按鈕,因此就要在顯示按鈕的地方打上一個標識符,webpack
讓編譯過程當中可以識別,安裝.vue的方式編譯展現仍是要用到markdown的配置,它其實封裝了markdown-it,支持options選項,只要加上定義的標識符(我用的是'demo'),options 選項的配置(也在webpack.base.conf.js 裏)git
const vueMarkdown = { preprocess: (MarkdownIt, source) => { MarkdownIt.renderer.rules.table_open = function () { return '<table class="table">' } MarkdownIt.renderer.rules.fence = utils.wrapCustomClass(MarkdownIt.renderer.rules.fence) const code_inline = MarkdownIt.renderer.rules.code_inline MarkdownIt.renderer.rules.code_inline = function (...args) { args[0][args[1]].attrJoin('class', 'code_inline') return code_inline(...args) } return source }, use: [ [MarkdownItContainer, 'demo', { // 用於校驗包含demo的代碼塊 validate: params => params.trim().match(/^demo\s*(.*)$/), render: function (tokens, idx) { var m = tokens[idx].info.trim().match(/^demo\s*(.*)$/); if (tokens[idx].nesting === 1) { var desc = tokens[idx + 2].content; // 編譯成html const html = utils.convertHtml(striptags(tokens[idx + 1].content, 'script')) // 移除描述,防止被添加到代碼塊 tokens[idx + 2].children = []; return `<demo-block> <div slot="desc">${html}</div> <div slot="highlight">`; } return '</div></demo-block>\n'; } }] ] }
其實這就是把要當解析器遇到帶demo的標識符時就會添加咱們準備好的demo-block組件,按照以上規則解析成AST(抽象語法樹),再把它編譯成html
因此寫示例文檔時,能夠這樣寫
github
2.如何編寫組件源碼
其實沒有想象中那麼難,就像日常寫組件那樣,只不過要按照必定結構編寫(具體的能夠去看個人github),通常的UI組件庫都支持全局引入和單個組件引入,
全局引入:web
const install = function(Vue) { if(install.installed) return components.map(component => Vue.component(component.name, component)) }
遍歷你寫的組件,經過Vue.component註冊到Vue上,構成一個install函數,暴露install,當你的別的項目要用時只要安裝一下包,用Vue.use()使用(像別的插件同樣)
單個文件引入:
export default { install, JButton, JCol, JRow, JTag, JBreadcrumb, JBreadcrumbItem, JCard, towTable }
相似的只要暴露出組件就OK了
別人要可以經過npm安裝包用咱們的包,咱們是否是要在包裏寫因此組件和樣式,別人只要npm安裝包和引入一個所有組件的樣式兩步驟就可使用了
3. npm發佈你的UI框架
- 你要擁有一個npm帳號(沒有的直接去官網註冊一個)
- 打開終端登陸npm
npm login
3.發佈包
咱們只有發佈packages這個文件夾就行,寫好packages文件夾下個的package.json
{ "name": "jk-ui", "version": "1.0.9", "description": "UI base on Vue", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "git+ssh://git@github.com/liuyangjike/JKUI.git" }, "keywords": [ "UI" ], "author": "Jike", "license": "ISC", "bugs": { "url": "https://github.com/liuyangjike/JKUI/issues" }, "homepage": "https://github.com/liuyangjike/JKUI#readme" }
使用npm publish發佈就OK了,別人就能夠用npm install jk-ui --save愉快的玩耍了
具體的能夠去看源碼,在github上,以爲能夠的話幫忙star一下