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

Vue中的路由導(dǎo)航守衛(wèi)導(dǎo)航解析流程

 更新時(shí)間:2023年04月20日 08:30:18   作者:itpeilibo  
這篇文章主要介紹了Vue中的路由導(dǎo)航守衛(wèi)導(dǎo)航解析流程,正如其名,vue-router 提供的導(dǎo)航守衛(wèi)主要用來(lái)通過(guò)跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航。這里有很多方式植入路由導(dǎo)航中:全局的,單個(gè)路由獨(dú)享的,或者組件級(jí)的

正如其名,vue-router 提供的導(dǎo)航守衛(wèi)主要用來(lái)通過(guò)跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航。這里有很多方式植入路由導(dǎo)航中:全局的,單個(gè)路由獨(dú)享的,或者組件級(jí)的。

全局前置守衛(wèi)

你可以使用 router.beforeEach 注冊(cè)一個(gè)全局前置守衛(wèi):

const router = createRouter({ ... })
router.beforeEach((to, from) => {
  // ...
  // 返回 false 以取消導(dǎo)航
  return false
})

當(dāng)一個(gè)導(dǎo)航觸發(fā)時(shí),全局前置守衛(wèi)按照創(chuàng)建順序調(diào)用。守衛(wèi)是異步解析執(zhí)行,此時(shí)導(dǎo)航在所有守衛(wèi) resolve 完之前一直處于等待中。

每個(gè)守衛(wèi)方法接收兩個(gè)參數(shù):

  • to: 即將要進(jìn)入的目標(biāo)
  • from: 當(dāng)前導(dǎo)航正要離開(kāi)的路由

可以返回的值如下:

  • false: 取消當(dāng)前的導(dǎo)航。如果瀏覽器的 URL 改變了(可能是用戶手動(dòng)或者瀏覽器后退按鈕),那么 URL 地址會(huì)重置到 from 路由對(duì)應(yīng)的地址。
  • 一個(gè)路由地址: 通過(guò)一個(gè)路由地址跳轉(zhuǎn)到一個(gè)不同的地址,就像你調(diào)用 router.push() 一樣,你可以設(shè)置諸如 replace: truename: 'home' 之類的配置。當(dāng)前的導(dǎo)航被中斷,然后進(jìn)行一個(gè)新的導(dǎo)航,就和 from 一樣。
 router.beforeEach(async (to, from) => {
   if (
     // 檢查用戶是否已登錄
     !isAuthenticated &&
     // ?? 避免無(wú)限重定向
     to.name !== 'Login'
   ) {
     // 將用戶重定向到登錄頁(yè)面
     return { name: 'Login' }
   }
 })

如果遇到了意料之外的情況,可能會(huì)拋出一個(gè) Error。這會(huì)取消導(dǎo)航并且調(diào)用 router.onError() 注冊(cè)過(guò)的回調(diào)。

如果什么都沒(méi)有,undefined 或返回 true,則導(dǎo)航是有效的,并調(diào)用下一個(gè)導(dǎo)航守衛(wèi)

以上所有都同 async 函數(shù) 和 Promise 工作方式一樣:

router.beforeEach(async (to, from) => {
  // canUserAccess() 返回 `true` 或 `false`
  const canAccess = await canUserAccess(to)
  if (!canAccess) return '/login'
})

可選的第三個(gè)參數(shù) next

在之前的 Vue Router 版本中,也是可以使用 第三個(gè)參數(shù) next 的。這是一個(gè)常見(jiàn)的錯(cuò)誤來(lái)源,可以通過(guò) RFC 來(lái)消除錯(cuò)誤。然而,它仍然是被支持的,這意味著你可以向任何導(dǎo)航守衛(wèi)傳遞第三個(gè)參數(shù)。在這種情況下,確保 next 在任何給定的導(dǎo)航守衛(wèi)中都被嚴(yán)格調(diào)用一次。它可以出現(xiàn)多于一次,但是只能在所有的邏輯路徑都不重疊的情況下,否則鉤子永遠(yuǎn)都不會(huì)被解析或報(bào)錯(cuò)。這里有一個(gè)在用戶未能驗(yàn)證身份時(shí)重定向到/login的錯(cuò)誤用例:

