教你搭建按需加载的Vue组件库(小结)


Posted in Javascript onJuly 29, 2019

按需加载的原理

按需加载,本质上是把一个组件库的不同组件 拆分成不同文件 ,按照需要引用对应的文件,而该文件暴露一个 install方法 ,供Vue.use使用。 比如:我只想引用element库里的一个Button组件

import Button from 'element-ui/lib/Button.js'
import Button from 'element-ui/lib/theme-chalk/Button.css'

Vue.use(Button);

上面的写法比较繁琐,而且需要知道每个组件的实际路径,使用起来并不方便,所以我们还需要借助一个转换插件。

先来看看 element 是怎么做的,官方的的「快速手上」:

教你搭建按需加载的Vue组件库(小结)

element使用一个了babel插件,作用就是代码转换:

import { Button } from 'components'

// 转换为

var button = require('components/lib/button')
require('components/lib/button/style.css')

到这我们可以知道,要搭建一个按需加载的组件库。 主要工作 需要两点:

  1. 组件独立打包 ,单个文件对应单个组件
  2. 引入 代码转换 的插件

组件代码的编写规范

我们在项目的跟目录建一个文件夹packages,下面放我们的组件:

教你搭建按需加载的Vue组件库(小结)

packages下每一个文件夹对应一个组件所需要的资源,在index.js定义组件的install方法。而packages/index.js存放了在全量加载时用的install方法

packages/Button/index.js:

import Button from './src/main';

Button.install = function(Vue) {
 Vue.component(Button.name, Button);
};

export default Button;

packages/Button/src/main.vue:

<template>
 <div>
 我是一个Button组件
 </div>
</template>

packages/index.js:

import Button from './Button';
import Loading from './Loading';
import LoadMore from './LoadMore';

const components = [
 Button,
 LoadMore,
 Loading
];

const install = function(Vue) {
 components.forEach(component => {
 Vue.component(component.name, component);
 });
}

if (typeof window !== 'undefined' && window.Vue) {
 install(window.Vue)
}

export default {
 install, // 全量引入
 Button,
 LoadMore,
 Loading
};

webpack配置

组件代码写好了,接下来需要配置一下webpack的打包逻辑。我们复用vue-cli生成的模板,在上面做一些必要更改:

多入口

每个组件独立生成一个对应的js和css,这就需要我们在入口处就把组件的引用定义好:

webpack.prod.conf.js:

const entrys = {
 Button: path.resolve(__dirname, '../packages/Button'),
 index: path.resolve(__dirname, '../packages')
};

const webpackConfig = merge(baseWebpackConfig, {
 entry: entrys,
 // ......
});

上述配置每增加一个组件都需要修改entrys,我们可以优化一下,使其 动态生成

webpack.prod.conf.js:

const entrys = require(./getComponents.js)([组件目录入口]);
const webpackConfig = merge(baseWebpackConfig, {
 entry: entrys,
 ......
});

getComponents.js:

const fs = require('fs');
const path = require('path');

/**
 * 判断刚路径是否含有index.js
 * @param {String} dir 
 */
function hasIndexJs(dir) {
 let dirs = [];
 try {
  dirs = fs.readdirSync(dir);
 } catch(e) {
  dirs = null;
 }
 return dirs && dirs.includes('index.js');
}

/**
 * 获取指定入口和入口下包含index.js的文件夹的路径
 * @param {String} entryDir 
 */
const getPath = function(entryDir) {
 let dirs = fs.readdirSync(entryDir);
 
 const result = {
  index: entryDir
 };
 dirs = dirs.filter(dir => {
  return hasIndexJs(path.resolve(entryDir, dir));
 }).forEach(dir => {
  result[dir] = path.resolve(entryDir, dir); 
 });
 return result;
}

module.exports = getPath;

修改webpack的输出

默认生成的js文件并不支持ES6引入,在这里我们设置成 umd

output: {
 path: config.build.assetsRoot,
 filename: utils.assetsPath('[name].js'),
 library: 'LoadOnDemand',
 libraryTarget: 'umd'
},

配置 babel-plugin-component -D

上面的组件库打包发布到npm上之后。我们在使用的时候npm install babel-plugin-component -D之后,修改一下.babelrc.js:

"plugins": [
 [
  "component",
  {
  "libraryName": "load-on-demand", // 组件库的名字
  "camel2Dash": false, // 是否把驼峰转换成xx-xx的写法
  "styleLibrary": {
   "base": false, // 是否每个组件都默认引用base.css
   "name": "theme" // css目录的名字
  }
  }
 ]
 ],

