ホームページ  >  記事  >  ウェブフロントエンド  >  UI コンポーネント ライブラリを最初から構築する方法を段階的に説明します。

UI コンポーネント ライブラリを最初から構築する方法を段階的に説明します。

藏色散人
藏色散人転載
2023-04-13 17:42:213153ブラウズ

この記事は、UI コンポーネントに関する関連知識を提供します。主に、UI コンポーネント ライブラリを最初から構築する方法について説明します。コード例もあります。興味のある友人は、以下を参照してください。皆さんが協力してくれることを願っています。

UI コンポーネント ライブラリを最初から構築する方法を段階的に説明します。

#1. 環境の準備

コンポーネント ライブラリのコンポーネントを作成する前に、まず次の項目を含む環境が必要です。

    コンポーネント ライブラリとは別に新しいプロジェクトを作成する必要がある
  1. 適切なディレクトリ構造を計画する必要がある
  2. #コンポーネント ドキュメントの記述を定義する必要がある
  3. ビルドする必要があります 完全な単体テスト
1.1 プロジェクトの構築

現在のプロジェクトは vue2 バージョンに基づいているため、このコンポーネント ライブラリ プロジェクトも vue cli バージョンを使用して作成されます2.0。

// 全局安装 vue-cli

npm install --global vue-cli



// 基于 webpack 创建一个的新项目

vue init webpack my-project



// 安装依赖

npm install



// 运行

npm run dev

インストール プロセス中の関連オプションは次のとおりです。

コンポーネント ライブラリの単体テスト フレームワークとしてデフォルトで jest をインストールし、コード検査ツールのデフォルトは eslint です。

1.2 ディレクトリの最適化

プロジェクトが正常に作成された後、新しいプロジェクトのディレクトリ構造は次のようになります:

ビルド パッケージ関連のディレクトリと構成
  • config 構成ファイル ディレクトリ
  • #node_modules プロジェクトにインストールされている依存モジュール
  • ##src ソース コード ディレクトリ
  • #static 静的ファイル ディレクトリ
  • #test 単体テスト ディレクトリ
  • 既存のディレクトリにいくつかの調整を加える必要があります。まず、vant/ant などのいくつかの主流の UI コンポーネント ライブラリにアクセスしました。これらのコンポーネント ライブラリの公式 Web サイトは次のとおりです。非常に直感的なサンプル ページを提供します。この時点で、コンポーネント ライブラリは src ディレクトリの名前を変更します。たとえば、公式のサンプル ディレクトリです。
  • さらに、コンポーネントを保存するための新しいパッケージ ディレクトリを追加します。
  • これで、ディレクトリ構造は次のようになります:

#この時点でプロジェクトを再実行すると、エラーが発生します。これは、src ディレクトリ名が異なるためです。が変更され、webpack の設定が変更されました。デフォルトのエントリ ファイルは依然として src/main.js です。設定を変更し、build/webpack.base.conf ファイル内の src を例に置き換える必要があります。同時に、新しいパッケージ ディレクトリを Webpack コンパイル キューに追加する必要があります。

変更された webpack.base.conf は次のようになります。

'use strict'

const path = require('path')

const utils = require('./utils')

const config = require('../config')

const vueLoaderConfig = require('./vue-loader.conf')



function resolve (dir) {

  return path.join(__dirname, '..', dir)

}



const createLintingRule = () => ({

  test: /.(js|vue)$/,

  loader: 'eslint-loader',

  enforce: 'pre',

  include: [resolve('examples'), resolve('packages'),resolve('test')],

  options: {

    formatter: require('eslint-friendly-formatter'),

    emitWarning: !config.dev.showEslintErrorsInOverlay

  }

})