// BAD
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  // 如果用戶未能驗(yàn)證身份,則 `next` 會(huì)被調(diào)用兩次
  next()
})

下面是正確的版本:

// GOOD
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  else next()
})

全局解析守衛(wèi)

你可以用 router.beforeResolve 注冊(cè)一個(gè)全局守衛(wèi)。這和 router.beforeEach 類似,因?yàn)樗?每次導(dǎo)航時(shí)都會(huì)觸發(fā),但是確保在導(dǎo)航被確認(rèn)之前,同時(shí)在所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后,解析守衛(wèi)就被正確調(diào)用。這里有一個(gè)例子,確保用戶可以訪問(wèn)自定義 meta屬性 requiresCamera 的路由:

路由元信息

有時(shí),你可能希望將任意信息附加到路由上,如過(guò)渡名稱、誰(shuí)可以訪問(wèn)路由等。這些事情可以通過(guò)接收屬性對(duì)象的meta屬性來(lái)實(shí)現(xiàn),并且它可以在路由地址和導(dǎo)航守衛(wèi)上都被訪問(wèn)到。定義路由的時(shí)候你可以這樣配置 meta 字段:

const routes = [
  {
    path: '/posts',
    component: PostsLayout,
    children: [
      {
        path: 'new',
        component: PostsNew,
        // 只有經(jīng)過(guò)身份驗(yàn)證的用戶才能創(chuàng)建帖子
        meta: { requiresAuth: true }
      },
      {
        path: ':id',
        component: PostsDetail
        // 任何人都可以閱讀文章
        meta: { requiresAuth: false }
      }
    ]
  }
]

那么如何訪問(wèn)這個(gè) meta 字段呢?

首先,我們稱呼 routes 配置中的每個(gè)路由對(duì)象為 路由記錄。路由記錄可以是嵌套的,因此,當(dāng)一個(gè)路由匹配成功后,它可能匹配多個(gè)路由記錄。

例如,根據(jù)上面的路由配置,/posts/new 這個(gè) URL 將會(huì)匹配父路由記錄 (path: '/posts') 以及子路由記錄 (path: 'new')。

一個(gè)路由匹配到的所有路由記錄會(huì)暴露為 $route 對(duì)象(還有在導(dǎo)航守衛(wèi)中的路由對(duì)象)的$route.matched 數(shù)組。我們需要遍歷這個(gè)數(shù)組來(lái)檢查路由記錄中的 meta 字段,但是 Vue Router 還為你提供了一個(gè) $route.meta 方法,它是一個(gè)非遞歸合并所有 meta 字段的(從父字段到子字段)的方法。這意味著你可以簡(jiǎn)單地寫

router.beforeEach((to, from) => {
  // 而不是去檢查每條路由記錄
  // to.matched.some(record => record.meta.requiresAuth)
  if (to.meta.requiresAuth && !auth.isLoggedIn()) {
    // 此路由需要授權(quán),請(qǐng)檢查是否已登錄
    // 如果沒(méi)有,則重定向到登錄頁(yè)面
    return {
      path: '/login',
      // 保存我們所在的位置,以便以后再來(lái)
      query: { redirect: to.fullPath },
    }
  }
})

TypeScript

可以通過(guò)擴(kuò)展 RouteMeta 接口來(lái)輸入 meta 字段:

// typings.d.ts or router.ts
import 'vue-router'
declare module 'vue-router' {
  interface RouteMeta {
    // 是可選的
    isAdmin?: boolean
    // 每個(gè)路由都必須聲明
    requiresAuth: boolean
  }
}

router.beforeResolve

