公司作的后台管理系统,越作越庞大,并且系统之间还须要常常的来回嵌套页面,单页面已经不太顺手了。
因此我把vue+elementui+webpack单页面改成多页面的经验在这里唠叨唠叨,这里做展现的是一个简单的后台管理系统,利用iframe模拟的路由跳转,很简单也很容易上手,能够把这个项目下载到本地,而后把大家的页面慢慢移进去,但愿能帮到一些小伙伴。
建议,把项目下载下来跑起来,结合着项目看这篇文章,否则会蒙。
gitHub:欢迎各位star
在线预览:网站不太稳定,最好下载到本地
效果预览:css
一.广泛的实现方案:html
1.手动改造webpack,配置多个入口,配置多个出口;
2.每一个目录下边都有个.html文件来承载实例,.js文件引入Vue等等模块,.vue页面来书写逻辑等,如图:
![]()
二.改进的方案vue
1.用node自带的模块fs来动态的匹配目录,动态的生成入口文件,动态的生成打包出口文件;
2.咱们写一个公共的html文件来承载实例,写一个公共的js来引入各类依赖,根据动态传入.vue文件模块生成实例
如图:
3.解释一下template下的config.js:
由于咱们如今只用config.js来去引入各类依赖,就像单页面的mian.js同样,不一样的是,
须要被挂载的vue文件是动态的,因此咱们用localStorage来传递,咱们在页面目录下边只用写一个.vue文件,一个.js文件,
这个.js文件里只用写上当前对应的.vue文件所在的目录,不用在每一个js里写那么多引入的依赖
文件目录下的js:node
let baseUrl = "china/china" localStorage.setItem('baseUrl', baseUrl)
template/config.jswebpack
// 若是你想用本身建立的实例,在本身单独的js文件里加上:let baseUrl="noNeed" / localStorage.setItem('baseUrl',baseUrl) let baseMounted = localStorage.getItem('baseUrl') console.log(baseMounted) import '../src/style/index.scss' //公用样式 if (baseMounted === 'noNeed') { // 组件本身建立了实,将不会再引入下边的资源 throw new Error("当前组件本身建立了实例,不会引用公用方法、实例"); } import Vue from 'vue'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI); // 动态捕获要挂载实例的.vue文件的路径 var App = resolve => require.ensure([], () => resolve(require("../src/views/" + baseMounted + ".vue"))); new Vue({ el: '#app', template: '<App/>', components: { App } })
总结:就是你每次切换页面的时候,会先加载本身目录下的js文件,js里用localStorage存储.vue的路径(固然你也能够写成'noNeed',这样你本身就得在js里去引入各类依赖了),
再去引用template/config.js的时候,利用localStorage告诉挂载实例的模板是哪一个。git
三.最重要的webpack配置github
webpack的复杂程度我就不累赘了(我本身也是个入门选手),这个须要本身花时间去看,我就直接讲下实现的结果。
主要的实现逻辑就是下边的这个js文件,出处我翻不到了,不知道是哪位大神研究出来的,
这个js文件主要实现了webpack匹配出入口文件的功能,
一开始,我也是研究了研究里边的方法,而后在原版的基础上改造了好几版,实现了如今的效果,
主要改了公共模板html和js,以及js的加载顺序。
build下的这三个文件都要改为multipage-helper.js里的方法web
multipage-helper.js:element-ui
var path = require('path') var fs = require("fs") const resolve = (p) => path.resolve(__dirname, "..", p) var HtmlWebpackPlugin = require('html-webpack-plugin') const templatePath = resolve("template/index.html") const templateJs = "./template/config.js" var moduleList //缓存多页面模块列表 var moduleRootPath = './src/views' //模块根目录(这个能够根据本身的需求命名) /** * 获取js入口数组 */ exports.getEntries = function getEntries() { //缓存js入口数组 var entries = {} //初始化模块列表 this.getModuleList() //变量模块列表 moduleList.forEach(function(module) { if (module.moduleID != "" && module.moduleJS != "") { entries[module.moduleID] = module.moduleJS } }) entries.app=templateJs console.log("*********************************** entries ***********************************") console.log(entries) return entries } /** * 获取多页面模块列表 * @returns {模块的信息集合} */ exports.getModuleList = function getModuleList() { //判断是否为空,不为空则直接返回 if (moduleList) { return moduleList } else { //为空则读取列表 moduleList = new Array(); readDirSync(moduleRootPath, "") console.log("*********************************** moduleList ***********************************") console.log(moduleList) return moduleList } } /** * 获取dev的Html模板集合 * @returns {dev的Html模板集合} */ exports.getDevHtmlWebpackPluginList = function getDevHtmlWebpackPluginList() { console.log("*********************************** devHtmlWebpackPluginList ***********************************") //缓存dev的Html模板集合 var devHtmlWebpackPluginList = [] //获取多页面模块集合 var moduleList = this.getModuleList() //遍历生成模块的HTML模板 moduleList.forEach(function(mod) { //生成配置 var conf = { filename: mod.moduleID + ".html", template: mod.moduleHTML ? mod.moduleHTML : templatePath, chunks: [mod.moduleID,'app'], chunksSortMode: 'manual', inject: true } console.log(conf) //添加HtmlWebpackPlugin对象 devHtmlWebpackPluginList.push(new HtmlWebpackPlugin(conf)) }) return devHtmlWebpackPluginList } /** * 获取prod的Html模板集合 * @returns {prod的Html模板集合} */ exports.getProdHtmlWebpackPluginList = function getProdHtmlWebpackPluginList() { console.log("*********************************** prodHtmlWebpackPluginList ***********************************") //缓存dev的Html模板集合 var prodHtmlWebpackPluginList = [] //获取多页面模块集合 var moduleList = this.getModuleList() //遍历生成模块的HTML模板 moduleList.forEach(function(mod) { //生成配置 var conf = { filename: mod.moduleID + ".html", template: mod.moduleHTML ? mod.moduleHTML : templatePath, inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency', chunks: ['manifest', 'vendor', mod.moduleID,'app'], chunksSortMode: 'manual' } console.log(conf) //添加HtmlWebpackPlugin对象 prodHtmlWebpackPluginList.push(new HtmlWebpackPlugin(conf)) }) return prodHtmlWebpackPluginList } /** * 深度遍历目录,并整理多页面模块 * @param path 须要变量的路径 * @param moduleName 模块名称 */ function readDirSync(path, moduleName) { //缓存模块对象 var module = { moduleID: "", moduleHTML: "", moduleJS: "" } //获取当前模块ID var moduleID = path.replace(moduleRootPath + "/", "") if (path == moduleRootPath) { moduleID = "" } module.moduleID = moduleID //获取目录下全部文件及文件夹 var pa = fs.readdirSync(path) pa.forEach(function(ele, index) { var info = fs.statSync(path + "/" + ele) if (info.isDirectory()) { // console.log("dir: "+ele) readDirSync(path + "/" + ele, ele) } else { //判断当前模块的html是否存在 if (moduleName+".html" == ele){ module.moduleHTML = path+"/"+ele } // module.moduleHTML = templatePath //判断当前模块的js是否存在 if (moduleName + ".js" == ele) { module.moduleJS = path + "/" + ele } // console.log("file: "+ele) } }) //判断模块是否真实(可能只是个分级目录) if ((module.moduleID != "" && module.moduleHTML != "") || (module.moduleID != "" && module.moduleJS != "")) { moduleList.push(module) } }
鄙人的webpack正在学习中,因此可能有些细节讲的不会太清楚,但能用,但愿你们的指正,也但愿能帮到你们,嘻嘻嘻。数组