亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

VueRouter路由模式全面解析

 更新時間:2023年06月06日 10:37:24   作者:dralexsanderl  
這篇文章主要介紹了VueRouter路由模式的用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

VueRouter路由模式

前端路由的實(shí)現(xiàn)方式主要有兩種:hash模式和history模式。

hash模式

window.location對象中有一個hash字段,可以獲取地址欄中#字符及后邊的所有字符。

hash也稱作錨點(diǎn),本身是用來做頁面定位的,可以使對應(yīng)id的元素顯示在可是區(qū)域內(nèi)。

比如說下面這張動圖,通過錨點(diǎn)直接跳轉(zhuǎn)到footer

請?zhí)砑訄D片描述

hash 雖然出現(xiàn)在 URL 中,但不會被包括在 HTTP 請求中,不會對請求有影響。

下圖可以看到雖然地址是http://localhost:3000/index.html#footer,但是network中的請求是http://localhost:3000/index.html。

請?zhí)砑訄D片描述

由于hash值變化不會導(dǎo)致瀏覽器向服務(wù)器發(fā)出請求,而且hash改變會觸發(fā)hashchange事件,瀏覽器的進(jìn)后退也能對其進(jìn)行控制,所以在 html5history 出現(xiàn)前,開發(fā)者基本都是使用 hash 來實(shí)現(xiàn)前端路由的。

history模式

HTML5規(guī)范提供了history.pushStatehistory.replaceState來進(jìn)行路由控制。

通過這兩個方法可以改變url且不向服務(wù)器發(fā)送請求。

同時不會像hash有一個#,更加的美觀。

但是如果刷新頁面,那么請求的資源就是當(dāng)前地址欄中的地址了,對于SPA應(yīng)用來說就需要進(jìn)行配置將所有的路由重定向到根頁面。

調(diào)用pushState跳轉(zhuǎn)到相同的路由時仍可以成功且路由棧數(shù)量會加1。

這個可以重寫pushState方法來進(jìn)行過濾。

const stack = [];
const originPushState = window.history.pushState;
window.history.pushState = function() {
  if(stack[stack.length - 1] === arguments[2]) {
    return;
  }
  stack.push(arguments[2])
  originPushState.call(history, ...arguments);
}

history.replaceStatehistory.pushState 卻不會觸發(fā) popstate 事件,不過可以手動創(chuàng)建一個PopStateEvent并觸發(fā)該事件。

function createPopStateEvent(state, title) {
  return new PopStateEvent("popstate", {
    state: state,
    title: title
  });
}
window.history.pushState = function() {
  if(stack[stack.length - 1] === arguments[2]) {
    return;
  }
  stack.push(arguments[2])
  window.dispatchEvent(createPopStateEvent(...arguments));
  originPushState.call(history, ...arguments);
}

VueRouter中的路由模式

文章中介紹的vue-router源碼版本為v3.4.9

hash模式

hash模式中,VueRouter主要還是以history.pushState為首選,在不支持history的瀏覽器中才會通過改變location.hash的值來實(shí)現(xiàn)路由切換。

在源碼中的hash.js文件中的pushHash方法明確定義。

// src/history/hash.js
function pushHash (path) {
  if (supportsPushState) {
    pushState(getUrl(path))
  } else {
    window.location.hash = path
  }
}

同時在beforeCreate監(jiān)聽hashchange方法,防止用戶直接在地址欄上修改url。

通過點(diǎn)擊跳轉(zhuǎn)的方式VueRouter做了處理并不會觸發(fā)該方法。

const eventType = supportsPushState ? 'popstate' : 'hashchange'
window.addEventListener(
  eventType,
  handleRoutingEvent
)

hash模式為什么首先考慮使用history.pushState呢?

因?yàn)橥ㄟ^history.pushState可以設(shè)置state值,VueRouter在每個路由跳轉(zhuǎn)時帶有唯一的key,可以用于在瀏覽器后退前進(jìn)時恢復(fù)到之前的滾動的位置。