router.beforeResolve(async to => {
  if (to.meta.requiresCamera) {
    try {
      await askForCameraPermission()
    } catch (error) {
      if (error instanceof NotAllowedError) {
        // ... 處理錯(cuò)誤,然后取消導(dǎo)航
        return false
      } else {
        // 意料之外的錯(cuò)誤,取消導(dǎo)航并把錯(cuò)誤傳給全局處理器
        throw error
      }
    }
  }
})

router.beforeResolve 是獲取數(shù)據(jù)或執(zhí)行任何其他操作(如果用戶無(wú)法進(jìn)入頁(yè)面時(shí)你希望避免執(zhí)行的操作)的理想位置。

全局后置鉤子

你也可以注冊(cè)全局后置鉤子,然而和守衛(wèi)不同的是,這些鉤子不會(huì)接受 next 函數(shù)也不會(huì)改變導(dǎo)航本身:

router.afterEach((to, from) => {
  sendToAnalytics(to.fullPath)
})

它們對(duì)于分析、更改頁(yè)面標(biāo)題、聲明頁(yè)面等輔助功能以及許多其他事情都很有用。

它們也反映了 navigation failures 作為第三個(gè)參數(shù):

js

router.afterEach((to, from, failure) => {
  if (!failure) sendToAnalytics(to.fullPath)
})

了解更多關(guān)于 navigation failures 的信息在它的指南中。

路由獨(dú)享的守衛(wèi)

你可以直接在路由配置上定義 beforeEnter 守衛(wèi):

const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter: (to, from) => {
      // reject the navigation
      return false
    },
  },
]

beforeEnter 守衛(wèi) 只在進(jìn)入路由時(shí)觸發(fā),不會(huì)在 params、queryhash 改變時(shí)觸發(fā)。例如,從 /users/2 進(jìn)入到 /users/3 或者從 /users/2#info 進(jìn)入到 /users/2#projects。它們只有在 從一個(gè)不同的 路由導(dǎo)航時(shí),才會(huì)被觸發(fā)。

你也可以將一個(gè)函數(shù)數(shù)組傳遞給 beforeEnter,這在為不同的路由重用守衛(wèi)時(shí)很有用:

function removeQueryParams(to) {
  if (Object.keys(to.query).length)
    return { path: to.path, query: {}, hash: to.hash }
}
function removeHash(to) {
  if (to.hash) return { path: to.path, query: to.query, hash: '' }
}
const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter: [removeQueryParams, removeHash],
  },
  {
    path: '/about',
    component: UserDetails,
    beforeEnter: [removeQueryParams],
  },
]

