04.ElementUI原始碼學習:元件封裝、說明文件的編寫釋出

Anduril 發表於 2021-04-21

0x00.前言

書接上文。專案經過一系列的配置,開發腳手架已經搭建完畢。接下來開始封裝自定義元件、並基於 markdown 檔案生成文件和演示案例。

後續文章程式碼會根據篇幅,不影響理解的情況下進行部分刪減,詳細程式碼可在 Github Repo 檢視。

0x01.封裝第一個元件

封裝元件

接下來封裝一個loading元件。

建立 packages/loading/src/main.vue 檔案(篇幅問題,樣式程式碼詳見Github)。

carbon (54).png

建立 packages/loading/index.js 檔案。使用 install 方法來全域性註冊該元件,安裝元件通過全域性方法 Vue.use() 即可。官網-Vue外掛

carbon (49).png

建立 src/index.js 檔案,該檔案的作用:

  1. 匯入元件庫所有元件
  2. 定義元件庫元件註冊安裝的install 方法
  3. 整體匯出版本、install、各個元件等。

carbon (51).png

引用元件

examples/main.js 檔案中引用元件庫

carbon (53).png

examples/App.vue 中新增元件引用

carbon (52).png

頁面效果如下

page.gif

0x02.編寫元件說明文件

接下來基於 markdown 編寫元件文件,能讓示例程式碼像元件一樣在頁面中渲染。

md-loader

markdown 檔案的解析基於markdown-it 及其社群外掛。

  1. markdown-it 主要的解析器/渲染器。官方文件
  2. markdown-it-anchor 生成標題錨點。官方文件
  3. markdown-it-container 建立塊級自定義容器的解析外掛。官方文件
  4. markdown-it-chain 支援鏈式呼叫 markdown-it 。官方文件
npm i  -D  markdown-it markdown-it-anchor markdown-it-container markdown-it-chain

其他核心外掛

npm i -D transliteration // 漢字轉拼音

自定義loader
專案將使用element的自定義loader,在原始碼目錄 build\md-loader 建立檔案,目錄結構如下。

├─md-loader
|     ├─config.js
|     ├─containers.js
|     ├─fence.js
|     ├─index.js
|     └─util.js

index.js檔案是loader的入口檔案,通過提取template 與 script 的內容,把 Markdown 轉化成 Vue 元件。

carbon (57).png

config.js檔案使用 markdown-it-chain 配置markdown-it選項、外掛和容器資訊,初始化markdown-it例項。

carbon (58).png

containers.js檔案使用 markdown-it-container 來轉換自定義容器,將自定義容器 :::demo轉換成 demo-block 元件。

carbon (59).png

fence.js檔案中重寫了程式碼塊(fence)預設渲染規則。

carbon (60).png

util.js檔案提供 stripScript stripStyle stripTemplate genInlineComponentText等方法用於頁面內容提取和生成元件。

carbon (61).png

webpack 配置

建立build/config.js檔案設定 webpack 公共配置資訊。

carbon (62).png

更新 build\webpack.config.js檔案,新增自定義 md-loder ,實現 markdown 檔案的解析。

carbon (63).png

編寫文件

編寫元件說明文件examples\docs\loading.md

carbon (56).png

安裝 vue-router 外掛。

npm i -D vue-router  

新增 examples/router.js 檔案配置路由資訊。

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const routes = [
  {
    path: '/',
    name: 'index',
    //使用vue的非同步元件技術 , 可以實現按需載入 .
    component: (resolve) => require(['./components/HelloWorld.vue'], resolve), 
  },
];

routes.push({
  path: '/test',
  name: 'test',
  component: (resolve) => require(['./docs/loading.md'], resolve),
});

routes.push({
  path: '/jsx',
  name: 'jsx',
  component: (resolve) => require(['./components/JSX.vue'], resolve), 
});

export default new VueRouter({
  mode: 'hash',
  base: process.env.NODE_ENV !== 'production' ? '/' : '/me-ui',
  routes,
});

carbon (64).png

調整 examples 目錄下文件結構如下,詳見原始碼。

├─examples
|    ├─App.vue
|    ├─main.js
|    ├─router.js
|    ├─docs
|    |  └loading.md
|    ├─components
|    |     ├─HelloWorld.vue
|    |     └JSX.vue
|    ├─assets
|    |   └logo.png

examples\main.js 引入路由,examples\App.vue 更新路由導航資訊。

// main.js
...
...
import router from './router'; 
...
new Vue({
  router,
  render: (h) => h(App),
}).$mount('#app');

// App.vue
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> | <router-link to="/jsx">JSX</router-link> |
      <router-link to="/test">loading元件</router-link>
    </div>
    <router-view />
  </div>
</template>

頁面效果如下

Animation12.gif

demo-block 元件

上面的說明文件功能十分簡陋,接下來編寫 demo-block 元件,支援示例元件渲染、高亮程式碼等功能。

安裝語法高亮外掛 highlight.js

npm i -D highlight.js    // 程式碼高亮

建立 examples\components\demo-block.vue 元件

carbon (19).png

examples\main.js 引入 highlight 外掛、 demo-block 元件,配置語法高亮主題樣式。增加 afterEach 全域性後置鉤子,高亮頁面程式碼塊。

carbon (20).png

元件說明文件 examples\docs\loading.md 更新成約定的文件格式。

carbon (21).png

執行程式,頁面示例程式碼塊渲染元件,可以展開收起原始碼,語法高亮顯示,效果如下:

page1.gif

0x03.示例程式碼

Github Repo

0x04.參考

Element 文件中的 Markdown 解析
element的demo-block
highlight 97種主題樣式列表