項目初始化
注意:安裝前請確保有安裝node.js,並且node>=8.9
全局安裝vue
npm install -g @vue/cli
如果之前安裝了vue舊版本,查看vue --version
創建項目
vue create vue-cli3-init(項目名)
注:名稱不能采用駝峰
vue-cli3也可以采用UI面板進行配置,相對比較方便,目前先寫命令行創建,后續再加上面板創建。
選擇配置,默認配置還是手動,這里我選擇手動Manually,繼續回車會讓你選擇你想要功能。 (不用用git窗口,選擇不了選項,可以使用上下方向來切換選項)
此處有兩個選擇:
- default (babel, eslint) 默認套餐,提供 babel 和 eslint 支持。
- Manually select features 自己去選擇需要的功能,提供更多的特性選擇。比如如果想要支持 TypeScript,就應該選擇這一項。

回車后可進行選擇,8個功能特性,可以多選: 使用方向鍵在特性選項之間切換,使用空格鍵選中當前特性,使用 a 鍵切換選擇所有,使用 i 鍵翻轉選項。我的選擇如下,請根據自己需要進行選擇。
對於每一項的功能,此處做個簡單描述:
- TypeScript 支持使用 TypeScript 書寫源碼。
- Progressive Web App (PWA) Support PWA 支持。
- Router 支持 vue-router 。
- Vuex 支持 vuex 。
- CSS Pre-processors 支持 CSS 預處理器。
- Linter / Formatter 支持代碼風格檢查和格式化。
- Unit Testing 支持單元測試。
- E2E Testing 支持 E2E 測試。

是否選擇history模式,根據自己需要選擇。

是否選擇預語言,根據自己需要選擇。

是否ESlint輸出,根據自己需要選擇。

是否保存時或者提交時是進行ESlint校驗,根據自己需要選擇。

選擇把配置文件放在外面,選擇 In dedicated config files

要不要把當前的這一系列選項配置保存起來,方便下一次創建項目時復用。

項目初始化完成,進入項目:
cd vue-cli3-init
依賴安裝完成之后啟動項目:
npm run serve

用編輯器打開后可以看到目錄結構。相對於vue-cli2精簡了很多,減少了對webpack的配置。

