1.項目架構(gòu)
項目使用到的技術(shù)vue-cli + vue-echarts + sass + axios
2.項目搭建
2.1 安裝vue-cli
npm i -g vue-cli
2.2 初始化項目
vue init webpack project-name
2.3運行
npm run dev
3.路由history模式
vue-router 默認(rèn) hash 模式 —— 使用 URL 的 hash 來模擬一個完整的 URL恨锚,于是當(dāng) URL 改變時厌丑,頁面不會重新加載薪缆。
如果不想要很丑的 hash漾唉,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉(zhuǎn)而無須重新加載頁面膛壹。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
以上是官方文檔的原理介紹和使用方式驾中,筆者在本地測試完全沒有問題,當(dāng)項目開發(fā)完成打包放到服務(wù)器時恢筝,如果項目目錄不在服務(wù)器根目錄哀卫,會出現(xiàn)路由和資源文件路徑找不到的情況,此時頁面留白(下文會做處理)
以下為解決方案,配置base路由為服務(wù)器項目地址,routers中的所有路由將以“base+path”的形式訪問
const router = new VueRouter({
mode: 'history',
base: ' /public/project-name', //值為服務(wù)器項目地址
routes: [...]
})
為優(yōu)化用戶體驗撬槽,routers路由中增加匹配不到的情況統(tǒng)一處理為404頁面
routes: [
// 覆蓋所有匹配不到的路由
{
path: '*',
component: notFound //404頁面組件
},
]
4.網(wǎng)絡(luò)層axios的封裝
- 根據(jù)不同環(huán)境切換不同的baseUrl
- 對請求前的token校驗和請求后的狀態(tài)碼和數(shù)據(jù)處理
- 控制loading的顯示隱藏
import axios from 'axios'
// 根據(jù)不同環(huán)境設(shè)置對應(yīng)的baseURL
if (process.env.NODE_ENV == 'development') { //開發(fā)環(huán)境
axios.defaults.baseURL = '/dev';
} else {
axios.defaults.baseURL = location.origin;
}
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios.defaults.timeout = 8e3;
const that = this
//請求時的攔截
axios.interceptors.request.use(function (config) {
//發(fā)送請求前做的處理
if (that.$store.state.token) { // 判斷是否存在token此改,如果存在的話,則每個http header都加上token
config.headers.Authorization = `${that.$store.state.token}`;
}
return config
}, function (error) {
//異常請求時作處理
return Promise.reject(error)
})
// 響應(yīng)時的攔截
axios.interceptors.response.use(function (response) {
if (response.status == 200 && response.statusText == 'OK') {
//返回響應(yīng)時做一些處理
return response
}
}, function (error) {
throw Error('服務(wù)器異常')
if(error.response.status == 404){
alert('接口不存在')
}else if(error.response.status == 550){
alert('服務(wù)器異常')
}
//響應(yīng)異常時做一些處理
return Promise.reject(error)
})
//將axios掛載到vue原型鏈上暴露為全局
Vue.prototype.$http = axios
封裝好之后侄柔,在main.js中引入
import $http from '../http/http' //路徑自行修改
全局使用
this.$http
.get('http://www.baidu.com')
.then(function(response) {
console.log(response)
})
.catch(function(error) {
console.log(error);
});
}
5.頁面刷新導(dǎo)致的問題
項目類型為web APP共啃,點擊各自模塊展示不同頁面,并將此模塊tab文字和圖片高亮顯示,以下為邏輯代碼:
<router-link :to="{ path: '/'}" replace exact><img :src="curTabIndex == '1' ? choosedSrc : './static/img/tab_1.png'" alt=""><p>首頁</p></router-link>
//此處img的src根據(jù)curTabIndex 值來控制顯示高亮
export default {
data () {
return{
curTabIndex: 1, //當(dāng)前點擊的tab索引值暂题,默認(rèn)1(項目首頁)
}
},
methods: {
tabClick (index,event) {
this.curTabIndex = index //置為當(dāng)前索引
}
}
}
復(fù)現(xiàn)bug
假設(shè)當(dāng)前有4個tab,當(dāng)我們點擊第三個tab后嘗試刷新頁面后移剪,注意:此時頁面的第一個tab高亮顯示,這是因為vue是單頁面應(yīng)用,用戶操作頁面都是無刷新來更新數(shù)據(jù)的薪者,此時data中curTabIndex值恢復(fù)為默認(rèn)值1纵苛。
解決方案
思路:我們知道單頁應(yīng)用原理為根據(jù)不同路由加載不同視圖,那么當(dāng)頁面created時可以根據(jù)當(dāng)前頁面的路由值(可通過location.pathname獲取)來動態(tài)修改curTabIndex 值言津,看代碼:
created() {
this.hightImg()
},
methods: {
tabClick(index, event) {
this.curTabIndex = index;
},
hightImg() {
if (location.pathname == "/sec") {
this.curTabIndex = '2' //對應(yīng)tab2
} else if (location.pathname == "/third") {
this.curTabIndex = '3' //對應(yīng)tab3
} else if (location.pathname == "/fourth") {
this.curTabIndex = '4' //對應(yīng)tab4
} else {
this.curTabIndex = '1' //對應(yīng)tab1
}
}
}
6.打包優(yōu)化
6.1未優(yōu)化之前文件大小
未優(yōu)化之前資源加載耗時
優(yōu)化點:
1.主文件vendor
2.echarts庫
優(yōu)化方案:
1.vue-echart組件庫改為按需引入
2.定制echarts庫 http://echarts.baidu.com/builder.html
3.路由懶加載
6.2優(yōu)化后的打包文件
優(yōu)化后資源加載耗時
7.兼容性問題
問題:安卓所有機(jī)型自帶瀏覽器頁面無法加載(留白)攻人,ios無任何問題。
排查:引用vconsole查找報錯悬槽。
注意:eval方法只能在非嚴(yán)格模式中進(jìn)行使用怀吻,在strict mode下是不允許使用這個方法的。
解決方案:
1.針對報錯文件單獨進(jìn)行編譯初婆,注意4818行代碼蓬坡;
2.在webpack配置文件中添加此文件;