在源碼中的pushState方法中可以看到,在跳轉(zhuǎn)前保存當(dāng)前路由的滾動條位置,同時為跳轉(zhuǎn)路由添加一個新key標(biāo)識新路由。

function pushState (url?: string, replace?: boolean) {
  saveScrollPosition()
  const history = window.history
  // safari存在問題,路由棧中只能保存100,超過100個異常捕獲用location來替換路由對象
  try {
    if (replace) {
      const stateCopy = extend({}, history.state)
     stateCopy.key = getStateKey()
     history.replaceState(stateCopy, '', url)
   } else {
     history.pushState({ key: setStateKey(genStateKey()) }, '', url)
   }
 } catch (e) {
    window.location[replace ? 'replace' : 'assign'](url)
  }
}

history模式

在初始化history模式時,監(jiān)聽popstate,在路由變化時恢復(fù)滾動條位置。

// src/history/html5.js
this.transitionTo(location, (route) => {
  if (supportsScroll) {
    handleScroll(router, route, current, true)
  }
})
window.addEventListener('popstate', handleRoutingEvent)

前面提到history.pushStatehistory.replaceState兩個方法不會觸發(fā)popstate方法,因此在pushreplace方法中,在路由切換成功后手動執(zhí)行hashScroll方法。

// src/history/html5.js
push(location: RawLocation, onComplete?: Function, onAbort?: Function) {
    const { current: fromRoute } = this
    this.transitionTo(
      location,
      (route) => {
        pushState(cleanPath(this.base + route.fullPath))
        handleScroll(this.router, route, fromRoute, false)
        onComplete && onComplete(route)
      },
      onAbort
    )
  }

abstract模式

VueRouter中除了hashhistory兩種模式外,還新增了一個abstract模式,用來在不支持瀏覽器的環(huán)境中充當(dāng)一個備用方案(例如Weex)。

abstract模式中新建了一個對象用來模擬瀏覽器中路由棧。

this.stack = []

同時提供了三個路由跳轉(zhuǎn)方法push、replacego,這三種方法跟hashhistory模式中的pushreplacego方法類似,來看看是怎么實(shí)現(xiàn)的。

// src/history/abstract.js push()方法
route => {
  // 在路由棧中添加一個新路由
  this.stack = this.stack.slice(0, this.index + 1).concat(route)
  this.index++
  onComplete && onComplete(route)
}

因?yàn)榉菫g覽器環(huán)境中沒有前進(jìn)后退按鈕,因此replace其實(shí)就是替換掉路由棧中的最后一個路由。

// src/history/abstract.js replace()方法
route => {
  // 在路由棧中替換掉最后一個路由
  this.stack = this.stack.slice(0, this.index).concat(route)
  this.index++
  onComplete && onComplete(route)
}

go方法中同樣對傳入的數(shù)字進(jìn)行判斷是否在路由棧的范圍內(nèi),否則不執(zhí)行。

// src/history/abstract.js go()方法
const targetIndex = this.index + n
if (targetIndex < 0 || targetIndex >= this.stack.length) {
  return
}

之后直接將路由索引指向需要跳轉(zhuǎn)的路由索引同時更新當(dāng)前路由。

