本篇文章给大家带来了关于ui组件的相关知识,其中主要跟大家聊聊怎么从零开始搭建一套ui组件库,有代码示例,感兴趣的朋友下面一起来看一下吧,希望对大家有帮助。

// 全局安装 vue-cli

npm install --global vue-cli



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

vue init webpack my-project



// 安装依赖

npm install



// 运行

npm run dev
登录后复制

安装过程相关选项如下:

我们默认安装jest做为我们组件库的单元测试框架,代码检查工具默认eslint

1.2 目录的优化

创建项目成功后,现在我们新项目的目录结构应该是这样的:

  • build 打包相关目录以及配置
  • config 配置文件目录
  • node_modules 项目中安装的依赖模块
  • src 源码目录
  • static 静态文件目录
  • test 单元测试目录

我们需要对现有目录做一些调整,首先我们接触过一些主流的ui组件库比如 vant/ant,我们知道在这些组件库的官网上都提供了很直观的示例页面,此时我们的组件库将src目录改名为examples,作为我们的官方示例目录。

另外我们新增一个packages目录用户存放我们的组件。

现在我们目录结构变成如下:

'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 组件文档的编写

在搭建完基础的代码环境后,我们要考虑我们新增组件的组件文档如何编写。

我们推荐使用 markdown来编写组件文档,然后我们如何在vue中使用markdown来编写我们的组件文档呢?这里我们推荐一个好用的工具。

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 编写组件文档

在我们配置完工具后,我们开始测试下组件文档的编写,

首先,我们在examples目录下新增一个docs文件夹,用于存放我们的组件文档。

新建一个test.md

 # hello world
登录后复制

接下来我们在router文件夹新增一个 docs.js路由文件,用来存放我们组件文档的路径,并将它引入到根路由文件中。

const docs = [

 {

 path: '/test',

 name: 'test',

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

 }

 ]

export default docs
登录后复制

浏览器中运行,我们便可以看到我们组件库的第一个组件文档...

<template>

    <div :class="[size]"  @click="click()">

        <span><slot></slot></span>

    </div>

</template>

<script>

 /**

 * 全局统一弹窗

 */

export default {

  name: 'sgButton',

  props: {

    size: {

      type: String,

      default: ''

    } // 按钮大小 :small large

  },

  methods: {

    click () {

      this.$emit('click')

    }

  }

}

</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 component 上,并导出:

我们需要在组件的入口文件index.js添加如下代码:

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

import sgButton from './src'



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

sgButton.install = function (Vue) {

  Vue.component(sgButton.name, sgButton)

}



 // 导出组件

export default sgButton
登录后复制

然后我们在packages目录下新增入口文件,统一处理导出所有组件:

 // 导入button组件

import sgButton from './sg-button'



 // 组件列表

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 !== 'undefined' && window.Vue) {

  install(window.Vue)

}



export default {

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

  install,

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

  sgButton

}
登录后复制

2.3 组件引入

按需引入:

import sgUi from '../packages/index'



Vue.use(sgUi.sgButton)
登录后复制

全部引入:

import sgUi from '../packages/index'



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 'vue'

import App from './App'

import router from './router'

import sgUi from '../packages/index'



Vue.config.productionTip = false



Vue.use(sgUi)

 /* eslint-disable no-new */

new Vue({

  el: '#app',

  router,

  components: { App },

  template: '<App/>'

})
登录后复制

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

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

<template>

    <div class="container">

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

      <sg-button :size="'large'">大按钮</sg-button>

      <sg-button :size="'small'">小按钮</sg-button>

    </div>

</template>

<script>

 /**

 * button 示例

 */

export default {

  name: 'buttonExample',



  methods: {



  }

}

</script>
登录后复制

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

// 本地编译组件库代码

yarn lib

// 登录

 npm login

 // 发布

 npm publish

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

 npm publish --access public
登录后复制
  1. 单元测试

Vue Test Utils 安装

以上就是手把手教你从零开始搭建一套ui组件库的详细内容,转载自php中文网

点赞(920) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部