當前位置:首頁 » 網頁前端 » 前端路由原理
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

前端路由原理

發布時間: 2022-03-08 13:34:19

『壹』 :前端路由是什麼東西

前端路由是不涉及伺服器的,是前端利用hash或者HTML5的history API來實現的,一般用於不同內容的展示和切換。

其實前端路由要做的就是兩點:

  • 在頁面不刷新的情況下實現url的變化

  • 捕捉url的變化,根據url更改頁面內容

『貳』 用迷你無線路由器中繼的時候,前端路由器都需要怎麼設置

可以中繼。這時候你要連接到迷你無線路由上。。

『叄』 什麼是"前端路由"什麼時候適合使用"前端路由""前端路由"有哪些優點和缺點

你的理解有錯誤,所謂的前端路由是為了和後端路由區分開。後端路由也叫做二級路由,三級路由!簡單舉個例子,你在光貓後面插的第一個路由器就叫做前端路由,它主管你連接在這台路由器上的其他所有路由器,也就是二級或者三級路由器,在家用領域這個概念基本不會使用!但在公司或者一些比較大的企業,前端路由器的功能決定你公司的其他電腦的功能,比如帶寬,認證,收費等!~

『肆』 vue實現路由跳轉的原理是什麼,是調用js底層什麼方法

前端路由是直接找到與地址匹配的一個組件或對象並將其渲染出來。改變瀏覽器地址而不向伺服器發出請求有兩種方式:
1. 在地址中加入#以欺騙瀏覽器,地址的改變是由於正在進行頁內導航
2. 使用H5的window.history功能,使用URL的Hash來模擬一個完整的URL。
當打包構建應用時,Javascript 包會變得非常大,影響頁面載入。如果我們能把不同路由對應的組件分割成不同的代碼塊,然後當路由被訪問的時候才載入對應組件,這樣就更加高效了。

目錄結構
先來看看整體的目錄結構

和流程相關的主要需要關注點的就是 components、history 目錄以及 create-matcher.js、create-route-map.js、index.js、install.js。下面就從 basic 應用入口開始來分析 vue-router 的整個流程。
import Vue from 'vue'
import VueRouter from 'vue-router'

// 1. 插件
// 安裝 <router-view> and <router-link> 組件
// 且給當前應用下所有的組件都注入 $router and $route 對象
Vue.use(VueRouter)

// 2. 定義各個路由下使用的組件,簡稱路由組件
const Home = { template: '<div>home</div>' }
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 3. 創建 VueRouter 實例 router
const router = new VueRouter({
mode: 'history',
base: __dirname,
routes: [
{ path: '/', component: Home },
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
})

// 4. 創建 啟動應用
// 一定要確認注入了 router
// 在 <router-view> 中將會渲染路由組件
new Vue({
router,
template: ` <div id="app">
<h1>Basic</h1>
<ul>
<li><router-link to="/">/</router-link></li>
<li><router-link to="/foo">/foo</router-link></li>
<li><router-link to="/bar">/bar</router-link></li>
<router-link tag="li" to="/bar">/bar</router-link>
</ul>
<router-view class="view"></router-view>
</div>
`
}).$mount('#app')04142

作為插件
上邊代碼中關鍵的第 1 步,利用 Vue.js 提供的插件機制 .use(plugin) 來安裝 VueRouter,而這個插件機制則會調用該 plugin 對象的 install 方法(當然如果該 plugin 沒有該方法的話會把 plugin 自身作為函數來調用);下邊來看下 vue-router 這個插件具體的實現部分。
VueRouter 對象是在 src/index.js 中暴露出來的,這個對象有一個靜態的 install 方法:
/* @flow */
// 導入 install 模塊
import { install } from './install'// ...import { inBrowser, supportsHistory } from './util/dom'// ...export default class VueRouter {
// ...}

// 賦值 install
VueRouter.install = install

// 自動使用插件if (inBrowser && window.Vue) {
window.Vue.use(VueRouter)
}123456789101112131415161718

可以看到這是一個 Vue.js 插件的經典寫法,給插件對象增加 install 方法用來安裝插件具體邏輯,同時在最後判斷下如果是在瀏覽器環境且存在 window.Vue 的話就會自動使用插件。
install 在這里是一個單獨的模塊,繼續來看同級下的 src/install.js 的主要邏輯:
// router-view router-link 組件import View from './components/view'import Link from './components/link'// export 一個 Vue 引用export let _Vue// 安裝函數export function install (Vue) {
if (install.installed) return
install.installed = true

