造輪子:寫vue組件庫orange-ui

項目搭建

項目效果地址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

實現 demo/代碼演示

  • 需求 1 就是攔截 import,而且解析 markdowm 語法
  • 需求 2 在析 markdown 中也能夠寫 Vue 的組件

所有配置可參考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
相關文章
相關標籤/搜索