手把手教你从零开始搭建一套ui组件库
本篇文章给大家带来了关于ui组件的相关知识,其中主要跟大家聊聊怎么从零开始搭建一套ui组件库,有代码示例,感兴趣的朋友下面一起来看一下吧,希望对大家有帮助。
1. 环境准备
我们在编写我们组件库的组件前,首先需要一套环境,包括下面几项:
- 需要为组件库单独创建一个新的项目
- 需要规划合适的目录结构
- 需要定义组件文档的编写
- 需要搭建完善的单元测试
1.1 项目的搭建
我们目前的项目是基于vue2的版本,所以本次组件库项目也将使用 2.0版本的vue cli来创建。
// 全局安装 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目录用户存放我们的组件。
现在我们目录结构变成如下:
此时如果重新运行项目会发现报错,因为我们src目录名变了,而webpack配置中默认的入口文件还是src/main.js,我们需要更改下配置,在build/webpack.base.conf文件中将src替换成examples。同时,我们需要将新增的 packages目录加入到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 组件文档的编写
在搭建完基础的代码环境后,我们要考虑我们新增组件的组件文档如何编写。
我们推荐使用 markdown来编写组件文档,然后我们如何在vue中使用markdown来编写我们的组件文档呢?这里我们推荐一个好用的工具。
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
浏览器中运行,我们便可以看到我们组件库的第一个组件文档...
以上完成,我们组件库的环境基本搭建完成了,接下来我们尝试开始写一个新的组件。
组件创建
我们先从一个基础的button组件开始。
首先我们在之前创建的packages中新增如下结构:
- sg-button 组件目录
- index.js 组件安装入口程序
- src 组件源码
2.1 组件vue源码
这里我在src/index.vue中简单实现了一个button组件,支持三种大小的按钮,
<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,运行看下效果:
效果完美,代表我们组件库第一个组件以及整体流程打通!
组件库发布
之前的环节,我们成功实现了我们组件库的第一个组件,但考虑到这只是组件库,组件库内能调用肯定是不够的,类似 vant/ant 这些组件库,我们怎么让其他用户可以使用我们的组件库组件内?
我们可以考虑发布到npm上,后续项目需要的话,我们直接通过npm安装引入的方式来调用。
发布到npm的方法也很简单, 首先我们需要先注册去npm官网注册一个账号, 然后控制台登录即可,最后我们执行npm publish即可.具体流程如下:
// 本地编译组件库代码 yarn lib // 登录 npm login // 发布 npm publish // 如果发布失败提示权限问题,请执行以下命令 npm publish --access public
单元测试
以上是手把手教你从零开始搭建一套ui组件库的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

PHP与Vue:完美搭档的前端开发利器在当今互联网高速发展的时代,前端开发变得愈发重要。随着用户对网站和应用的体验要求越来越高,前端开发人员需要使用更加高效和灵活的工具来创建响应式和交互式的界面。PHP和Vue.js作为前端开发领域的两个重要技术,搭配起来可以称得上是完美的利器。本文将探讨PHP和Vue的结合,以及详细的代码示例,帮助读者更好地理解和应用这两

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

在前端开发面试中,常见问题涵盖广泛,包括HTML/CSS基础、JavaScript基础、框架和库、项目经验、算法和数据结构、性能优化、跨域请求、前端工程化、设计模式以及新技术和趋势。面试官的问题旨在评估候选人的技术技能、项目经验以及对行业趋势的理解。因此,应试者应充分准备这些方面,以展现自己的能力和专业知识。

Django是一个Python编写的web应用框架,它强调快速开发和干净方法。尽管Django是一个web框架,但是要回答Django是前端还是后端这个问题,需要深入理解前后端的概念。前端是指用户直接和交互的界面,后端是指服务器端的程序,他们通过HTTP协议进行数据的交互。在前端和后端分离的情况下,前后端程序可以独立开发,分别实现业务逻辑和交互效果,数据的交

Go语言作为一种快速、高效的编程语言,在后端开发领域广受欢迎。然而,很少有人将Go语言与前端开发联系起来。事实上,使用Go语言进行前端开发不仅可以提高效率,还能为开发者带来全新的视野。本文将探讨使用Go语言进行前端开发的可能性,并提供具体的代码示例,帮助读者更好地了解这一领域。在传统的前端开发中,通常会使用JavaScript、HTML和CSS来构建用户界面

Django:前端和后端开发都能搞定的神奇框架!Django是一个高效、可扩展的Web应用程序框架。它能够支持多种Web开发模式,包括MVC和MTV,可以轻松地开发出高质量的Web应用程序。Django不仅支持后端开发,还能够快速构建出前端的界面,通过模板语言,实现灵活的视图展示。Django把前端开发和后端开发融合成了一种无缝的整合,让开发人员不必专门学习

Golang与前端技术结合:探讨Golang如何在前端领域发挥作用,需要具体代码示例随着互联网和移动应用的快速发展,前端技术也愈发重要。而在这个领域中,Golang作为一门强大的后端编程语言,也可以发挥重要作用。本文将探讨Golang如何与前端技术结合,以及通过具体的代码示例来展示其在前端领域的潜力。Golang在前端领域的作用作为一门高效、简洁且易于学习的

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务