-
node_modules 文件夾 項目依賴(對webpack進行了封裝)
-
public 文件夾
1.favicon.ico 是 網站圖標
2.index.html 頁面入口文件
-
src 文件夾
main.js 入口js
assets 存放靜態文件
components 存放公用組件
App.vue 入口vue文件
-
.eslintrc.js 配置
-
.gitignore 指定文件無需提交到git上
-
balel.config.js 使用一些預設
-
package.json 項目描述及依賴
-
package-lock.json 版本管理使用的文件
由於現在的目錄結構不利於后期的開發,現在我們增加部分文件,待后續可以進行功能擴展。在src文件下:新建api文件夾,config文件夾,router文件夾,utils文件夾,views文件夾,store文件夾。並在其文件下建子目錄,詳細請參考目錄截圖:
多環境運行
由於我們的項目需要在不同環境下進行運行(開發,生產,測試等),這避免我們需要多次的去切換請求的地址以及相關的配置,vue-cli2是可以直接在config文件中進行配置的,但是vue-cli3已經簡化了,官方文檔也有進行配置的說明,實現具體有以下2種方法,我比較偏向第二種。
第一種實現方法
1.在根目錄新建2個文件,分別為.env.development
,.env.production
,.env.test
。注意文件是只有后綴的。
.env.development
模式用於serve,開發環境,就是開始環境的時候會引用這個文件里面的配置
.env.production
模式用於build,線上環境。
.env.test
測試環境
2.分別在文件內寫上:
開發環境:
//.env.development
VUE_APP_BASE_API = '需要請求API'
線上環境:
//.env.production
VUE_APP_BASE_API = '需要請求API'
測試環境:
//.env.test
VUE_APP_BASE_API = '需要請求API'
當需要用到該變量是可以用process.env.VUE_APP_BASE_API
進行取值。
3.更改package.json文件
"scripts": { "dev": "vue-cli-service serve", "test": "vue-cli-service serve --mode test", "build": "vue-cli-service build", "build:test": "vue-cli-service build --mode test", "lint": "vue-cli-service lint" },
第二種實現方式
1.在config文件新建index.js文件,根據全局的環境變量來進行判斷,並進行輸出。代碼如下:
// 一些全局的config配置
const modeUrlObj = { // 生產環境
'production': { baseURL: 'http://xxx:9091/pro/', authBaseURL: '' }, // 開發環境
'development': { baseURL: 'http://xxxx:9091/dev/', authBaseURL: '' }, // 測試環境
'test': { baseURL: 'http://xxxx:9091/test/', authBaseURL: '' } } export default modeUrlObj[process.env.NODE_ENV]
2.更改package.json文件
"scripts": { "dev": "vue-cli-service serve", "test": "vue-cli-service serve --mode test", "build": "vue-cli-service build", "build:test": "vue-cli-service build --mode test", "lint": "vue-cli-service lint" },
3.引用的方法可以參照如下:
import config from '../config/index' // 路徑配置 config.baseURL // 對應環境api
4.運行命令行
npm run dev // 開發環境 npm run test // 測試環境 npm run build // 正式環境打包 npm run build:test // 測試環境打包
axios封裝
在vue項目中,和后台交互獲取數據這塊,我們通常使用的是axios庫,它是基於promise的http庫,可運行在瀏覽器端和node.js中。他有很多優秀的特性,例如攔截請求和響應、取消請求、轉換json、客戶端防御XSRF等。所以我們的尤大大也是果斷放棄了對其官方庫vue-resource的維護,直接推薦我們使用axios庫。如果還對axios不了解的,可以移步axios文檔。
安裝依賴
npm install axios --save; // 安裝axios
配置axios
在uitls文件下新增request.js文件,在這里我們對axios進行初始化后,暴露給需要引用的文件,方便開發。
import axios from 'axios' import config from '../config/index' // 路徑配置
創建axios實例,並進行配置
// 創建axios 實例
const service = axios.create({ baseURL: config.baseURL, // api的base_url
timeout: 10000 // 請求超時時間
})
利用axios的請求攔截和響應攔截可以對登錄和權限方面進行控制,具體需求可以自己進行配置。完整代碼如下:
import axios from 'axios' import config from '../config/index' // 路徑配置
// 創建axios 實例
const service = axios.create({ baseURL: config.baseURL, // api的base_url
timeout: 10000 // 請求超時時間
}) // request 攔截器
service.interceptors.request.use( config => { // 這里可以自定義一些config 配置
return config }, error => { // 這里處理一些請求出錯的情況
Promise.reject(error) } ) // response 攔截器
service.interceptors.response.use( response => { const res = response.data // 這里處理一些response 正常放回時的邏輯
return res }, error => { // 這里處理一些response 出錯時的邏輯
return Promise.reject(error) } ) export default service
api請求配置
在api文件下新建分類的api請求文件。根據具體需要分類。主要是方便團隊開發,容易歸類。可以參考下面配置。
import request from '@/utils/request' export default { // 登錄
login (data) { return request({ url: '/login', method: 'post', data }) }, // 獲取用戶信息
getUserInfo () { return request({ url: '/userinfo', method: 'get' }) } }
業務中需要進行請求可以用import后,進行傳參即可。
模塊化vuex
Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
如果對vuex還不大了解的可以自行閱讀vuex官方文檔。
安裝vuex
npm install vuex -S
新建目錄
modules文件主要用法存放分類的文件,可以進行區分,getters文件是對state進行處理,index.js主要進行一些引入,初始化操作。

