最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

VueRouter路由模式全面解析

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

VueRouter路由模式

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

hash模式

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

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

比如說下面這張動圖,通過錨點直接跳轉(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值變化不會導致瀏覽器向服務器發(fā)出請求,而且hash改變會觸發(fā)hashchange事件,瀏覽器的進后退也能對其進行控制,所以在 html5history 出現(xiàn)前,開發(fā)者基本都是使用 hash 來實現(xiàn)前端路由的。

history模式

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

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

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

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

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

這個可以重寫pushState方法來進行過濾。

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的值來實現(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。

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

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

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

因為通過history.pushState可以設置state值,VueRouter在每個路由跳轉(zhuǎn)時帶有唯一的key,可以用于在瀏覽器后退前進時恢復到之前的滾動的位置。

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

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,在路由變化時恢復滾動條位置。

// 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)境中充當一個備用方案(例如Weex)。

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

this.stack = []

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

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

因為非瀏覽器環(huán)境中沒有前進后退按鈕,因此replace其實就是替換掉路由棧中的最后一個路由。

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

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

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

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

// 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模式都需要對瀏覽器當前的URL產(chǎn)生影響,通過與abstract結合也可以實現(xiàn)在已存在的路由頁面中內(nèi)嵌其他的路由頁面,而保持在瀏覽器當中依舊顯示當前頁面的路由path。

比如定義了一個hash模式并存在兩個路由的實例掛載在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')

總結

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

相關文章

  • 八個Vue中常用的v指令詳解

    八個Vue中常用的v指令詳解

    vue常用指令有v-once指令、v-show指令、v-if指令、v-else指令、v-else-if指令、v-for指令、v-html指令、v-text指令、v-bind指令、v-on指令、v-model指令等等,下面這篇文章主要給大家介紹了八個Vue中常用的v指令的相關資料,需要的朋友可以參考下
    2022-04-04
  • vue綁定事件后獲取綁定事件中的this方法

    vue綁定事件后獲取綁定事件中的this方法

    今天小編就為大家分享一篇vue綁定事件后獲取綁定事件中的this方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 詳解Vue 單文件組件的三種寫法

    詳解Vue 單文件組件的三種寫法

    這篇文章主要介紹了詳解Vue 單文件組件的三種寫法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • el-descriptions引入代碼中l(wèi)abel不生效問題及解決

    el-descriptions引入代碼中l(wèi)abel不生效問題及解決

    這篇文章主要介紹了el-descriptions引入代碼中l(wèi)abel不生效問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 基于vue-cli3+typescript的tsx開發(fā)模板搭建過程分享

    基于vue-cli3+typescript的tsx開發(fā)模板搭建過程分享

    這篇文章主要介紹了搭建基于vue-cli3+typescript的tsx開發(fā)模板,本文通過實例代碼截圖的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • vue動態(tài)綁定class選中當前列表變色的方法示例

    vue動態(tài)綁定class選中當前列表變色的方法示例

    這篇文章主要介紹了vue動態(tài)綁定class選中當前列表變色的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • Uniapp圖片上傳的兩種實現(xiàn)方式詳解

    Uniapp圖片上傳的兩種實現(xiàn)方式詳解

    UniApp是一個跨平臺的前端框架,它允許開發(fā)者使用一套代碼構建同時運行在微信小程序、H5、iOS、Android等多個平臺的應用,在UniApp中,上傳圖片通常涉及到使用其提供的File?API或者第三方插件來進行操作,所以本文給大家介紹了Uniapp圖片上傳的兩種實現(xiàn)方式
    2025-10-10
  • 詳解vue中v-bind:style效果的自定義指令

    詳解vue中v-bind:style效果的自定義指令

    這篇文章主要介紹了vue中v-bind:style效果的自定義指令,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • 解決el-cascader在IE11瀏覽器中加載頁面自動展開下拉框問題

    解決el-cascader在IE11瀏覽器中加載頁面自動展開下拉框問題

    這篇文章主要為大家介紹了解決el-cascader在IE11瀏覽器中加載頁面自動展開下拉框問題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • vue使用路由技術實現(xiàn)登錄成功后跳轉(zhuǎn)到首頁

    vue使用路由技術實現(xiàn)登錄成功后跳轉(zhuǎn)到首頁

    本文主要介紹了vue使用路由技術實現(xiàn)登錄成功后跳轉(zhuǎn)到首頁,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-05-05

最新評論

靖边县| 达拉特旗| 宿迁市| 临武县| 鹿邑县| 甘谷县| 莱西市| 防城港市| 宽城| 西青区| 黄骅市| 辛集市| 五峰| 乌鲁木齐市| 大丰市| 胶南市| 宜黄县| 通州市| 池州市| 浙江省| 牙克石市| 兴隆县| 哈密市| 洪雅县| 商城县| 滨海县| 南郑县| 英德市| 隆安县| 桐城市| 内丘县| 犍为县| 延津县| 右玉县| 梅州市| 鄂伦春自治旗| 吉林省| 陈巴尔虎旗| 育儿| 乡城县| 饶河县|