// src/history/abstract.js go()方法
const route = this.stack[targetIndex]
this.confirmTransition(
  route,
  () => {
  this.index = targetIndex
  this.updateRoute(route)
  // ...
)
// src/history/base.js
updateRoute(route: Route) {
  this.current = route
  this.cb && this.cb(route)
}

無論是hash還是history模式都需要對瀏覽器當(dāng)前的URL產(chǎn)生影響,通過與abstract結(jié)合也可以實(shí)現(xiàn)在已存在的路由頁面中內(nèi)嵌其他的路由頁面,而保持在瀏覽器當(dāng)中依舊顯示當(dāng)前頁面的路由path。

比如定義了一個hash模式并存在兩個路由的實(shí)例掛載在app上,其中第二個路由中又定義一個abstract模式的路由。這時候切換/route1/route2并不會影響URL。

const routes = [
  {
    path: '/',
    component: { template: `<div>default view</div>` }
  },
  {
    path: '/abstractRoute',
    component: {
      name: "abstract",
      template: '<div><h1 @click="toRoute(1)">跳轉(zhuǎn)到router1</h1><h1 @click="toRoute(2)">跳轉(zhuǎn)到router2</h1><router-view></router-view></div>',
      methods: {
        toRoute(num) {
          this.$router.push(`/route${num}`);
        }
      },
      router: new VueRouter({
        routes: [
          {
            path: '/route1',
            component: {template:'<h1>abstract route 1</h1>'}
          },
          {
            path: '/route2',
            component: { template:'<h1>abstract route 2</h1>'}
          },
        ],
        mode: 'abstract'
      })
    }
  },
]
const app = new Vue({
  router: new VueRouter({
    routes,
    mode: 'hash'
  }),
  template: `<div><router-link to="/">to /</router-link>
    <router-link to="/abstractRoute">to abstractRoute</router-link>
    <router-view></router-view>
    </div>`,
}).$mount('#app')

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue?數(shù)據(jù)綁定事件綁定樣式綁定語法示例

    Vue?數(shù)據(jù)綁定事件綁定樣式綁定語法示例

    這篇文章主要為大家介紹了Vue?數(shù)據(jù)綁定事件綁定樣式綁定語法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Vue.js中vue-property-decorator的使用方法詳解

    Vue.js中vue-property-decorator的使用方法詳解

    vue-property-decorator是一個用于在Vue.js中使用TypeScript裝飾器的庫,它能夠簡化 Vue 組件的定義,使代碼更加簡潔和可維護(hù),它能夠簡化Vue組件的定義,使代碼更加簡潔和可維護(hù),本文將深入探討vue-property-decorator的使用方法,并展示如何在Vue.js項(xiàng)目中應(yīng)用它
    2024-08-08
  • vue全局接入百度地圖的實(shí)現(xiàn)示例

    vue全局接入百度地圖的實(shí)現(xiàn)示例

    本文主要介紹了vue全局接入百度地圖的實(shí)現(xiàn)示例,文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Vue3?企業(yè)級組件庫框架搭建?pnpm?monorepo實(shí)戰(zhàn)示例

    Vue3?企業(yè)級組件庫框架搭建?pnpm?monorepo實(shí)戰(zhàn)示例

    這篇文章主要為大家介紹了Vue3?企業(yè)級組件庫框架搭建?pnpm?monorepo實(shí)戰(zhàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • vue2.0多條件搜索組件使用詳解

    vue2.0多條件搜索組件使用詳解

    這篇文章主要為大家詳細(xì)介紹了vue2.0多條件搜索組件的實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Vue2.0用 watch 觀察 prop 變化(不觸發(fā))

    Vue2.0用 watch 觀察 prop 變化(不觸發(fā))

    本篇文章主要介紹了Vue2.0用 watch 觀察 prop 變化(不觸發(fā)),非常具有實(shí)用價值,需要的朋友可以參考下
    2017-09-09
  • Vue3中創(chuàng)建異步組件的流程步驟

    Vue3中創(chuàng)建異步組件的流程步驟

    在現(xiàn)代前端開發(fā)中,組件的重用性和異步加載是提升用戶體驗(yàn)和優(yōu)化性能的關(guān)鍵因素,在Vue 3中,創(chuàng)建異步組件變得更為便利,本文將探討如何在Vue 3中使用setup語法糖來創(chuàng)建異步組件,感興趣的小伙伴跟著小編一起來看看吧
    2024-09-09
  • vue項(xiàng)目中使用多選框的實(shí)例代碼

    vue項(xiàng)目中使用多選框的實(shí)例代碼

    這篇文章主要介紹了vue項(xiàng)目中使用多選框的實(shí)例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • 淺談vue 單文件探索

    淺談vue 單文件探索

    這篇文章主要介紹了淺談vue 單文件探索,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • Vue2中的過濾器filter使用及注意說明

    Vue2中的過濾器filter使用及注意說明

    這篇文章主要介紹了Vue2中的過濾器filter使用及注意說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09

最新評論