module.exports = {

  context: path.resolve(__dirname, '../'),

  entry: {

    app: './examples/main.js' // 打包入口

  },

  output: {

    path: config.build.assetsRoot,

    filename: '[name].js',

    publicPath: process.env.NODE_ENV === 'production'

      ? config.build.assetsPublicPath

      : config.dev.assetsPublicPath

  },

  resolve: {

    extensions: ['.js', '.vue', '.json'],

    alias: {

      'vue$': 'vue/dist/vue.esm.js',

      '@': resolve('examples'),

    }

  },

  module: {

    rules: [

      ...(config.dev.useEslint ? [createLintingRule()] : []),

      {

        test: /.vue$/,

        loader: 'vue-loader',

        options: vueLoaderConfig

      },

      {

        test: /.js$/,

        loader: 'babel-loader',

        include: [resolve('examples'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]

      },

      {

        test: /.(png|jpe?g|gif|svg)(?.*)?$/,

        loader: 'url-loader',

        options: {

          limit: 10000,

          name: utils.assetsPath('img/[name].[hash:7].[ext]')

        }

      },

      {

        test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.*)?$/,

        loader: 'url-loader',

        options: {

          limit: 10000,

          name: utils.assetsPath('media/[name].[hash:7].[ext]')

        }

      },

      {

        test: /.(woff2?|eot|ttf|otf)(?.*)?$/,

        loader: 'url-loader',

        options: {

          limit: 10000,

          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')

        }

      }

    ]

  },

  node: {

    // prevent webpack from injecting useless setImmediate polyfill because Vue

    // source contains it (although only uses it if it's native).

    setImmediate: false,

    // prevent webpack from injecting mocks to Node native modules

    // that does not make sense for the client

    dgram: 'empty',

    fs: 'empty',

    net: 'empty',

    tls: 'empty',

    child_process: 'empty'

  }

}
再実行するとコンパイルが成功します。

1.3 コンポーネント ドキュメントの作成

基本的なコーディング環境をセットアップした後、新しいコンポーネントのコンポーネント ドキュメントを作成する方法を検討する必要があります。

コンポーネント ドキュメントを記述するにはマークダウンを使用することをお勧めしますが、vue でコンポーネント ドキュメントを記述するためにマークダウンを使用するにはどうすればよいでしょうか?ここでは便利なツールをおすすめします。

#vue-markdown-loader

##1.3.1 インストール方法

# vue1版本

npm i vue-markdown-loader@0 -D



# vue2版本

npm i vue-markdown-loader -D

npm i  vue-loader vue-template-compiler -D

1.3.2 webpack 設定webpack.base.conf に次の変更を加えています:

const VueLoaderPlugin = require('vue-loader/lib/plugin');



  module: {

    rules: [

      ...,

      {

        test: /.md$/,

        use: [

          {

            loader: 'vue-loader'

          },

          {

            loader: 'vue-markdown-loader/lib/markdown-compiler',

            options: {

              raw: true

            }

          }

        ]

      },

      ...

      ]

      },

 plugins: [new VueLoaderPlugin()]

1.3.3 コンポーネント ドキュメントの作成ツールを設定した後、コンポーネント ドキュメントの作成のテストを開始します

まず、コンポーネントのドキュメントを保存するために、example ディレクトリに docs フォルダーを追加します。

新しい test.md

 # hello world
を作成します

次に、ルーター フォルダーに docs.js ルーティング ファイルを追加して、コンポーネント ドキュメントのパスを保存し、ファイル内のルート ルートに導入します。 。

const docs = [

 {

 path: '/test',

 name: 'test',

 component: r => require.ensure([], () => r(require('../docs/test.md')))

 }

 ]

export default docs

ブラウザで実行すると、コンポーネント ライブラリの最初のコンポーネント ドキュメントが表示されます...

上記で完了です。コンポーネント ライブラリ基本的に環境が整ったので、次は新しいコンポーネントを書き始めてみましょう。

#コンポーネントの作成

基本的なボタン コンポーネントから始めます。

まず、以前に作成したパッケージに次の構造を追加します:
sg-button コンポーネント ディレクトリ

index.jsコンポーネントのインストール エントリ プログラム

src コンポーネントのソース コード

