vue-router項目實戰總結篇,vue-router實戰總結
今天來談談vue項目{vue,vue-router,component
}三大神將之一的vue-router。作為我們前後端分離很重要的實踐之一,router幫我們完成了SPA應用間的頁面跳轉。
並且,配合axios這樣的第三方庫,我們可以實現配合後台介面的攔截器功能。
對於一個小型項目而言,router這個檔案夾裡面就包含了一個router.js就足夠了,
但是,當我們的頁面比較多的時候,我們就需要分出兩個檔案出來:一個定義我們的路由和組件,另一個執行個體化組件,並將路由掛載到vue的執行個體上。
基本的用法就不多贅述,大家可以看vue-router的官網,認真過一遍的話,基本使用肯定沒什麼問題。
1.為什麼我的路由不起作用?
這裡有個非常重要的一點就是當我們去構造VueRouter的執行個體的時候,傳入的參數的問題。
import routes from '@/router/router'const router = new VueRouter({ routes // (ES6文法)相當於 routes: routes})new Vue({ router}).$mount('#app')
如果你這裡引入的不是routes,你就要按照下面的方式來寫。
import vRoutes from '@/router/router'const router = new VueRouter({ routes :vRoutes })new Vue({ router}).$mount('#app')
2.在路由中基於webpack實現組件的懶載入
對於我們的vue項目,我們基本都是運用webpack打包的,如果沒有懶載入,打包後的檔案將會異常的大,造成首頁白屏,延時嚴重,不利於使用者體驗,而運用懶載入則可以將頁面進行劃分,webpack將不同組件打包成很多個小的js檔案。需要的時候再非同步載入,最佳化使用者的體驗,換而言之,有的頁面可能100個使用者只有一兩個會進去,何必把流量花在它身上。
import App from '@/App.vue'const index = r => require.ensure([], () => r(require('@/pages/index/index')), 'index')export default [{ path: '/', component: App, children: [ { path: '/index', name:'index', component: index }]}]
如果某個組件包含了嵌套路由,我們也可以將兩個路由打包到一個js chunk中。
// 這兩條路由被打包在相同的塊中,訪問任一路由都會消極式載入該路由群組件const orderUser= r => require.ensure([], () => r(require('@/pages/order/user')), 'order')const payRecord= r => require.ensure([], () => r(require('@/pages/order/payRecord')), 'order')
3.router的模式
對於瀏覽器,我們的router分為兩種模式。
1.hash模式(預設)
按照一個uri的基本結構來說,hash模式就是在一個基本的URI的片段進行的處理。如果拋開SPA的話,比較常見的應用情境就是我們在做pc商城的時候,會有比如說:商品詳情,評論,商品參數這樣的tab切換,就可以使用a標籤配合id使用,加上一點運動的特效,效果甚佳。
這也是router預設使用的路由方式。不過,這種方式有一個弊端,就是在接入第三方的支付的時候,我們傳入一個url給到第三方支付作為回調地址,但是在支付完成以後,有的第三方支付會把我們的#作為一個截取符號,僅保留第一個#符號前面的url內容,後面再添加相應的回調參數。導致支付完成以後無法跳轉到相應的支付頁面
傳入的url:
http://xx.xx.com/#/pay/123
回調後的地址:
http://xx.xx.com/pay/123?data=xxxxx%xxxx
2.history模式
還有一種就是history的模式。它是使用h5的history.pushState來完成URL的跳轉的。使用這種方式來處理跳轉的好處就是,url和我們平常看到的沒有什麼區別。和hash模式作比較的話就是沒有了#。不過使用history模式,我們在後台也要去做相應的處理,因為如果直接去訪問一個地址,例如http://www.xxxx.com/user/id的時候,如果後端沒有配置的時候,後端就會返回404頁面。
4.router-link在迴圈中this.參數名=undefined
<router-link>組件是我們在view層中需要用到的跳躍群組件。它替代了<a>標籤需要做的事情,並且協助我們做了更多的事情。
無論是 h5 history 模式還是 hash 模式,它的表現行為一致,所以,當你要切換路由模式,或者在 IE9 降級使用 hash 模式,無須任何變動。
在 HTML5 history 模式下,router-link 會守衛點擊事件,讓瀏覽器不再重新載入頁面。
當你在 HTML5 history 模式下使用 base 選項之後,所有的 to 屬性都不需要寫(基路徑)了。
不過當我們在v-for的迴圈中使用了router-link的時候,一般來說,我們需要取的都是迴圈裡的值,通過定義的item.xxx就可以取到。如果說需要取一個我們在data中定義的值的時候,我們是通過this.foo來取呢?還是通過foo來取呢?還是都可以?
這裡的話,我們是不能通過this.foo來取的,因為這裡的this,不再是指向vue的執行個體了,而是指向了[object Window]。所以用this.foo來取的話,其實是undefined.
<router-link tag="li" :to="{path:`/user/${item.userID}`}" v-for="(item, index) in userList" :key="index"> //含有固定的值 <p>{{this.foo}}</p> <p>{{foo}}</p> </router-link>data(){ return { foo:'bar', } }
4.vue-router配合axios的使用
初次接觸攔截器這個概念是在java中,通過攔截器,我們可以對使用者的登入狀態進行更加粒度的操作。而對於一個SPA的應用來說,沒有了後台路由的介入,我們就需要在前端實現一套自己的登入狀態的管理機制。
最直觀的一點就是,通過使用者的token來判斷使用者是否登入?
router.beforeEach((to, from, next) => { const NOW = new Date().getTime(); if (to.matched.some(r => r.meta.requireAuth)) { if(NOW > store.state.deadLine){ store.commit('CLEAR_USERTOKEN') } if (store.state.message.login === true) { next(); } else { next({ path: '/login', query: {redirect: to.fullPath} }) } } else { next(); }})
上面的代碼中,我們通過vue-router中的全域守衛,在導航觸發的時候大致做了如下幾件事:
(1)判斷導航的頁面是否需要登入
(2)超過登入持久期限,清除持久化的登入使用者token
(3)沒有超過登入期限,判斷是否登入狀態
(4)沒登入,重新導向到登入頁面
但是,僅僅這樣是不夠的。因為使用者直接不正常登出而直接後台運行網頁是很正常的事情,這就導致雖然token是存在的,但是對於後台而言,這個token是無效的,到期的了。所以,我們需要axios配合後台給出的狀態代碼來完善我們的攔截器。
import router from '@/router/routes'axios.interceptors.response.use( success => { switch (success .code) { case -100: router.replace({ path: 'login', query: {redirect: router.currentRoute.fullPath} }) console.warn('注意,登入已到期!') break; } return success; }, error => { switch (error.code) { case 404: console.warn('請求地址有誤或者參數錯誤!') break; } return Promise.reject(error.response.data) });
通過後端給到的登入到期狀態代碼,這裡以-100為例,我們可以用axios的響應攔截器實現,當我們的token到期的時候,我們將頁面重新導向到登入頁面去。
5.巧用replace替換push
在項目中,我有的同事就是一直this.$router.push(...)
,從開始push到結尾。
碰到有的頁面,比如說,在選擇地址的時候需要知道使用者當前所在的城市,如果沒有的話,就是重新導向到城市列表頁面去手動選取。選擇完成以後再回到選擇地址的頁面,如果一直使用push的話,點擊選擇地址的後退時,就會回退到城市列表頁。然後造成頁面間的死迴圈。
這裡如果使用replace來操作就沒有什麼問題了,問題就是我們不應該讓城市列表頁出現在我們的瀏覽歷史裡面。
總結
以上所述是小編給大家介紹的vue-router項目實戰總結,希望對大家有所協助,如果大家有任何疑問請給我留言,小編會及時回複大家的。在此也非常感謝大家對幫客之家網站的支援!