公司作的後臺管理系統,越作越龐大,並且系統之間還須要常常的來回嵌套頁面,單頁面已經不太順手了。
因此我把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正在學習中,因此可能有些細節講的不會太清楚,但能用,但願你們的指正,也但願能幫到你們,嘻嘻嘻。數組