投稿007期|記一次基於vue的spa多頁籤實踐經驗
前言
最近收到一個這樣的需求,要求做一個基於 vue 和 element-ui 的通用後臺框架頁,具體要求如下:
要求通用性高,需要在後期四十多個子專案中使用,所以大部分地方都做成可配置的.
要求做成腳手架的形式.可以 npm 安裝
要求實現多頁籤,並且可以透過瀏覽器 url 回顯多頁籤.而且頁籤內要維護一個歷史記錄,可以後退
元件要求非同步載入,減少首屏載入時間.
很明顯,這就是一個 類 ERP
的應用. 做過 JSP 等後臺的同學,對多頁籤應該都很熟悉吧.
那接下來我們就來談談實現.
通用性高
這點其實沒啥難點,無非就是麻煩了點,把所有的資料,都提取出來,放在一個 config
檔案裡面.然後在框架頁裡面引入,並且繫結到相應的位置上去. 這邊有個比較難以取捨的問題,就是如果把一溜的資料全部繫結到 vue 的 data 上面,由於資料量比較多,會導致效能問題,如果分開,又會使配置檔案看起來相對複雜,增加後期使用人員的學習成本。這塊要看具體的專案需求,由於我這邊暫時對前端的效能要求沒那麼高,所以暫時用全部繫結到 data 的方案
做成腳手架形式
起初產品對這個的需求使做成元件的形式,然後釋出 npm 包,方便後期更新的時候,只需更新一下 npm 就可以了,無需每個專案去複製貼上替換,但是基於這是一個框架頁,而且可配置項非常多,還要實現 tab 多頁籤等多方面的考慮,最終選擇了腳手架的方案,即便這樣後期升級會稍微麻煩一點(起初的方案是框架頁放在一個資料夾裡,到時候直接替換該資料夾),但相對於元件來說,還是更好維護的,況且後期可以再寫一個更新的腳手架,畢竟現在釋出一個 npm 工具的成本實在是太低了。
第一次開發腳手架,看了很多社群的帖子,發現目前大部分腳手架,一般都基於2種形式,一種基於檔案複製的形式,另一種基於 git-clone 的形式,經過對比,我覺得檔案複製的有點複雜了,我其實只是需要一個能一鍵安裝的工具而已,所以 git-clone 的形式還是比較適合我。
以下就是腳手架的程式碼,雖然只是簡單的五六十行程式碼,不過查資料+趟坑,也花了我一個上午的時間。
#!/usr/bin/env nodeconst shell = require('shelljs');const program = require('commander');const inquirer = require('inquirer');const ora = require('ora');const fs = require('fs');const path = require('path');const spinner = ora();const gitClone = require('git-clone')const chalk = require('chalk')program .version('1.0.0', '-v, --version') .parse(process.argv);const questions = [{ type: 'input', name: 'name', message: '請輸入專案名稱', default: 'my-project', validate: (name)=>{ if(/^[a-z]+/.test(name)){ return true; }else{ return '專案名稱必須以小寫字母開頭'; } }}]inquirer.prompt(questions).then((dir)=>{ downloadTemplate(dir.name);})function downloadTemplate(dir){ // 判斷目錄是否已存在 let isHasDir = fs.existsSync(path.resolve(dir)); if(isHasDir){ spinner.fail('當前目錄已存在!'); return false; } spinner.start(`您選擇的目錄是: ${chalk.red(dir)}, 資料載入中,請稍後...`); // 克隆 模板檔案 gitClone(``, dir , null, function(err) { // 移除無用的檔案 shell.rm('-rf', `${dir}/.git`) spinner.succeed('專案初始化成功!') // 執行常用命令 shell.cd(dir) spinner.start(`正在幫您安裝依賴...`); shell.exec('npm i') spinner.succeed('依賴安裝成功!') shell.exec('npm run dev') })}
如果你這個腳手架有疑問或者興趣,可以直接訪問 github 上的程式碼
實現多頁籤
要想實現多頁籤,那麼 vue-router 基本算是廢了,為什麼? vue-router 是根據 url 來切換單個元件的,而頁籤則需要再元件內部同時存在多個子元件的,所以路由無法勝任(至少我是這麼認為的,如果你有更好的方案,懇請不吝賜教)。
多個頁籤的顯示,其實不難, element 有現成的 tab 元件,於是老夫寫程式碼就是一把梭,擼起袖子就是幹,噼裡啪啦一頓寫,寫完一測,沒有任何問題,實在是不要太簡單,丟給產品預覽:
複製瀏覽器地址到別的地方貼上,tab 不能正確回顯
tab 內需要實現跳轉,而且要能返回。
第一個問題比較簡單,自己手寫一個基於 hash 的 偽路由
把當前 tab 的 id 放到 url 上去,然後回顯的時候,根據 url 開啟對應的 tab.
tip: 關於如何實現路由,請看我另外一篇部落格
第二個問題,大概就是本文的重點了,這裡詳細說明一下需求,每個 tab 都可以在 tab 內部 跳轉
,這裡的跳轉,要做的跟 vue-router 的有大體上差不多,要能 push, replace, back,還能帶引數。
那麼怎麼實現呢? 首先維護一個開啟的 tab 列表,然後每個列表裡面再維護一個用過的元件列表(包含引數),這樣大概就能實現了嗎?當然不是,元件的跳轉,引數的傳遞,不可能讓使用者自己去實現這些方法吧,我選擇把封裝一個公共物件,然後掛載在 vue.prototype上。然後類似 vue.$router.xxxx 一樣(我的命名是 vue.$tab)可以在頁面的任何地方使用,如果你對具體的實現方法有興趣,歡迎點選本文結尾的連結,去我的Github倉庫上檢視。
元件非同步載入
之前只用過基於 vue-router 的非同步載入方法,然而這個專案裡面並沒有使用 vue-router,怎麼非同步呢? 翻了一下 vue 的官方文件是這麼寫的:
Vue.component( 'async-webpack-example', // 這個 `import` 函式會返回一個 `Promise` 物件。 () => import('./my-async-component'))
然而我試了一下,發現報錯了,import 不能在這裡使用,換了 require 也不行,不知道上我哪裡沒弄好,如果你剛好知道又剛好有空,請告訴我,謝謝!後面在 segmentfault 上 看到 , 使用 webpack 的 require.ensure 可以實現
// 第一個字串是 元件名,第二個是 元件路徑,第三個是 chunkName (如果不指定則以1.js,2.js....n.js命名)vue.component('home', (resolve) => {require.ensure([], ()=>resolve(require('@/Views/index.vue')), 'home')})
順便還要在 webpack 裡面的 output 下面配置一下 chunkFilename: '[name].js',
, 當然檔名格式可以按你專案的需求來,我這邊就按最簡單的
結束語
首先,當然上獻上該專案的 咯
其次是本文的的地址
以上專案 歡迎隨意 star
和 follow
, 和不隨意的 issue
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2894/viewspace-2806617/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 基於微前端qiankun的多頁籤快取方案實踐前端快取
- vue-multi-tab–一個讓你在SPA裡使用多頁籤的框架頁Vue框架
- vue-multi-tab--一個讓你在SPA裡使用多頁籤的框架頁Vue框架
- 基於SPA架構的GraphQL工程實踐架構
- 基於Vue的SPA如何優化頁面載入速度Vue優化
- Vue路由+Tab元件實現多頁籤功能Vue路由元件
- IEEE Access投稿步驟及投稿經驗
- 期刊投稿經驗|用corresponding author的賬號進行投稿
- Vue 前端配置多級目錄實踐(基於Nginx配置方式)Vue前端Nginx
- 銀行基於雲原生架構的 DevOps 建設實踐經驗架構dev
- 記一次 VUE 專案優化實踐Vue優化
- 基於Kali的一次DDos攻擊實踐
- vue 單頁應用(spa)前端路由實現原理Vue前端路由
- Vue單頁及多頁應用全域性配置404頁面實踐Vue
- vue腳手架多頁自動化生成實踐Vue
- 基於 Rush 的 Monorepo 多包釋出實踐Mono
- 基於vue-cli的多頁面應用腳手架Vue
- 基於vue2.0的weex實踐(前端視角)Vue前端
- 基於vue自動化表單實踐Vue
- webpack多頁面實踐Web
- 基於Bootstrap的標籤頁元件bootstrap-tabboot元件
- vue-cli多頁面應用實踐,實現元件預覽Vue元件
- webpack + vuecli多頁面打包基於(vue-template-admin)修改WebVue
- 基於 Nuxt 的 Vue.js 服務端渲染實踐UXVue.js服務端
- [Vue CLI 3] 多頁應用實踐和原始碼設計Vue原始碼
- 經驗分享丨功能測試漲薪路線,記一次簡單的效能測試實踐!
- 記一次網頁記憶體溢位分析及解決實踐網頁記憶體溢位
- 記一次專案經驗(6)
- 在 JeecgBoot 專案中基於 Vue 3 配置多頁面入口bootVue
- 2.CNN圖片多標籤分類(基於TensorFlow實現驗證碼識別OCR)CNN
- Pyqt5 實現多標籤頁面QT
- 分享一次排查CLOSE_WAIT過多的經驗AI
- 一次基於AST的大規模程式碼遷移實踐AST
- Vue SPA專案優化小記Vue優化
- Vue頁面骨架屏注入實踐Vue
- Vue 頁面骨架屏注入實踐Vue
- 記錄一次基於vue、typescript、pwa的專案由開發到部署VueTypeScript
- 基於github的CICD實踐Github