引言
記錄 vue 專案中所使用的技術細節,此文著重使用和封裝層面,原理性的東西會附上參考文章連結。
建議 clone 下來程式碼看文章:vue-template-project
麻煩動動小手點個 star 哦。
專案初始化
技術選型
結合vue生態,此移動端專案模板使用如下技術:
- 前端框架——vue
- vue 狀態管理——vuex
- vue 路由管理——vue-router
- 請求方式——axios
- 樣式管理——less
- 包管理——npm/cnpm
vue-cli4搭建專案
vue-cli 工具更新很快,我們現在專案中仍使用的是 vue-cli2 ,專案中如需更新腳手架工具,按照以下步驟更新即可。
安裝 Vue CLI
安裝
npm install -g @vue/cli
複製程式碼
如果存在舊版本的 vue-cli ,需先解除安裝再安裝:
npm uninstall vue-cli -g
複製程式碼
檢測版本:
vue --version
#OR
vue -V
複製程式碼
建立專案
執行以下命令建立一個專案:
vue create vue-webapp-template
// vue-webapp-template是你建立的專案名稱
複製程式碼
新的腳手架工具也給提供了視覺化介面建立和管理專案,如需使用視覺化工具搭建專案可參考——從零使用vue-cli+webpack4搭建專案。
使用命令列建立專案時,會讓你選擇預設或手動配置,我選的第二個手動配置(Manually),因為在專案裡有輕微的強迫症,沒有用到的就沒有選,具體每個部分、每個目錄是做什麼的,這個文章講的比較清楚——從零使用vue-cli+webpack4搭建專案。
移動端元件庫選型
其實,元件庫是可選可不選的,如果團隊中都是大牛,而且有專門的 UI 團隊設計複用元件,專案中所用之處皆已封裝為元件或外掛,我認為這樣的團隊完全不需使用外部的元件庫,團隊本身都代表著效率,為什麼還要參考別人的效率工具。
如果不是上面那種團隊,我覺得還是謙虛些,選一個元件庫支援基礎開發更為穩妥。畢竟,業務繁忙時,效率至上。
對比了好多個移動端元件庫,對比結果如下:
在這裡我們選用 vant。
專案初始化後執行:
// 安裝
npm i vant -S
// 安裝外掛
npm i babel-plugin-import -D
// 在.babelrc 中新增配置
// 注意:webpack 1 無需設定 libraryDirectory
{
"plugins": [
["import", {
"libraryName": "vant",
"libraryDirectory": "es",
"style": true
}]
]
}
// 對於使用 babel7 的使用者,可以在 babel.config.js 中配置
module.exports = {
plugins: [
['import', {
libraryName: 'vant',
libraryDirectory: 'es',
style: true
}, 'vant']
]
};
// 接著你可以在程式碼中直接引入 Vant 元件
// 外掛會自動將程式碼轉化為方式二中的按需引入形式
import { Button } from 'vant';
複製程式碼
基本知識
vuex資料管理
在這裡只介紹專案中如何使用 vuex 進行資料管理,具體知識點請檢視 官網。
store 目錄的設計參考官網推薦購物車案例
vuex 執行的流程圖如下:
接下來展示在元件中如何呼叫 state、getters、actions、mutations。
state&&getters
import { mapState, mapGetters } from 'vuex'
export default {
computed: {
// 使用物件展開運算子將此物件混入到外部物件中
// home代表是store中的哪一個模組
...mapState('home', {
// 箭頭函式可使程式碼更簡練
home1: state => state.home1
}),
...mapGetters('home', {
home1Getter: 'home1'
})
}
}
複製程式碼
actions&&mutations
import { mapMutations, mapActions } from 'vuex'
export default {
methods: {
...mapActions('home', {
handleActions: 'getExample'
}),
...mapMutations('home', {
handleMutations: 'handleMutations'
}),
}
}
複製程式碼
vue-router路由管理
路由管理方面採用的是一個主檔案和各個模組的路由檔案的方式,這樣維護起來會稍微舒心一些,不至於當你接到一個專案時,幾千行程式碼在一起,看著也不是很舒服。基礎目錄如下:
--router
--index.js
--home.js
--my.js
複製程式碼
index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import home from './home'
import my from './my'
Vue.use(VueRouter)
const routes = [...home, ...my]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
複製程式碼
在 index.js 裡面可以加一些全域性路由守衛的東西。
例如可以在路由的 meta 中加入每個頁面的 title,然後當使用者進入每個頁面前,判斷這個元件是否有 title 屬性,如果有的話,就按照你定義的 title 進行展示。
// 設定頁面title
router.beforeEach((to, from, next) => {
if (to.meta.title) {
document.title = to.meta.title
}
next()
})
複製程式碼
最常用的應該是當使用者未登陸時,如果想進入某個頁面,需跳轉至登陸頁面。
實現思路:加一個全域性的登陸態,並利用前端儲存儲存在本地,如果未登陸跳轉到登陸的頁面,登陸後進入本想進入的頁面。
mixin
混入 (mixin) 提供了一種非常靈活的方式,來分發 Vue 元件中的可複用功能。一個混入物件可以包含任意元件選項。當元件使用混入物件時,所有混入物件的選項將被“混合”進入該元件本身的選項。
如果你有一些公用的資料和方法,不想在另一個元件裡面再寫一遍,就可以寫一個 mixin 的 js 檔案,類似:
const homeMixin = {
// 在不止一個檔案用到的資料
data () {
return {
homeMixin: 'test-homeMixin'
}
},
// 在不止一個檔案用到的方法
methods: {
one () {
},
two () {
}
}
}
export default homeMixin
複製程式碼
在元件中如何使用呢?
// 引入
import homeMixin from 'components/common/home.js'
// 使用
export default {
mixins:[homeMixin]
}
複製程式碼
工具封裝
axios封裝(請求攔截,響應攔截)
在我這個搭建的模板專案中只是簡單的做了一點封裝,之後我自己用到這個模板後,也可以有更多的操作性。
import Vue from 'vue'
import axios from 'axios'
import { Toast } from 'vant'
Vue.use(Toast)
axios.defaults.headers['content-Type'] = 'application/json;charset=UTF-8' // 'Content-Type': 'application/x-www-form-urlencoded'
// 請求攔截
axios.interceptors.request.use(function (config) {
if (config.method === 'post') {
} else if (config.method === 'get') {
}
return config
}, function (error) {
return Promise.reject(error)
})
// 響應攔截
axios.interceptors.response.use(res => res, err => {
if (err && (err.toString().indexOf('500') > -1 || err.toString().indexOf('502') > -1 || err.toString().indexOf('404') > -1)) {
Toast('網路或介面異常')
return Promise.reject('網路或介面異常')
} else {
return Promise.reject(err)
}
})
複製程式碼
api統一管控
api 是按照每個模組建立的檔案。
--service
----api.js // axios封裝
----homeApi.js // home模組所有的請求
----myApi.js // my模組所有的請求
複製程式碼
homeApi.js
import './api.js'
import axios from 'axios'
/**
* get 案例
* @param options
*/
export const getExample = options => {
return axios.get('mock/home1.json', { params: options })
}
/**
* post 案例
* @param options
* @returns {*}
*/
export const postExample = options => {
return axios.post('mock/home2.json', options)
}
複製程式碼
更為具體的 axios 封裝和 api 統一管控的內容可以參考我的另一篇文章詳解vue中Axios的封裝與API介面的管理
常用函式封裝
utils.js
模板專案中封裝了一個日期格式化的函式,專案中可以根據自己的需要封裝幾個常用的函式。
/**
* 日期格式化 new Date(...).format('yyyy-MM-dd hh:mm:ss')
* @param fmt
* @returns {*}
*/
window.Date.prototype.format = function (fmt) {
let o = {
'M+': this.getMonth() + 1,
'd+': this.getDate(),
'h+': this.getHours(),
'm+': this.getMinutes(),
's+': this.getSeconds(),
'q+': Math.floor((this.getMonth() + 3) / 3),
'S': this.getMilliseconds()
}
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length))
}
for (var k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
}
}
return fmt
}
複製程式碼
元件化思想
什麼是元件化
元件化並不是前端所特有的,一些其他的語言或者桌面程式等,都具有元件化的先例。確切的說,只要有UI層的展示,就必定有可以元件化的地方。簡單來說,元件就是將一段UI樣式和其對應的功能作為獨立的整體去看待,無論這個整體放在哪裡去使用,它都具有一樣的功能和樣式,從而實現複用,這種整體化的細想就是元件化。不難看出,元件化設計就是為了增加複用性,靈活性,提高系統設計,從而提高開發效率。
簡而言之:一個 .vue 檔案就是一個元件
slot擴充套件元件
Vue 實現了一套內容分發的 API,這套 API 的設計靈感源自 Web Components 規範草案,將 <slot>
元素作為承載分發內容的出口。
它允許你像這樣合成元件:
<home-header title="home標題">
<p>這是slot</p>
</home-header>
複製程式碼
然後你在 <home-header>
的模板中可能會寫為:
<div id="header">
<div class="left">{{title}}</div>
<slot></slot>
</div>
複製程式碼
install封裝外掛
如果重複業務很多的話,相較於元件化,外掛化無疑是更能加快開發效率的方式。
開發外掛
Vue.js 的外掛應該暴露一個 install 方法。這個方法的第一個引數是 Vue 構造器,第二個引數是一個可選的選項物件:
MyPlugin.install = function (Vue, options) {
// 1. 新增全域性方法或屬性
Vue.myGlobalMethod = function () {
// 邏輯...
}
// 2. 新增全域性資源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 邏輯...
}
...
})
// 3. 注入元件選項
Vue.mixin({
created: function () {
// 邏輯...
}
...
})
// 4. 新增例項方法
Vue.prototype.$myMethod = function (methodOptions) {
// 邏輯...
}
}
複製程式碼
使用外掛
通過全域性方法 Vue.use()
使用外掛。它需要在你呼叫 new Vue()
啟動應用之前完成:
// 呼叫 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)
new Vue({
// ...元件選項
})
複製程式碼
也可以傳入一個可選的選項物件:
Vue.use(MyPlugin, { someOption: true })
複製程式碼
Vue.use
會自動阻止多次註冊相同外掛,屆時即使多次呼叫也只會註冊一次該外掛。
Vue.js 官方提供的一些外掛 (例如 vue-router
) 在檢測到 Vue 是可訪問的全域性變數時會自動呼叫 Vue.use()
。然而在像 CommonJS 這樣的模組環境中,你應該始終顯式地呼叫 Vue.use()
:
// 用 Browserify 或 webpack 提供的 CommonJS 模組環境時
var Vue = require('vue')
var VueRouter = require('vue-router')
// 不要忘了呼叫此方法
Vue.use(VueRouter)
複製程式碼
效率工具
rem佈局——cssrem+flexble.js
移動端最常用的佈局無非有這幾種:響應式佈局、vw + vh 佈局、rem 佈局、vm + rem 佈局。
這裡採用的是 rem 佈局,使用的是淘寶出品的 Flexible.js 。
;(function(win, lib) {
var doc = win.document;
var docEl = doc.documentElement;
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
var flexible = lib.flexible || (lib.flexible = {});
if (metaEl) {
console.warn('將根據已有的meta標籤來設定縮放比例');
var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
var content = flexibleEl.getAttribute('content');
if (content) {
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
}
if (!dpr && !scale) {
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,對於2和3的屏,用2倍的方案,其餘的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他裝置下,仍舊使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}
docEl.setAttribute('data-dpr', dpr);
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
function refreshRem(){
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
win.addEventListener('resize', function() {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener('pageshow', function(e) {
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
if (doc.readyState === 'complete') {
doc.body.style.fontSize = 12 * dpr + 'px';
} else {
doc.addEventListener('DOMContentLoaded', function(e) {
doc.body.style.fontSize = 12 * dpr + 'px';
}, false);
}
refreshRem();
flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function(d) {
var val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
}
flexible.px2rem = function(d) {
var val = parseFloat(d) / this.rem;
if (typeof d === 'string' && d.match(/px$/)) {
val += 'rem';
}
return val;
}
})(window, window['lib'] || (window['lib'] = {}));
複製程式碼
事實上 flexible.js 做了下面三件事:
- 動態改寫標籤
- 給
<html>
元素新增data-dpr屬性,並且動態改寫data-dpr的值 - 給
<html>
元素新增font-size屬性,並且動態改寫font-size的值
因為我使用的是 vsCode 編輯器,在這裡介紹一下使用 vsCode 時,如何快速的將 px-->rem。
-
下載 cssrem 外掛
-
開啟 vsCode 編譯器————檔案————首選項————設定————搜尋 cssrem ————進行設定
因為我們的設計稿尺寸是375px的,自動轉換時除以37.5得到應有的 rem 值。
解決300ms延遲
移動裝置上的瀏覽器預設會在使用者點選螢幕大約延遲300毫秒後才會觸發點選事件。
原因: 移動端的雙擊會縮放導致click判斷延遲。
安裝FastClick
npm i fastclick -S
複製程式碼
呼叫
//jquery
<script type='application/javascript' src='/path/to/fastclick.js'></script>
$(function() {
FastClick.attach(document.body);
});
//原生js
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
//vue
import FastClick from 'fastclick'
FastClick.attach(document.body);
複製程式碼
移動端測試工具v-console
平時在 web 應用開發過程中,我們可以 console.log 去輸出一些資訊,但是在移動端,也就是在手機上, console.log 的資訊我們是看不到的。
這種情況下,可以選擇使用 alert 彈出一些資訊,但是這種方法不怎麼方便,也會阻斷 JS 執行緒,導致後面的執行緒都不執行,影響除錯體驗。
那麼,如果將console.log應用到移動端呢? 需要藉助第三方外掛:vConsole
安裝
npm install vconsole
複製程式碼
在main.js引入
import Vconsole from 'vconsole';
new Vconsole();
複製程式碼
在需要的地方
console.log('內容')
複製程式碼
專案優化
使用README.md記錄每次更新的內容
在我目前的團隊,人員流動還是比較大的,而且我們的專案耦合度很低,可能幾個頁面就是一個專案,所以造成專案很多。為了其他人更快的接手一個專案,所以在開發時制定了一個規範,即在 README.md 檔案中列出每個檔案中需要共享的部分,以減少溝通成本。
> 專案相關備註
- 相關人員 `有多人情況下全部列出`
+ 業務分析師:
+ 前端開發人員:
+ 後臺開發人員:
- 環境地址 `有更多環境依次補全, 以下詳情有則補充`
* 測試環境
+ 測試環境頁面訪問地址:
+ 測試環境介面地址:
+ 測試環境部署方式:
* 生產環境
+ 生產環境頁面訪問地址:
+ 生產環境介面地址:
+ 生產環境部署方式:
- 補充說明:
- 迭代說明:
- v1.0
......
複製程式碼
分環境打包
當我們在實際開發時,最少會分三個環境:開發環境(用於本地開發)、測試環境(模擬生產環境,上線前的測試)、生產環境。
- package.json
"scripts": {
"serve": "vue-cli-service serve --open --mode development",
"build": "vue-cli-service build",
"test": "vue-cli-service build --mode test"
},
複製程式碼
具體請參看:詳解vue-cli4環境變數與分環境打包方法
mock資料
在前端開發過程中,有後臺配合是很必要的。但是如果自己測試開發,或者後臺很忙,沒時間,那麼我們需要自己提供或修改介面。下面提供兩種方式,第二種更簡單,個人推薦第二種。
mock檔案
- 安裝
npm i mockjs -D
複製程式碼
- 在 src 目錄下新建 mock 目錄
- index.js 內容如下
const Mock = require('mockjs')
Mock.mock('/test/get', 'get', require('./json/testGet'))
Mock.mock('/test/post', 'post', require('./json/testPost'))
複製程式碼
- json 檔案內容如下,以 testGet.json 為例:
{
"result": "success",
"data": {
"sex": "man",
"username": "前端林木--get",
"age": 0,
"imgUrl": ""
},
"msg": ""
}
複製程式碼
- 在main.js入口檔案中引入mock資料
if (env === 'DEV') {
require('./mock') // 引入mock資料
}
複製程式碼
- vue 中封裝,然後呼叫即可
export const getExample = options => {
return axios.get('/test/get', { params: options })
}
複製程式碼
第三方介面 eolinker
需登入,沒註冊過的小夥伴,註冊一個賬號吧。
-
註冊好後有一個預設介面,當然我們要做自己的專案。
-
新建專案
- 新增介面
- 自定義介面
- 使用介面
- 前端專案中,後臺 url 地址,有開發版,測試版,本地版等多個版本,建議大家把開發的的URL換成 mock 的地址。
webpack 優化專案
如何提高 webpack 的打包速度
-
優化 Loader
對於 Loader 來說,影響打包效率首當其衝必屬 Babel 了。因為 Babel 會將程式碼轉為字串生成 AST,然後對 AST 繼續進行轉變最後再生成新的程式碼,專案越大,轉換程式碼越多,效率就越低。當然了,我們是有辦法優化的。
首先我們可以優化 Loader 的檔案搜尋範圍
module.exports = {
module: {
rules: [
{
// js 檔案才使用 babel
test: /\.js$/,
loader: 'babel-loader',
// 只在 src 資料夾下查詢
include: [resolve('src')],
// 不會去查詢的路徑
exclude: /node_modules/
}
]
}
}
複製程式碼
對於 Babel 來說,我們肯定是希望只作用在 JS 程式碼上的,然後 node_modules 中使用的程式碼都是編譯過的,所以我們也完全沒有必要再去處理一遍。
當然這樣做還不夠,我們還可以將 Babel 編譯過的檔案快取起來,下次只需要編譯更改過的程式碼檔案即可,這樣可以大幅度加快打包時間
loader: 'babel-loader?cacheDirectory=true'
複製程式碼
-
HappyPack
受限於 Node 是單執行緒執行的,所以 Webpack 在打包的過程中也是單執行緒的,特別是在執行 Loader 的時候,長時間編譯的任務很多,這樣就會導致等待的情況。
HappyPack 可以將 Loader 的同步執行轉換為並行的,這樣就能充分利用系統資源來加快打包效率了
module: {
loaders: [
{
test: /\.js$/,
include: [resolve('src')],
exclude: /node_modules/,
// id 後面的內容對應下面
loader: 'happypack/loader?id=happybabel'
}
]
},
plugins: [
new HappyPack({
id: 'happybabel',
loaders: ['babel-loader?cacheDirectory'],
// 開啟 4 個執行緒
threads: 4
})
]
複製程式碼
-
DllPlugin
DllPlugin 可以將特定的類庫提前打包然後引入。這種方式可以極大的減少打包類庫的次數,只有當類庫更新版本才有需要重新打包,並且也實現了將公共程式碼抽離成單獨檔案的優化方案。
接下來我們就來學習如何使用 DllPlugin
// 單獨配置在一個檔案中
// webpack.dll.conf.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
// 想統一打包的類庫
vendor: ['react']
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].dll.js',
library: '[name]-[hash]'
},
plugins: [
new webpack.DllPlugin({
// name 必須和 output.library 一致
name: '[name]-[hash]',
// 該屬性需要與 DllReferencePlugin 中一致
context: __dirname,
path: path.join(__dirname, 'dist', '[name]-manifest.json')
})
]
}
複製程式碼
然後我們需要執行這個配置檔案生成依賴檔案,接下來我們需要使用 DllReferencePlugin 將依賴檔案引入專案中
// webpack.conf.js
module.exports = {
// ...省略其他配置
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
// manifest 就是之前打包出來的 json 檔案
manifest: require('./dist/vendor-manifest.json'),
})
]
}
複製程式碼
-
程式碼壓縮
在 Webpack3 中,我們一般使用 UglifyJS 來壓縮程式碼,但是這個是單執行緒執行的,為了加快效率,我們可以使用 webpack-parallel-uglify-plugin 來並行執行 UglifyJS,從而提高效率。
在 Webpack4 中,我們就不需要以上這些操作了,只需要將 mode 設定為 production 就可以預設開啟以上功能。程式碼壓縮也是我們必做的效能優化方案,當然我們不止可以壓縮 JS 程式碼,還可以壓縮 HTML、CSS 程式碼,並且在壓縮 JS 程式碼的過程中,我們還可以通過配置實現比如刪除 console.log 這類程式碼的功能。
-
一些小的優化點
我們還可以通過一些小的優化點來加快打包速度
- resolve.extensions:用來表明檔案字尾列表,預設查詢順序是 ['.js', '.json'],如果你的匯入檔案沒有新增字尾就會按照這個順序查詢檔案。我們應該儘可能減少字尾列表長度,然後將出現頻率高的字尾排在前面
- resolve.alias:可以通過別名的方式來對映一個路徑,能讓 Webpack 更快找到路徑
- module.noParse:如果你確定一個檔案下沒有其他依賴,就可以使用該屬性讓 Webpack 不掃描該檔案,這種方式對於大型的類庫很有幫助
如何用 webpack 來優化前端效能
⽤webpack優化前端效能是指優化webpack的輸出結果,讓打包的最終結果在瀏覽器執行快速⾼效。
- 壓縮程式碼:刪除多餘的程式碼、註釋、簡化程式碼的寫法等等方式。可以利⽤ webpack 的 UglifyJsPlugin 和 ParallelUglifyPlugin 來壓縮 JS ⽂件, 利⽤ cssnano (css-loader?minimize)來壓縮 css。
- 利⽤CDN加速: 在構建過程中,將引⽤的靜態資源路徑修改為CDN上對應的路徑。可以利⽤webpack對於 output 引數和各loader的 publicPath 引數來修改資源路徑。
- Tree Shaking: 將程式碼中永遠不會⾛到的⽚段刪除掉。可以通過在啟動webpack時追加引數 --optimize-minimize 來實現。
- Code Splitting: 將程式碼按路由維度或者元件分塊(chunk),這樣做到按需載入,同時可以充分利⽤瀏覽器快取。
- 提取公共第三⽅庫: SplitChunksPlugin 外掛來進⾏公共模組抽取,利⽤瀏覽器快取可以⻓期快取這些⽆需頻繁變動的公共程式碼。
骨架屏展示
專案 demo 中使用的是 vant 中的 Skeleton 骨架屏
// 引入
import Vue from 'vue';
import { Skeleton } from 'vant';
Vue.use(Skeleton);
複製程式碼
// 展示子元件
// 將loading屬性設定成false表示內容載入完成,此時會隱藏佔點陣圖,並顯示Skeleton的子元件
<van-skeleton
title
avatar
:row="3"
:loading="loading"
>
<div>實際內容</div>
</van-skeleton>
export default {
data() {
return {
loading: true
}
},
mounted() {
this.loading = false;
}
};
複製程式碼
如果想自己搭建一個骨架屏,給大家幾個參考連結:
總結
以上就是 vue 移動端整體大的專案架構設計了(webpack 有一部分沒做演示,有需要的童鞋要實踐一下哦),總結一篇文章好辛苦。
2020-1-10 0:55
晚安~