这里提一下属性 camel2Dash ,默认是开启的,开启状态下假如你的组件名是vueCompoent,引用的css文件会变成vue-component.css。

结语

上面demo的代码放在了个人github github.com/jmx16449196… 大家如果有更好的实现方法,或者我上面还有什么需要更正的错误,欢迎交流。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js实现页面打印功能实例代码(附去页眉页脚功能代码)
Dec 15 Javascript
jquery之empty()与remove()区别说明
Sep 10 Javascript
JavaScript操纵窗口的方法小结
Jun 28 Javascript
浅谈JavaScript正则表达式分组匹配
Apr 10 Javascript
JavaScript仿flash遮罩动画效果
Jun 15 Javascript
javascript创建对象的3种方法
Nov 02 Javascript
实现easyui的datagrid导出为excel的示例代码
Nov 10 Javascript
JS填写银行卡号每隔4位数字加一个空格
Dec 19 Javascript
JS实现仿PS的调色板效果完整实例
Dec 21 Javascript
详解Vue结合后台的列表增删改案例
Aug 21 Javascript
AngularJS 事件发布机制
Aug 28 Javascript
js实现ATM机存取款功能
Oct 27 Javascript
JavaScript 继承 封装 多态实现及原理详解
Jul 29 #Javascript
Vue2.0实现简单分页及跳转效果
Jul 29 #Javascript
JavaScript面向对象程序设计中对象的定义和继承详解
Jul 29 #Javascript
js实现多张图片每隔一秒切换一张图片
Jul 29 #Javascript
javascript面向对象程序设计实践常用知识点总结
Jul 29 #Javascript
javascript中this的用法实践分析
Jul 29 #Javascript
学习LayUI时自研的表单参数校验框架案例分析
Jul 29 #Javascript
You might like
PHP+DBM的同学录程序(4)
2006/10/09 PHP
PHP解压ZIP文件到指定文件夹的方法
2016/11/17 PHP
PHP实现微信退款的方法示例
2019/03/26 PHP
discuz论坛更换域名,详细文件修改步骤
2020/12/09 PHP
jQuery easyui datagrid动态查询数据实例讲解
2013/02/26 Javascript
JQuery实现倒计时按钮具体方法
2013/11/14 Javascript
JavaScript的作用域和块级作用域概念理解
2014/09/21 Javascript
jsp 网站引入外部css或者js失效问题解决
2016/10/31 Javascript
HTML5 js实现拖拉上传文件功能
2020/11/20 Javascript
微信小程序引用公共js里的方法的实例详解
2017/08/17 Javascript
微信小程序实现签到功能
2018/10/31 Javascript
对vue生命周期的深入理解
2020/12/03 Vue.js
详解uniapp的全局变量实现方式
2021/01/11 Javascript
Python argv用法详解
2016/01/08 Python
Python中的groupby分组功能的实例代码
2018/07/11 Python
Python GUI编程完整示例
2019/04/04 Python
在Qt5和PyQt5中设置支持高分辨率屏幕自适应的方法
2019/06/18 Python
Python 获取numpy.array索引值的实例
2019/12/06 Python
python数据预处理 :样本分布不均的解决(过采样和欠采样)
2020/02/29 Python
Django 自定义权限管理系统详解(通过中间件认证)
2020/03/11 Python
设置jupyter中DataFrame的显示限制方式
2020/04/12 Python
python属于跨平台语言码
2020/06/09 Python
Python3开发环境搭建详细教程
2020/06/18 Python
webapp字号大小跟随系统字号大小缩放的示例代码
2018/12/26 HTML / CSS
ETO男装官方网店:ETO Jeans
2019/02/28 全球购物
LN-CC英国:伦敦时尚生活的缩影
2019/09/01 全球购物
会计电算化大学生职业规划书
2014/02/05 职场文书
大学社团活动总结
2014/04/26 职场文书
中国梦演讲稿3分钟
2014/08/19 职场文书
办理房产证委托书
2014/09/18 职场文书
党员批评与自我批评(5篇)
2014/09/23 职场文书
人身意外保险授权委托书
2014/10/01 职场文书
先进基层党组织材料
2014/12/25 职场文书
党小组考察意见
2015/06/02 职场文书
入党申请书格式
2019/06/20 职场文书
python用tkinter开发的扫雷游戏
2021/06/01 Python