2.1 コンポーネント vue のソース コード
  • ここでは、ボタンをサポートするボタン コンポーネントを src/index.vue に実装しました。 3 つのサイズの
  • <template>
    
        <div :class="[size]"  @click="click()">
    
            <span><slot></slot></span>
    
        </div>
    
    </template>
    
    <script>
    
     /**
    
     * 全局统一弹窗
    
     */
    
    export default {
    
      name: &#39;sgButton&#39;,
    
      props: {
    
        size: {
    
          type: String,
    
          default: &#39;&#39;
    
        } // 按钮大小 :small large
    
      },
    
      methods: {
    
        click () {
    
          this.$emit(&#39;click&#39;)
    
        }
    
      }
    
    }
    
    </script>
    
    <style  scoped>
    
    .container{
    
        height: 50px;
    
        display: flex;
    
        justify-content: center;
    
        align-items: center;
    
        border: 1px solid #ccc;
    
    }
    
    .container.small{
    
        height: 40px;
    
    }
    
    .container.large{
    
        height: 60px;
    
    }
    
    </style>
  • 2.2 コンポーネントのエクスポート
  • では、このコンポーネントをどのように使用するのでしょうか。
コンポーネント ライブラリを検討しているため、コンポーネントがグローバル インポートとオンデマンド インポートをサポートするようにする必要があります。グローバルにインポートする場合は、すべてのコンポーネントを Vue コンポーネントに登録してエクスポートする必要があります:

コンポーネントのエントリ ファイルindex.jsに次のコードを追加する必要があります:

 // 导入组件,组件必须声明 name

import sgButton from &#39;./src&#39;



 // 为组件提供 install 安装方法,供按需引入

sgButton.install = function (Vue) {

  Vue.component(sgButton.name, sgButton)

}



 // 导出组件

export default sgButton

次に、パッケージ ディレクトリに新しいエントリ ファイルを追加して、統一された方法ですべてのコンポーネントを処理およびエクスポートします:

 // 导入button组件

import sgButton from &#39;./sg-button&#39;



 // 组件列表

const components = [

  sgButton

]



 // 定义 install 方法,接收 Vue 作为参数。如果使用 use 注册插件,那么所有的组件都会被注册

const install = function (Vue) {

  // 判断是否安装

  if (install.installed) return

  // 遍历注册全局组件

  components.map(component => Vue.component(component.name, component))

}



 // 判断是否是直接引入文件

if (typeof window !== &#39;undefined&#39; && window.Vue) {

  install(window.Vue)

}



export default {

  // 导出的对象必须具有 install,才能被 Vue.use() 方法安装

  install,

  // 以下是具体的组件列表

  sgButton

}

2.3 コンポーネントの紹介

オンデマンドで紹介:

import sgUi from &#39;../packages/index&#39;



Vue.use(sgUi.sgButton)

すべて紹介:

import sgUi from &#39;../packages/index&#39;



Vue.use(sgUi)

2.4 测试代码

我们在examples目录的入口文件中全局引入了组件库

 // The Vue build version to load with the `import` command

 // (runtime-only or standalone) has been set in webpack.base.conf with an alias.

import Vue from &#39;vue&#39;

import App from &#39;./App&#39;

import router from &#39;./router&#39;

import sgUi from &#39;../packages/index&#39;



Vue.config.productionTip = false



Vue.use(sgUi)

 /* eslint-disable no-new */

new Vue({

  el: &#39;#app&#39;,

  router,

  components: { App },

  template: &#39;<App/>&#39;

})

然后我们编写一个vue页面来看看是否引入成功。

首先examples中新增pages目录,存放我们以后为每个组件单独编写的示例页面,新增examples/pages/buttonExample/index.vue 页面

<template>

    <div class="container">

      <sg-button>默认按钮</sg-button>

      <sg-button :size="&#39;large&#39;">大按钮</sg-button>

      <sg-button :size="&#39;small&#39;">小按钮</sg-button>

    </div>

</template>

<script>

 /**

 * button 示例

 */

export default {

  name: &#39;buttonExample&#39;,



  methods: {



  }

}

</script>

在这里我们直接调用了三种尺寸的button,运行看下效果:

效果完美,代表我们组件库第一个组件以及整体流程打通!

  1. 组件库发布

之前的环节,我们成功实现了我们组件库的第一个组件,但考虑到这只是组件库,组件库内能调用肯定是不够的,类似 vant/ant 这些组件库,我们怎么让其他用户可以使用我们的组件库组件内?

我们可以考虑发布到npm上,后续项目需要的话,我们直接通过npm安装引入的方式来调用。

发布到npm的方法也很简单, 首先我们需要先注册去npm官网注册一个账号, 然后控制台登录即可,最后我们执行npm publish即可.具体流程如下:

// 本地编译组件库代码

yarn lib

// 登录

 npm login

 // 发布

 npm publish

 // 如果发布失败提示权限问题,请执行以下命令

 npm publish --access public
  1. 单元测试

Vue Test Utils 安装

以上がUI コンポーネント ライブラリを最初から構築する方法を段階的に説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。