热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

教你搭建按需加载的Vue组件库

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

按需加载的原理

按需加载,本质上是把一个组件库的不同组件拆分成不同文件,按照需要引用对应的文件,而该文件暴露一个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:


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
https://github.com/jmx164491960/load-on-demand
大家如果有更好的实现方法,或者我上面还有什么需要更正的错误,欢迎交流。


推荐阅读
  • 本文介绍了如何使用外向烧鹅IO库来封装GET请求的具体步骤,包括库的安装与配置、请求拦截器的设置以及如何在Vue项目中调用这些封装好的请求方法。 ... [详细]
  • 本文详细介绍如何在iOS项目中集成和使用KTVHTTPCache音视频缓存插件,包括Podfile配置、初始化设置及实际应用中的使用方法。 ... [详细]
  • 在Ubuntu 16.04中使用Anaconda安装TensorFlow
    本文详细介绍了如何在Ubuntu 16.04系统上通过Anaconda环境管理工具安装TensorFlow。首先,需要下载并安装Anaconda,然后配置环境变量以确保系统能够识别Anaconda命令。接着,创建一个特定的Python环境用于安装TensorFlow,并通过指定的镜像源加速安装过程。最后,通过一个简单的线性回归示例验证TensorFlow的安装是否成功。 ... [详细]
  • 本文详细介绍了如何从SVN中获取项目,并在本地环境中进行有效的构建和开发,包括具体的步骤和配置方法。 ... [详细]
  • Java面向对象编程深入解析
    本文详细探讨了Java中的关键字static、单例模式、main()方法、代码块、final关键字、抽象类与方法、模板方法设计模式、接口、内部类等内容,旨在帮助读者深入理解和掌握Java面向对象编程的核心概念。 ... [详细]
  • 深入理解Kafka架构
    本文将详细介绍Kafka的内部工作机制,包括其工作流程、文件存储机制、生产者与消费者的具体实现,以及如何通过高效读写技术和Zookeeper支持来确保系统的高性能和稳定性。 ... [详细]
  • MySQL中的Anemometer使用指南
    本文详细介绍了如何在MySQL环境中部署和使用Anemometer,以帮助开发者有效监控和优化慢查询性能。通过本文,您将了解从环境准备到具体配置的全过程。 ... [详细]
  • 本文详细介绍了黑马旅游网的用户退出功能实现方法,包括前后端代码的具体操作步骤。通过访问Servlet销毁session,并重定向至登录页面。 ... [详细]
  • 解决Ant编译时出现的非法字符错误
    在进行Java项目的Ant构建过程中,有时会遇到由平台差异引发的编译错误。本文将详细探讨一种常见的错误——'error: illegal character'及其解决方案。 ... [详细]
  • 随着数据量的增长,手动处理Excel文件变得越来越耗时且容易出错。本文介绍如何利用编程工具自动化Excel文件处理流程,以提高效率并减少错误。 ... [详细]
  • 深入探讨PHP中的输出缓冲技术(Output Buffering)
    本文深入解析了PHP中输出缓冲(Output Buffering)的原理及其在Web开发中的应用,特别是如何通过输出缓冲技术有效管理HTTP头部信息,提高代码的灵活性与健壮性。 ... [详细]
  • 深入理解Java NIO:基础概念与原理
    本文介绍了Java NIO(New Input/Output)的基本概念,包括同步与异步、阻塞与非阻塞等核心理念,以及NIO相对于传统IO的优势和应用场景。通过详细解析这些概念,帮助读者更好地理解和掌握NIO的使用。 ... [详细]
  • 本文介绍了如何在Angular CLI创建的项目中安装并配置Bootstrap,包括必要的依赖项jQuery和Popper.js的安装步骤。 ... [详细]
  • 本文探讨了如何在Python 2.7环境中解决'ImportError: No module named builtins'的问题,并提供了确保代码兼容性的建议。 ... [详细]
  • 使用清华大学镜像源安装Setuptools与Pip
    本文介绍了如何通过清华大学的Python镜像源安装Setuptools和Pip,包括详细的步骤和可能遇到的问题解决方法。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有