按需加载原理install方法由Vue.use使用。例如:我只想引用元素库中的一个Button组件importButtonfrom'element-ui/lib/Button.js'importButtonfrom'element-ui/lib/theme-chalk/Button.css'Vue。使用(按钮);上面的写法比较麻烦,需要知道每个组件的实际路径,使用起来不方便,所以我们还需要使用转换插件。我们来看看element是怎么做的。官方“快速上手”:element使用了一个babel插件,作用是代码转换:import{Button}from'components'//converttovarbutton=require('components/lib/button')require('components/lib/button/style.css')至此,我们可以知道我们需要构建一个按需加载的组件库。主要工作需要两点:组件独立打包,单个文件对应单个组件。代码转换插件组件代码介绍。我们在项目的根目录下创建一个文件夹packages,在下面放置我们的组件:packages下的每个文件夹对应一个组件需要的资源,在index.js中定义组件的install方法。而packages/index.js中存放了完整加载packages/Button/index.js中使用的install方法:importButtonfrom'./src/main';Button.install=function(Vue){Vue.component(Button.name,Button);};exportdefaultButton;packages/Button/src/main.vue:我是一个Button组件
packages/index.js:从“./Button”导入按钮;从“./Loading”导入加载;从“./LoadMore”导入LoadMore;constcomponents=[Button,LoadMore,Loading];constinstall=function(Vue){components.forEach(component=>{Vue.component(component.name,component);});}if(typeofwindow!=='undefined'&&window.Vue){install(window.Vue)}exportdefault{install,//完全导入Button,LoadMore,Loading};webpack配置组件代码写完之后,接下来需要配置webpack的打包逻辑。我们复用了vue-cli生成的模板,并对其做了一些必要的改动:多入口,每个组件独立生成对应的js和css,这就需要我们在入口处定义组件的引用:webpack.prod。conf.js:constentries={Button:path.resolve(__dirname,'../packages/Button'),index:path.resolve(__dirname,'../packages')};constwebpackConfig=merge(baseWebpackConfig,{entry:entries,//......});上面的配置每次添加组件都需要修改entry,我们可以优化让它动态生成:webpack.prod.conf.js:constentries=require(./getComponents.js)([componentdirectoryentry]);constwebpackConfig=merge(baseWebpackConfig,{entry:entries,...});getComponents.js:constfs=require('fs');constpath=require('path');/***判断是否该路径包含index.js*@param{String}dir*/functionhasIndexJs(dir){letdirs=[];尝试{dirs=fs.readdirSync(dir);}catch(e){dirs=null;}returndirs&&dirs.includes('index.js');}/***获取指定入口及入口下包含index.js的文件夹路径*@param{String}entryDir*/constgetPath=function(entryDir){让dirs=fs.readdirSync(entryDir);常量结果={我索引:entryDir};dirs=dirs.filter(dir=>{returnhasIndexJs(path.resolve(entryDir,dir));}).forEach(dir=>{result[dir]=path.resolve(entryDir,dir);});返回结果;}module.exports=getPath;修改webpack的输出默认生成的js文件不支持ES6导入,这里我们设置为umdoutput:{path:config.build.assetsRoot,filename:utils.assetsPath('[name].js'),library:'LoadOnDemand',libraryTarget:'umd'},配置babel-plugin-component-D后,将上面的组件库打包发布到npm上。当我们使用npminstallbabel-plugin-component-D后,修改.babelrc.js:"plugins":[["component",{"libraryName":"load-on-demand",//组件名称library"camel2Dash":false,//是否将驼峰式大小写转换为xx-xx"styleLibrary":{"base":false,//各组件是否默认引用base.css"name":"theme"//nameofthecssdirectory}}]],这里提到属性camel2Dash,默认启用。如果你的组件名称是启用状态下的vueComponent,那么引用的css文件就会变成vue-component.css。结论以上demo的代码放在我的github上https://github.com/jmx164491960/load-on-demand如果大家有更好的实现方法,或者有什么错误需要指正,欢迎交流。