請(qǐng)注意,你也可以通過(guò)使用``路徑 meta 字段和全局導(dǎo)航守衛(wèi)`來(lái)實(shí)現(xiàn)類似的行為。

組件內(nèi)的守衛(wèi)

最后,你可以在路由組件內(nèi)直接定義路由導(dǎo)航守衛(wèi)(傳遞給路由配置的)

可用的配置 API

你可以為路由組件添加以下配置:

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
const UserDetails = {
  template: `...`,
  beforeRouteEnter(to, from) {
    // 在渲染該組件的對(duì)應(yīng)路由被驗(yàn)證前調(diào)用
    // 不能獲取組件實(shí)例 `this` !
    // 因?yàn)楫?dāng)守衛(wèi)執(zhí)行時(shí),組件實(shí)例還沒(méi)被創(chuàng)建!
  },
  beforeRouteUpdate(to, from) {
    // 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用
    // 舉例來(lái)說(shuō),對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 `/users/:id`,在 `/users/1` 和 `/users/2` 之間跳轉(zhuǎn)的時(shí)候,
    // 由于會(huì)渲染同樣的 `UserDetails` 組件,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用。
    // 因?yàn)樵谶@種情況發(fā)生的時(shí)候,組件已經(jīng)掛載好了,導(dǎo)航守衛(wèi)可以訪問(wèn)組件實(shí)例 `this`
  },
  beforeRouteLeave(to, from) {
    // 在導(dǎo)航離開(kāi)渲染該組件的對(duì)應(yīng)路由時(shí)調(diào)用
    // 與 `beforeRouteUpdate` 一樣,它可以訪問(wèn)組件實(shí)例 `this`
  },
}

beforeRouteEnter 守衛(wèi) 不能 訪問(wèn) this,因?yàn)槭匦l(wèi)在導(dǎo)航確認(rèn)前被調(diào)用,因此即將登場(chǎng)的新組件還沒(méi)被創(chuàng)建。

不過(guò),你可以通過(guò)傳一個(gè)回調(diào)給 next 來(lái)訪問(wèn)組件實(shí)例。在導(dǎo)航被確認(rèn)的時(shí)候執(zhí)行回調(diào),并且把組件實(shí)例作為回調(diào)方法的參數(shù):

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通過(guò) `vm` 訪問(wèn)組件實(shí)例
  })
}

注意 beforeRouteEnter 是支持給 next 傳遞回調(diào)的唯一守衛(wèi)。對(duì)于 beforeRouteUpdatebeforeRouteLeave 來(lái)說(shuō),this 已經(jīng)可用了,所以不支持 傳遞回調(diào),因?yàn)闆](méi)有必要了:

beforeRouteUpdate (to, from) {
  // just use `this`
  this.name = to.params.name
}

這個(gè) 離開(kāi)守衛(wèi) 通常用來(lái)預(yù)防用戶在還未保存修改前突然離開(kāi)。該導(dǎo)航可以通過(guò)返回 false 來(lái)取消。

beforeRouteLeave (to, from) {
  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
  if (!answer) return false
}

使用組合 API

如果你正在使用組合 API 和 setup 函數(shù)來(lái)編寫組件,你可以通過(guò) onBeforeRouteUpdateonBeforeRouteLeave 分別添加 update 和 leave 守衛(wèi)。 請(qǐng)參考組合 API 部分以獲得更多細(xì)節(jié)。

完整的導(dǎo)航解析流程

  • 導(dǎo)航被觸發(fā)。
  • 在失活的組件里調(diào)用 beforeRouteLeave 守衛(wèi)。
  • 調(diào)用全局的 beforeEach 守衛(wèi)。
  • 在重用的組件里調(diào)用 beforeRouteUpdate 守衛(wèi)(2.2+)。
  • 在路由配置里調(diào)用 beforeEnter。
  • 解析異步路由組件。
  • 在被激活的組件里調(diào)用 beforeRouteEnter。
  • 調(diào)用全局的 beforeResolve 守衛(wèi)(2.5+)。
  • 導(dǎo)航被確認(rèn)。
  • 調(diào)用全局的 afterEach 鉤子。
  • 觸發(fā) DOM 更新。
  • 調(diào)用 beforeRouteEnter 守衛(wèi)中傳給 next 的回調(diào)函數(shù),創(chuàng)建好的組件實(shí)例會(huì)作為回調(diào)函數(shù)的參數(shù)傳入。

到此這篇關(guān)于Vue中的路由導(dǎo)航守衛(wèi)導(dǎo)航解析流程的文章就介紹到這了,更多相關(guān)Vue路由導(dǎo)航守衛(wèi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue項(xiàng)目的甘特圖組件之dhtmlx-gantt使用教程和實(shí)現(xiàn)效果展示(推薦)

    Vue項(xiàng)目的甘特圖組件之dhtmlx-gantt使用教程和實(shí)現(xiàn)效果展示(推薦)

    文章介紹了如何使用dhtmlx-gantt組件來(lái)實(shí)現(xiàn)公司的甘特圖需求,并提供了一個(gè)簡(jiǎn)單的Vue組件示例,文章還分享了一些配置項(xiàng),如格式化表頭日期、設(shè)置甘特圖尺寸、啟用只讀模式、設(shè)置表格列等,感興趣的朋友一起看看吧
    2025-02-02
  • VUE項(xiàng)目中封裝Echart折線圖的方法

    VUE項(xiàng)目中封裝Echart折線圖的方法

    這篇文章主要為大家詳細(xì)介紹了VUE項(xiàng)目中封裝Echart折線圖的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • vue中data改變后讓視圖同步更新的方法

    vue中data改變后讓視圖同步更新的方法

    這篇文章主要給大家介紹了關(guān)于vue中data改變后讓視圖同步更新的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • vue項(xiàng)目中頁(yè)面跳轉(zhuǎn)傳參的方法總結(jié)

    vue項(xiàng)目中頁(yè)面跳轉(zhuǎn)傳參的方法總結(jié)

    在Vue項(xiàng)目中,你可以使用路由(vue-router)來(lái)實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)并傳遞參數(shù),這篇文章主要為大家整理了一些常用的方法,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-11-11
  • vue使用el-upload上傳文件及Feign服務(wù)間傳遞文件的方法

    vue使用el-upload上傳文件及Feign服務(wù)間傳遞文件的方法

    這篇文章主要介紹了vue使用el-upload上傳文件及Feign服務(wù)間傳遞文件的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03
  • vue中對(duì)接Graphql接口的實(shí)現(xiàn)示例

    vue中對(duì)接Graphql接口的實(shí)現(xiàn)示例

    本文主要介紹了vue中對(duì)接Graphql接口的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 如何用VUE和Canvas實(shí)現(xiàn)雷霆戰(zhàn)機(jī)打字類小游戲

    如何用VUE和Canvas實(shí)現(xiàn)雷霆戰(zhàn)機(jī)打字類小游戲

    這篇文章主要介紹了如何用VUE和Canvas實(shí)現(xiàn)雷霆戰(zhàn)機(jī)打字類小游戲,麻雀雖小,五臟俱全,對(duì)游戲感興趣的同學(xué),可以參考下,研究里面的原理和實(shí)現(xiàn)方法
    2021-04-04
  • 詳解vue中router-view組件的生成原理

    詳解vue中router-view組件的生成原理

    在vue的使用過(guò)程中,有一個(gè)組件,幾乎是必用的,那就是router-view,它是所有組件的入口,是單頁(yè)面系統(tǒng)的一把利劍,如果你的系統(tǒng)是火箭,那么router-view無(wú)疑將是這艘火箭的北斗衛(wèi)星,本文將給大家介紹vue中的router-view組件是如何生成的,感興趣的朋友可以參考下
    2024-01-01
  • vue監(jiān)聽(tīng)瀏覽器的后退和刷新事件,阻止默認(rèn)的事件方式

    vue監(jiān)聽(tīng)瀏覽器的后退和刷新事件,阻止默認(rèn)的事件方式

    這篇文章主要介紹了vue監(jiān)聽(tīng)瀏覽器的后退和刷新事件,阻止默認(rèn)的事件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • vue使用ElementUI時(shí)導(dǎo)航欄默認(rèn)展開(kāi)功能的實(shí)現(xiàn)

    vue使用ElementUI時(shí)導(dǎo)航欄默認(rèn)展開(kāi)功能的實(shí)現(xiàn)

    這篇文章主要介紹了vue使用ElementUI時(shí)導(dǎo)航欄默認(rèn)展開(kāi)功能的實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-07-07

最新評(píng)論

曲阜市| 昌宁县| 偃师市| 乌鲁木齐市| 泽库县| 鄂托克旗| 汤阴县| 天峨县| 潼关县| 山西省| 尤溪县| 成武县| 石家庄市| 温宿县| 永寿县| 菏泽市| 交城县| 深州市| 日喀则市| 安多县| 固始县| 荥阳市| 城步| 威远县| 蕲春县| 朝阳县| 都江堰市| 惠安县| 拉萨市| 嘉禾县| 博客| 双桥区| 崇州市| 嫩江县| 志丹县| 内黄县| 昂仁县| 阜宁县| 龙门县| 昌平区| 德清县|