// 賦值私有 Vue 引用
_Vue = Vue // 注入 $router $route
Object.defineProperty(Vue.prototype, '$router', {
get () { return this.$root._router }
}) Object.defineProperty(Vue.prototype, '$route', {
get () { return this.$root._route }
}) // beforeCreate mixin
Vue.mixin({
beforeCreate () { // 判斷是否有 router
if (this.$options.router) { // 賦值 _router
this._router = this.$options.router // 初始化 init
this._router.init(this) // 定義響應式的 _route 對象
Vue.util.defineReactive(this, '_route', this._router.history.current)
}
}
}) // 注冊組件
Vue.component('router-view', View)
Vue.component('router-link', Link)// ...}0414243

這里就會有一些疑問了?
· 為啥要 export 一個 Vue 引用?
插件在打包的時候是肯定不希望把 vue 作為一個依賴包打進去的,但是呢又希望使用 Vue 對象本身的一些方法,此時就可以採用上邊類似的做法,在 install 的時候把這個變數賦值 Vue ,這樣就可以在其他地方使用 Vue 的一些方法而不必引入 vue 依賴包(前提是保證 install 後才會使用)。
· 通過給 Vue.prototype 定義 $router、$route 屬性就可以把他們注入到所有組件中嗎?
在 Vue.js 中所有的組件都是被擴展的 Vue 實例,也就意味著所有的組件都可以訪問到這個實例原型上定義的屬性。
beforeCreate mixin 這個在後邊創建 Vue 實例的時候再細說。
實例化 VueRouter
在入口文件中,首先要實例化一個 VueRouter ,然後將其傳入 Vue 實例的 options 中。現在繼續來看在 src/index.js 中暴露出來的 VueRouter 類:
// ...import { createMatcher } from './create-matcher'// ...export default class VueRouter {
// ...
constructor (options: RouterOptions = {}) {
this.app = null
this.options = options
this.beforeHooks = []
this.afterHooks = []
// 創建 match 匹配函數
this.match = createMatcher(options.routes || [])
// 根據 mode 實例化具體的 History
let mode = options.mode || 'hash'
this.fallback = mode === 'history' && !supportsHistory if (this.fallback) {
mode = 'hash'
} if (!inBrowser) {
mode = 'abstract'
}
this.mode = mode switch (mode) {
case 'history':
this.history = new HTML5History(this, options.base) break
case 'hash':
this.history = new HashHistory(this, options.base, this.fallback) break
case 'abstract':
this.history = new AbstractHistory(this) break
default:
assert(false, `invalid mode: ${mode}`)
}
}
// ...}

里邊包含了重要的一步:創建 match 匹配函數。
match 匹配函數
匹配函數是由 src/create-matcher.js 中的 createMatcher 創建的:
/* @flow */

import Regexp from 'path-to-regexp'// ...import { createRouteMap } from './create-route-map'// ...export function createMatcher (routes: Array<RouteConfig>): Matcher {
// 創建路由 map
const { pathMap, nameMap } = createRouteMap(routes)
// 匹配函數 function match (
raw: RawLocation,
currentRoute?: Route,
redirectedFrom?: Location
): Route {
// ...
} function redirect (
record: RouteRecord,
location: Location
): Route {
// ...
} function alias (
record: RouteRecord,
location: Location,
matchAs: string
): Route {
// ...
} function _createRoute (
record: ?RouteRecord,
location: Location,
redirectedFrom?: Location
): Route { if (record && record.redirect) { return redirect(record, redirectedFrom || location)
} if (record && record.matchAs) { return alias(record, location, record.matchAs)
} return createRoute(record, location, redirectedFrom)
}
// 返回 return match
}
// ...04142434445464748495051

具體邏輯後續再具體分析,現在只需要理解為根據傳入的 routes 配置生成對應的路由 map,然後直接返回了 match 匹配函數。
繼續來看 src/create-route-map.js 中的 createRouteMap 函數:
/* @flow */import { assert, warn } from './util/warn'import { cleanPath } from './util/path'// 創建路由 mapexport function createRouteMap (routes: Array<RouteConfig>): {
pathMap: Dictionary<RouteRecord>,
nameMap: Dictionary<RouteRecord>
} { // path 路由 map
const pathMap: Dictionary<RouteRecord> = Object.create(null) // name 路由 map
const nameMap: Dictionary<RouteRecord> = Object.create(null) // 遍歷路由配置對象 增加 路由記錄
routes.forEach(route => {
addRouteRecord(pathMap, nameMap, route)
}) return {
pathMap,
nameMap
}
}// 增加 路由記錄 函數function addRouteRecord (
pathMap: Dictionary<RouteRecord>,
nameMap: Dictionary<RouteRecord>,
route: RouteConfig,
parent?: RouteRecord,
matchAs?: string
) {
// 獲取 path 、name
const { path, name } = route
assert(path != null, `"path" is required in a route configuration.`) // 路由記錄 對象
const record: RouteRecord = {
path: normalizePath(path, parent),
components: route.components || { default: route.component },
instances: {},
name, parent,
matchAs,
redirect: route.redirect,
beforeEnter: route.beforeEnter,
meta: route.meta || {}
} // 嵌套子路由 則遞歸增加 記錄
if (route.children) {// ...
route.children.forEach(child => {
addRouteRecord(pathMap, nameMap, child, record)
})
} // 處理別名 alias 邏輯 增加對應的 記錄
if (route.alias !== undefined) { if (Array.isArray(route.alias)) {
route.alias.forEach(alias => {
addRouteRecord(pathMap, nameMap, { path: alias }, parent, record.path)
})
} else {
addRouteRecord(pathMap, nameMap, { path: route.alias }, parent, record.path)
}
} // 更新 path map
pathMap[record.path] = record // 更新 name map
if (name) { if (!nameMap[name]) {
nameMap[name] = record
} else {
warn(false, `Duplicate named routes definition: { name: "${name}", path: "${record.path}" }`)
}
}
}function normalizePath (path: string, parent?: RouteRecord): string {
path = path.replace(/\/$/, '') if (path[0] === '/') return path if (parent == null) return path return cleanPath(`${parent.path}/${path}`)
}57677787980818283

