分享

vue组件库开发

 15所 2019-11-03

为何要进行组件库开发

如果你所在的公司对于页面的样式没有什么要求,那么你只要随便拿一个组件库来用就行了,比如element、iView等等,不用再重复造轮子了;
如果你目前只有个人用一个组件,或者是只对个别组件有要求,那么只要在你的工程里面开发一个.vue单文件组件就可以了;如果你的团队想要一个更加快速的开发方式,希望有一套一类应用的标准,并且对组件的样式有较高的要求,那么你就需要开发一个组件库了。

正确的学习方式

我觉得我写完这篇文章以后,大家看完可能只是能按部就班地开发一个组件库而已,而且具体的记忆和理解不是很深,所以我觉得正确的方式应该是站在巨人的肩膀上,比如去查看element组件库的源码,去了解他的文件组织方式,文档是如何管理的,主题文件是如何管理的,以及一些复杂组件是如何实现的。接下来,我们就进入正题。

步骤

我们来理一下整个步骤:

  1. 创建项目
  2. 调整项目结构
  3. 编写组件
  4. 使用vue-cli-service库模式打包编译
  5. 发布到npm

创建项目

# 创建目录mkdir frog-ui# 切换目录cd frog-ui# 初始化项目vue create .

调整目录

将项目的目录调整到以下形式,该目录方式像是成了业界不成名的规定,element和iview都是以这样的方式组织的。我觉得挺好的,所以不做修改了。

image.png

其中:

|-- examples  // 为原来的src目录改名而来,用于测试编写的组件|-- packages  // 用于组织我们的组件库

目录调整以后,我们需要修改相应的webpack配置,使原来的src目录指向修改后的examples目录,修改vue.config.js文件:

const path = require('path')function resolve (dir) { return path.join(__dirname, '..', dir)}module.exports = { // 将entry指向examples pages: { index: { entry: 'examples/main.js', template: 'public/index.html', filename: 'index.html' } }, // 为packages目录添加babel-loader处理 chainWebpack: config => { config.module .rule('js') .include .add(resolve('packages')) .end() .use('babel') .loader('babel-loader') .tap(options => { return options }) }}

编写组件

packages目录下面的文件组织情况如下:

image.png

其中:

|-- datePicker      // 新编写的组件,以datepicker为例|-- theme-default   // 主题文件

主题文件较为特殊,他作为单独的一个包进行发布引入,方便进行主题发布,后面再进行介绍。下面对datePicker进行介绍:

datePicker.vue

<template> <div>这是一个datePicker组件</div></template><script>export default { name: 'datePicker'}</script>

datePicker/src/index.js

// 导入组件,组件必须声明 nameimport datePicker from './src/datePicker.vue'// 为组件提供 install 安装方法,供按需引入datePicker.install = function (Vue) {  Vue.component(datePicker.name, datePicker)}// 默认导出组件export default datePicker</script>

批量注册组件

// 导入日期选择器组件import datePicker from './datePicker'// 存储组件列表const components = [ datePicker]// 定义 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, // 以下是具体的组件列表 ...components}

本地测试组件

我们的组件以及编写完成,第一步先在本地进行测试:
examples/main.js

import Vue from 'vue'import App from './App.vue'import router from './router'// 导入组件库import datePicker from './../packages/index'import './../packages/theme-default/src/test.scss'// 注册组件库Vue.use(datePicker)Vue.config.productionTip = falsenew Vue({  router,  render: h => h(App)}).$mount('#app')

examples/views/home.vue

<template> <div class='home'> <datePicker></datePicker> </div></template><script>export default { name: 'home'}</script>

如何在浏览器中就可以看到我们的组件运行成功了,下一步就是要将我们的代码打包成npm库了,那么需要通过vue-cli3中vue-cli-service的库模式进行打包。

库模式打包

# package.json'script': {    'build-lib': 'vue-cli-service build --target lib --name frog-ui --dest lib packages/index.js  && npm run build-theme',}

库模式的介绍:点击这里
执行:

npm run build-lib

项目的根目录新增了lib文件夹,内容如下


image.png

其中:

  • lib/frog-ui.common.js:一个给打包器用的 CommonJS 包
  • lib/frog-ui.umd.js:一个直接给浏览器或 AMD loader 使用的 UMD 包
  • lib/frog-ui.umd.min.js:压缩后的 UMD 构建版本

修改package.json

修改packages.json,目前我的项目的完整package.json如下:

{  'name': 'frog-ui',  'version': '0.1.0',  'private': false,  'lisence': 'MIT',  'main': 'lib/frog-ui.umd.min.js',  'scripts': {    'serve': 'vue-cli-service serve',    'build': 'vue-cli-service build',    'build-lib': 'vue-cli-service build --target lib --name frog-ui --dest lib packages/index.js  && npm run build-theme',    'build-theme': 'gulp build --gulpfile packages/theme-default/gulpfile.js && cp-cli packages/theme-default/lib lib/theme-default',    'lint': 'vue-cli-service lint'  },  'dependencies': {    'core-js': '^2.6.5',    'vue': '^2.6.10',    'vue-router': '^3.0.3'  },  'devDependencies': {    '@vue/cli-plugin-babel': '^3.7.0',    '@vue/cli-plugin-eslint': '^3.7.0',    '@vue/cli-service': '^3.7.0',    '@vue/eslint-config-standard': '^4.0.0',    'babel-eslint': '^10.0.1',    'cp-cli': '^2.0.0',    'eslint': '^5.16.0',    'eslint-plugin-vue': '^5.0.0',    'gulp': '^4.0.2',    'gulp-autoprefixer': '^6.1.0',    'gulp-cssmin': '^0.2.0',    'gulp-sass': '^4.0.2',    'markdown-it-anchor': '^5.0.2',    'markdown-it-container': '^2.0.0',    'markdown-it-decorate': '^1.2.2',    'markdown-it-task-checkbox': '^1.0.6',    'node-sass': '^4.12.0',    'sass-loader': '^7.1.0',    'vue-markdown-loader': '^2.4.1',    'vue-template-compiler': '^2.5.21'  }}

主要要修改的是:

{ 'private': false, // 是否私有,必须指定为false才能发布到npm 'main': 'lib/frog-ui.umd.min.js', // 编译后包的入口文件}

根目录添加.npmignore文件

发布到npm下,只需要lib目录、package.json 和readme.md文件,所以需要忽略掉其他的目录
.npmignore

examples/packages/public/vue.config.jspostcss.config.jsbabel.config.js*.map

发布npm

# 设置要发布的源,我发布的是通过verdaccio搭建的私库npm config set registry http://registry.# 登录npm login# 发布npm publish

下图可以看到,我们的包发布成功了,关于私库的搭建可以查看我另外的文章。


image.png

总结

整个过程有一点点繁琐,但是能学到一些意外的知识,希望大家能够动手尝试。能力有限,文章中有写得不对的地方请大家见谅。如果对你有帮助的话,可以帮忙点个赞哦 ~

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多