項目效果地址css
項目搭建參考 從零開始搭建 Vue 組件庫 VV-UIhtml
項目地址vue
記錄模仿 VV-UI 組件庫造輪子中遇到的問題,以及解決方案webpack
對於腳手架環境的問題,目前已經有很是成熟的 vue 官方的腳手架,咱們拿來用就行了git
npm install vue-cli -g vue init webpack origin-ui cd origin-ui npm install npm run dev
項目能夠正常啓動,在此基礎上進行改造github
|-- examples // 原 src 目錄,改爲 examples 用做示例展現 |-- assets // api文檔logo 樣式文件 |-- docs // api文檔 |-- router // api文檔路由 |-- packages // 新增 packages 用於編寫存放組件 |-- button // 組件 |-- theme-default // 組件樣式 gulp 運行目錄 |-- lib // 編譯後css |-- src // 編譯前css |-- gulpfile.js // gulp 寫打包css的task |-- salad.config.json // BEM的配置文件 |-- index.js // 導出組件
原 src 目錄,改爲 examples 用做示例展現,須要對應修改 webpack 配置web
把原先的編譯指向 src 的目錄改爲 examplesvue-cli
{ test: /\.(js|vue)$/, loader: 'eslint-loader', include: [resolve('examples'), resolve('test'), resolve('packages')],// 修改 } entry: { app: './examples/main.js' // 程序入口修改 }, resolve: { alias: { vue$: 'vue/dist/vue.esm.js', '@': resolve('examples') // 根據實際狀況修改 } },
使用vue-markdown-loader在 vue 下能夠去寫 markdown 文檔npm
# For Vue2 npm i vue-markdown-loader -D npm i vue-loader vue-template-compiler -D
webpack.config.js file:json
module.exports = { module: { rules: [ { test: /\.md$/, loader: 'vue-markdown-loader' } ] } }
在 example/docs 目錄下新建 test.md
同時建立一個新的路由,指向咱們的 md 文件:
{ path: '/test', name: 'test', component: r => require.ensure([], () => r(requi('../docs/test.md'))) }
打開瀏覽器訪問http://localhost:8080/#/test
所有配置可參考Vue 加載 Markdown 格式組件有詳細註釋
markdown-it,支持 options 選項。這樣咱們就能夠爲咱們的 markdown 定義獨特的標識符,這裏我用 demo 標識須要顯示代碼塊的地方,因此我須要配置 options 選項 :
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 ) 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' } } ] ] }
這裏簡單的描述一下這段代碼是幹什麼的:首先把內容裏面 vue 片斷編譯成 html,用於顯示,另外一方面用 highlight 來高亮代碼塊。demo-block 自己是咱們定義好的組件:
<template> <div class="docs-demo-wrapper"> <div :style="{maxHeight: isExpand ? '700px' : '0'}" class="demo-container"> <div span="14"> <div class="docs-demo docs-demo--expand"> <div class="highlight-wrapper"> <slot name="highlight"></slot> </div> </div> </div> </div> <span class="docs-trans docs-demo__triangle" @click="toggle" >{{isExpand ? '隱藏代碼' : '顯示代碼'}}</span > </div> </template>
基本用法:
::: demo <o-button>默認按鈕</o-button> :::
環境準備完畢,緊接着要開始編寫組件,考慮的是組件庫,因此咱們竟可能讓咱們的組件支持全局引入和按需引入,若是全局引入,那麼全部的組件須要要註冊到 Vue component 上,並導出:
const install = function(Vue) { if (install.installed) return components.map(component => Vue.component(component.name, component)) } export default { install }
着要實現按需加載,咱們只須要單個導出組件便可:
import Button from './button/index.js' import Row from './row/index' import Col from './col/index' const components = [Button, Row, Col] const install = function(Vue) { if (install.installed) return components.map(component => Vue.component(component.name, component)) } if (typeof window !== 'undefined' && window.Vue) { install(window.Vue) } export { install, Button, Row, Col }
既然是單頁面應用,必然要去解決樣式衝突問題,若是組件內使用 soped,那麼樣式就沒法從組件內抽離出來,達不到可定製化主題顏色的目的。咱們須要一套能夠分離處理的樣式,能夠自行編譯,能夠相互不污染。這時候 css 的 BEM 規範就顯得尤其重要。若是你還不知道什麼是 BEM 參考: http://www.w3cplus.com/css/cs...。
說到這裏,目前對 BEM 規範支持較好的插件就是 postcss 了,他容許咱們配置 BEM 之間的鏈接符和縮寫:
{ "browsers": ["ie > 8", "last 2 versions"], "features": { "bem": { "shortcuts": { "component": "b", "modifier": "m", "descendent": "e" }, "separators": { "descendent": "__", "modifier": "--" } } } }
這樣咱們就能夠把樣式單獨的抽離出來,經過 gulp 進行打包編譯:
gulp.task('compile', function() { return gulp .src('./src/*.css') .pipe(postcss([salad])) .pipe(cssmin()) .pipe(gulp.dest('./lib')) })
關於 gulp 的使用
npm install --global gulp npm install --save-dev gulp
進入 packages/theme-default 中,運行 gulp
gulp