可以看出主要做的事情就是根據用戶路由配置對象生成普通的根據 path 來對應的路由記錄以及根據 name 來對應的路由記錄的 map,方便後續匹配對應。
實例化 History
這也是很重要的一步,所有的 History 類都是在 src/history/ 目錄下,現在呢不需要關心具體的每種 History 的具體實現上差異,只需要知道他們都是繼承自 src/history/base.js 中的 History 類的:
/* @flow */// ...import { inBrowser } from '../util/dom'import { runQueue } from '../util/async'import { START, isSameRoute } from '../util/route'// 這里從之前分析過的 install.js 中 export _Vueimport { _Vue } from '../install'export class History {// ...
constructor (router: VueRouter, base: ?string) { this.router = router this.base = normalizeBase(base) // start with a route object that stands for "nowhere"
this.current = START this.pending = null
}// ...}// 得到 base 值function normalizeBase (base: ?string): string { if (!base) { if (inBrowser) { // respect <base> tag
const baseEl = document.querySelector('base') base = baseEl ? baseEl.getAttribute('href') : '/'
} else { base = '/'
}
} // make sure there's the starting slash
if (base.charAt(0) !== '/') { base = '/' + base

『伍』 實際開發過程中,是不是前端路由應該謹慎使用

一般情況下一套route搞定,如果項目太大,可以分成多個小項目,而每個小項目又是一個single page,小項目之間用url跳轉,適合那種項目太大多個小組協作的情況!

『陸』 前端為什麼要用路由 不用a標簽

步驟1、連接線路。
由於HyFi智能無線路由器與HyFi智能無線擴展器之間的正常注冊需要使用到智能無線路由器的DHCP服務,因此對於前端有路由器的環境中,建議使用LAN-WAN級聯。
將前端的網線接入HyFi智能無線路由器的WAN口,電腦通過有線連接到HyFi智能無線路由器的LAN口或者無線連接HyFi智能無線路由器的無線信號。

步驟2、設置HyFi智能無線路由器的管理IP地址。
為避免由於和前端路由設備網段沖突導致HyFi智能無線路由器無法正常連接到前段網路,需要修改HyFi智能無線路由器的管理IP地址網段。
電腦登陸HyFi智能無線路由器的管理界面(默認地址為http://192.168.1.1),點擊「網路參數--LAN口設置」,修改IP地址為其他網段(例如192.168.2.1)後保存,設備將會重啟。

步驟3、注冊HyFi產品。
設置完HyFi智能無線路由器後,還需要將HyFi智能無線擴展器進行注冊才可以正常使用HyFi產品。
在設備都通電情況下,兩分鍾內分別按一下HyFi智能無線路由器TL-H18R和HyFi智能無線擴展器TL-H18E上的Config按鈕,待HyFi智能無線擴展器的指示燈由閃爍變為常亮時,即完成設備的注冊。
如果有多個HyFi智能無線擴展器,使用相同方法多次與HyFi智能無線路由器進行注冊即可。

『柒』 前端路由和後端路由有什麼區別

組網級層的區別,主級路由次級路由之間的區別。

『捌』 前端在埠號和前端路由之間加內容

摘要 express既能提供靜態資源, 還能提供數據介面

『玖』 前端路由」有哪些優點和缺點

前端路由的優點和缺點:

  • 優點

  • 用戶體驗好,不需要每次都從伺服器全部獲取,快速展現給用戶

  • 缺點

  • 使用瀏覽器的前進,後退鍵的時候會重新發送請求,沒有合理地利用緩存

  • 單頁面無法記住之前滾動的位置,無法在前進,後退的時候記住滾動的位置