書寫vuex配置
index.js文件
import Vue from 'vue' import Vuex from 'vuex' import user from './modules/user' // 引入各個模塊的代碼 import getters from './getters' Vue.use(Vuex) const store = new Vuex.Store({ modules: { user }, getters }) export default store
getter.js文件
getter中的配置可根據需求進行增加或者刪除,下面是示例。
const getters = { requestLoading: state => state.app.requestLoading, size: state => state.app.size, token: state => state.user.token, avatar: state => state.user.avatar, name: state => state.user.name, roles: state => state.user.roles } export default getters
moduels/user.js文件
該文件為與業務相關,可以跟據具體參見進行增加和刪除命名。每個文件的基本配置和用法如下:
import { getToken, setToken } from '@/utils/auth' import api from '@/api/user' const user = { state: { token: getToken(), }, mutations: { SET_TOKEN: (state, token) => { state.token = token }, }, actions: { // 登錄 Login ({ commit }, userInfo) { return new Promise((resolve, reject) => { api.login(userInfo).then(res => { if (res.code === 200) { setToken(res.data) commit('SET_TOKEN', res.data) } resolve() }).catch(err => { reject(err) }) }) } } } export default user
全局樣式引用
在項目開發過程中,我們經常需要全局樣式引用,例如主題色等,如果每次去寫的化會變得很麻煩。因為我們應該了sass預語言編譯,所以可以大膽的應用其特性。例如變量,函數,混入等。但是我們需要在項目中進行全局的配置才能有效果。不用在每一個頁面都進行引入樣式,就能直接引用。
新建目錄
在assets下新建如下文件,具體的代碼自行進行配置
* common.scss 主要存放公共的樣式 * mixin.scss 存放混入樣式 * reset.scss 存放重置樣式。 * variable.scss 存放變量

全局引入
新建vue.config.js文件,並寫上以下代碼
module.exports = { css: { loaderOptions: { // pass options to sass-loader
sass: { // @/ is an alias to src/
// so this assumes you have a file named `src/variables.scss`
data: ` @import "@/assets/css/variable.scss"; @import "@/assets/css/common.scss"; @import "@/assets/css/mixin.scss"; ` } } }, }
在app.vue中引入reset.scss文件,完成后,樣式即可進行全局調用了。
<style lang="scss"> @import "assets/css/reset"; </style>
移動端適配配置
在本項目中主要用rem來進行頁面的適配操作的,因為rem就可以隨根字體大小改變而改變,從而實現了自適應的功能。但是html的字體是固定的,所以需要監聽頁面大小的變化,我主要用了淘寶的amfe-flexible
來進行監聽改變的。將項目中css的px轉成rem單位,免去計算煩惱,我們可以用scss來進行計算或者利用px2rem
插件來進行自動轉化。因為是開發移動端,需把mate換為
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale= 1.0, minimum-scale=1.0">
實現方法如下:
安裝amfe-flexible
npm i amfe-flexible --save
px轉rem
方法一:
在common.scss文件中,全局引入scss函數:
/** 轉化px為rem。$base-font-size = 設計稿尺寸/10 */ @function px2rem($px, $base-font-size: 37.5) { @return ($px/$base-font-size)*1rem }
調用方式直接: width: px2rem(175);
方法二:
安裝依賴
npm i postcss-pxtorem --save-dev
package.json內,在postcss內添加:
"postcss": { "plugins": { "autoprefixer": {}, "postcss-pxtorem": { "rootValue": 75, // 設計稿寬度的1/10,(JSON文件中不加注釋,此行注釋及下行注釋均刪除) "propList":["*"] // 需要做轉化處理的屬性,如`hight`、`width`、`margin`等,`*`表示全部 } } },
常用util
該文件主要是對一些常用的js進行封裝,例如時間格式化,LocalStorage操作等,相對比較常用的方法,這個文件可以進行保存,要用到時直接復制過來用即可。下面是我封裝LocalStorage的文件,可參考以下,其他自行設置
import Cookies from 'js-cookie' const TokenKey = 'Authorization' /* * 設置setLocalStorage * */ export function setLocalStorage (key, value) { window.localStorage.setItem(key, window.JSON.stringify(value)) } /* * 獲取getLocalStorage * */ export function getLocalStorage (key) { return window.JSON.parse(window.localStorage.getItem(key) || '[]') } /* * 設置setSessionStorage * */ export function setSessionStorage (key, value) { window.sessionStorage.setItem(key, window.JSON.stringify(value)) } /* * 獲取getSessionStorage * */ export function getSessionStorage (key) { return window.JSON.parse(window.sessionStorage.getItem(key) || '[]') } /* * 獲取getToken * */ export function getToken () { return Cookies.get(TokenKey) } /* * 設置setToken * */ export function setToken (token) { return Cookies.set(TokenKey, token) } /* * 移除removeToken * */ export function removeToken () { return Cookies.remove(TokenKey) }
1. 打開控制台,執行vue add element命令,為項目安裝element。
2.等待其安裝完畢,在設置向導中配置引入方式和加載地區。
3.在自動安裝完依賴后,可以看到相關的文件已經被創建/更新了。
4.如果需要按需引入,則去到src目錄下自動新建的plugins目錄,編輯element.js即可,默認會導入一個Button。這么做的好處是不用把引入的ele組件寫在main.js文件下,使各模塊更加分離。
配置vue.config.js文件
基本配置
1.文件目錄配置別名
我們可以把src配置為@,如果需要就不用到根目錄開始寫了,直接用@/xxx/進行引用。根據自己需要進行配置,在vue.config.js文件中加入代碼
// 配置 chainWebpack: (config)=>{ // 配置別名 config.resolve.alias .set('@', resolve('src')) .set('assets',resolve('src/assets')) .set('components',resolve('src/components')) .set('router',resolve('src/router')) .set('utils',resolve('src/utils')) .set('static',resolve('src/static')) .set('store',resolve('src/store')) .set('views',resolve('src/views')) }
2.跨域配置
在前端請求過程中,如果后台沒有設置跨域請求的,可以在webpack進行配置。
devServer: { proxy: { '/api': { target: 'http://127.0.0.1:8080', changeOrigin: true } } }
3.其他配置
具體可以參照官網的配置說明,在項目中我用到了
assetsDir: 'assets', // 靜態文件目錄 publicPath: './', // 編譯后的地址,可以根據環境進行設置 lintOnSave: true, // 是否開啟編譯時是否不符合eslint提示
以上的所有代碼必須寫在module.exports
輸出才能生效. 詳細的配置可參考官網 vue-cli3
項目框架性能優化 (v1_mint_ui分支)
通過以上的基本配置,項目已經符合我們工作需要了,但是在工作過程中會發現隨着項目的集成度越來越高,業務越來越多。出現了加載慢和打包文件過大的問題。導致我們頁面白屏時間過長,用戶體驗不友好。那么如果你感興趣的話,可以進行以下的配置,可以大大大大大的減小體積和加載速度。在master分支是沒有進行優化的,如果需要看優化代碼可以到另外一個分支。所以在頁面引入的代碼都是當前頁面需要的執行代碼,可以往下面幾個方法進行處理。
-
js,css代碼的最小化壓縮和分割
-
js,css代碼公用代碼提取, 按需引入(cdn加載)
-
圖片文件的壓縮
-
gzip的壓縮
-
去除console.log
1.js,css代碼的最小化壓縮和分割
首先,我們先對js文件進行配置以達到壓縮效果,先看一下沒有配置代碼情況,整個app.js 的文件是2.8M(因為是初始項目),但是如果頁面一多,就不只這個數了。

我們會通過chainWebpak來處理. 在優化前, 看下相關文件的響應代碼: 看下app.js文件的返回代碼:代碼如下:

在vue.config.js文件中加入,run以下后查看app.js情況,文件會變小(由於初始項目體積小,看不出多大區別)。
module.exports = { chainWebpack: config => { config.optimization.minimize(true); } }

分割代碼,相應的文件中存入分割后的代碼。
module.exports = { chainWebpack: config => { config.optimization.minimize(true); config.optimization.splitChunks({ chunks: 'all' }) } }

加入以上代碼后,分成了2個文件,最大的只有2.7M了,這樣可以分成多個進行加載,可以達到最快化,但是一定要平衡文件大小的和分割出來的文件數量的平衡, 數量多了, 請求也會變慢的, 影響性能.可以根據項目的進行設置,具體可參考官方文檔的詳細說明。
2.js,css代碼公用代碼提取, 按需引入(CDN加載
)
把公用代碼提取出來,然后采用使用免費的cdn資源進行加載。在項目中我們主要是引入引入不同的模塊庫才會導致文件較大,那么是否可以把這些文件進一步處理,答案是可以的,比如vue, vuex, vue-router, element-ui等公共資源庫。利用webpack我們可以使用externals參數來配置:
在vue.config.js文件:
module.exports = { chainWebpack: config => { // 壓縮代碼 config.optimization.minimize(true); // 分割代碼 config.optimization.splitChunks({ chunks: 'all' }) // 用cdn方式引入 config.externals({ 'vue': 'Vue', 'vuex': 'Vuex', 'vue-router': 'VueRouter', 'mint-ui': 'MINT', // 需用MINT 'axios': 'axios' }) } }
index.html加入CDN地址,注意引入的時候要寫在body里面,否則會報錯。
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.runtime.min.js"></script> <script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script> <script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script> <script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script> <script src="https://cdn.bootcss.com/mint-ui/2.2.13/index.js"></script>
mint-ui樣式通過CDN引入。然后商儲mian.js文件的 import 'mint-ui/lib/style.css' (全局引入模式才有)
<link href="https://cdn.bootcss.com/mint-ui/2.2.13/style.min.css" rel="stylesheet">
如果需要引入其他依賴的CDN可以通過BootCDN查找進行引入。
重新運行項目, 看看效果,已經大大的減小了很多,到了k級別了:

因為js會動態的加載出css,所以js文件包會比較大,那么需要提取css代碼到文件. 這里我們只需要將css配置一下:
module.exports = { css: { extract: true } }
3.圖片文件的壓縮
圖片文件大於在webpack設定的值時,我們可以對其進行壓縮在進行引入,安利給大家一個壓縮圖片的網站https://tinypng.com/,它可以批量的壓縮圖片又不會失真,壓縮比相對較大。可以對圖片進行有效壓縮。
4.gzip的壓縮
如果后台有對前端的代碼進行gzip壓縮的話,那么就不需要進行壓縮了,后台自己配置就可以。如果后台不具備這種情況那么我們可以利用compression-webpack-plugin插件可以幫助我們進行gzip壓縮:
安裝依賴:
npm install --save-dev compression-webpack-plugin
然后引入相關代碼:
const CompressionWebpackPlugin = require('compression-webpack-plugin') const compress = new CompressionWebpackPlugin( { filename: info => { return `${info.path}.gz${info.query}` }, algorithm: 'gzip', threshold: 10240, test: new RegExp( '\\.(' + ['js'].join('|') + ')$' ), minRatio: 0.8, deleteOriginalAssets: false } ) module.exports = { devServer: { before(app, server) { app.get(/.*.(js)$/, (req, res, next) => { req.url = req.url + '.gz'; res.set('Content-Encoding', 'gzip'); next(); }) } } configureWebpack: { plugins: [compress] }
重新run一遍,出現了意向不到的結果了。又原來的2.8M轉化為250+kb了,縮小了11倍以上。重大突破

6.去除console.log
正常情況下我們會在開發環境進行console調試,但是如果不刪除,過多會出現內存泄漏的情況,那么我們可以在正式環境的時候就把它給干掉,實現方法如下:
方法一:
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); module.exports = { configureWebpack: config => { if (IS_PROD) { const plugins = []; plugins.push( new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false, drop_console: true, drop_debugger: false, pure_funcs: ['console.log']//移除console } }, sourceMap: false, parallel: true }) ); config.plugins = [ ...config.plugins, ...plugins ]; } } }
方法二:使用babel-plugin-transform-remove-console
插件
npm i --save-dev babel-plugin-transform-remove-console
在babel.config.js中配置
const plugins = []; if(['production', 'prod'].includes(process.env.NODE_ENV)) { plugins.push("transform-remove-console") } module.exports = { presets: [["@vue/app",{"useBuiltIns": "entry"}]], plugins: plugins };