文章目录
- BrowserRouter、HashRouter、MemoryRouter区别
- BrowserRouter
- HashRouter
- MemoryRouter
- 框架路由
- Vue router
- React router
- react-router 和 react-router-dom 区别
- Vue-Router和React-Router区别
BrowserRouter、HashRouter、MemoryRouter区别
- BrowserRouter、HashRouter 和 MemoryRouter 是三种不同的路由类型,每种都有自己的特点和使用场景:
BrowserRouter
BrowserRouter 使用 HTML5 历史 API (pushState, replaceState 和 popstate 事件) 来保持 UI 和 URL 的同步。它为您的应用程序创建了一个干净的 URL,没有额外的字符,看起来就像常规的 URL。
- BrowserRouter 利用h5api实现路由切换: H5提供的pushState(),replaceState(),window.addEventListener(‘popstate’)我们可以通过location.pathname来显示对应的视图
- 例子:
http://example.com/about
它通常用于支持服务器端渲染和动态服务器配置的应用,因为服务器需要对每个可能的 URL 响应并返回正确的资源。 - 特点:
提供干净、美观的 URL。
需要服务器配置以响应路由请求。
不支持旧版浏览器。
history 漂亮像正常路径一样,但是需要服务端支持 history-fallback pushState / window.addEventListener(‘popstate’)
HashRouter
HashRouter 使用 URL 的哈希部分(即 window.location.hash)来保持 UI 和 URL 的同步。因此,URL 中会包含一个额外的 # 字符,这个哈希模式主要用于不支持 HTML5 历史 API 的旧版浏览器或者在静态文件服务器上部署的应用。
-
HashRouter 利用hash实现路由切换: 主要是监听它的hashchange事件的变化,window.addEventListener(‘hashchange’),然后拿到对应的location.hash更新对应的视图
-
例子:
http://example.com/#/about
由于浏览器不会将哈希后的 URL 发送到服务器,因此这允许前端路由而无需任何服务器端配置。 -
特点:
不需要服务器端配置,适合静态文件服务器。
URL 包含 #,不如 BrowserRouter 的 URL 美观。
兼容旧版浏览器。
hash 特点丑 兼容性好 location.hash = ‘xx’ / window.addEventListener(‘hashchange’)
MemoryRouter
MemoryRouter 将 URL 的历史记录保存在内存中,而不是在地址栏。这意味着路由状态是在页面刷新时丢失的,因此这个路由器类型通常用于不需要地址栏更新或浏览器历史记录的应用程序,如测试和非浏览器环境(React Native)或者在某些嵌入式应用(如电视设备的应用)。
-
特点:
不会在地址栏中更新 URL。
适合测试、服务器渲染应用、React Native 或嵌入式应用。
UI 状态完全由内存维护,不依赖浏览器的历史记录。
在选择正确的路由器时,你应该考虑应用的部署环境、浏览器兼容性需求以及是否需要服务器支持。对于大多数应用来说,BrowserRouter 是最常用的,因为它提供了最直观的 URL 体验,但 HashRouter 可以在静态文件服务器上提供更简单的部署选项,而 MemoryRouter 在特定的环境中非常有用。
框架路由
Vue router
Vue Router 提供了三种路由模式:hash、history 和 abstract,以适应不同的使用场景和需求。每种模式都有其特点和适用环境,以下是对每种模式的简要说明:
- hash 模式
特点:默认模式。使用 URL 的哈希(#)来模拟一个完整的 URL,从而实现页面之间的跳转而不重新加载页面。哈希值的改变不会导致浏览器向服务器发出请求,页面不会重新加载。
适用场景:适用于不支持 HTML5 History API 的旧浏览器,或者在不需要服务器特别配置的情况下使用。
URL 示例:http://example.com/#/page - history 模式
特点:依赖 HTML5 的 History API 来实现,去掉了 URL 中的哈希(#)。这种模式下,URL 看起来更像传统的网址,更加美观。
适用场景:适用于现代浏览器。需要服务器进行相应配置,确保用户在直接访问或刷新非根 URL 时,服务器能返回对应的页面。
URL 示例:http://example.com/page
服务器配置:例如,对于 Apache 服务器,需要在 .htaccess 文件中添加重写规则;对于 Node.js,需要配置服务器端的路由返回入口页面。 - abstract 模式
特点:不依赖浏览器的地址栏。这种模式支持所有 JavaScript 运行环境,包括 Node.js 服务器端。在没有浏览器 API 支持的环境下,Vue Router 会自动强制进入这个模式。
适用场景:主要用于非浏览器环境,或者在浏览器环境中进行单元测试时使用。
URL 示例:由于是抽象模式,不涉及地址栏变化,因此没有 URL 示例。
在选择路由模式时,应考虑你的应用运行环境、浏览器兼容性以及服务器配置能力。大多数现代 web 应用倾向于使用 history 模式,因为它能提供干净、美观的 URL,但这需要服务器正确配置以支持单页应用的路由。
React router
-
<HashRouter>(Hash路由组件)
<HashRouter> 使用 URL 的哈希部分(即 window.location.hash)来保持 UI 和 URL 的同步。它适用于不支持 HTML5 历史 API 的旧版浏览器,或者在不想进行服务器端配置以响应所有可能路由请求的静态文件服务器上。使用<HashRouter>时,你的 URL 会看起来像这样:
http://example.com/#/your/route -
<BrowserRouter>
<BrowserRouter> 是使用 HTML5 历史 API(即 pushState、replaceState 和 popstate 事件)来保持用户界面(UI)和 URL 同步的路由组件。这种路由方式为你的应用程序提供了干净、美观的 URL,不会在 URL 中看到像在 hash 模式中那样的哈希(#)。
当使用 <BrowserRouter> 时,它会为你的 web 应用创建一个类似传统多页面应用中的导航体验,因为 URL 的变化会反映在浏览器的地址栏中,并且用户可以使用前进和后退按钮来导航你的单页面应用(SPA)。
需要注意的是,当你使用 <BrowserRouter> 时,如果用户直接访问一个非根 URL 或者刷新页面,服务器需要配置响应所有可能的 URL,并返回入口 HTML 文件。这通常涉及到后端服务器配置,比如重写规则,确保对于 SPA 中的所有路由请求,服务器都返回同一个 index.html 文件。在开发过程中,像 Create React App 这样的脚手架工具会为你处理这些配置。 -
<MemoryRouter>(内存路由组件)
<MemoryRouter> 将路由的历史记录保存在内存中,不会在浏览器的地址栏中进行任何更改。这个组件通常用于服务器渲染的应用程序、测试环境或者非浏览器环境(例如React Native),在这些场景中你不需要修改浏览器的 URL。 -
<NativeRouter>(Native的路由组件)
<NativeRouter> 是专门为 React Native 应用设计的路由组件。它使用了 React Native 的导航功能而不是浏览器的历史记录,因此适用于移动应用开发。如果你在开发一个 React Native 应用,你会用到 <NativeRouter> 来处理导航。 -
<StaticRouter>(地址不改变的静态路由组件)
<StaticRouter> 用于服务器渲染场景,它不监控浏览器地址栏的改变,也不修改浏览器的历史记录。服务器渲染的应用程序不需要与用户的浏览器历史交互,因此 <StaticRouter> 会在服务器端生成静态页面内容。使用 <StaticRouter> 时,你通常会提供一个 location 属性,用来表明在服务器端渲染时应用应该呈现的路由位置。
- 在使用这些组件时,请确保选择适合你的应用场景的路由组件。例如,如果你正在构建一个浏览器中运行的单页应用,则通常会选择使用 <BrowserRouter> 或 <HashRouter>。如果你在做服务器端渲染或静态站点生成,可能就会使用 <StaticRouter>。而对于 React Native 应用,则是 <NativeRouter>。而 <MemoryRouter> 可能用于测试或其他不需要地址栏同步的特殊情况。
react-router 和 react-router-dom 区别
react-router 和 react-router-dom 是用于构建路由系统的 JavaScript 库,它们是 React Router 的一部分,专门用于在 React 应用程序中添加导航功能。下面是这两个包的基本概述和它们之间的区别:
-
react-router
react-router 是 React Router 的核心库,包含与路由相关的核心组件和功能,如 Router、Route、Switch、Redirect 等。
它提供了基础的路由功能,可以在任何 React 环境中使用,包括 React Native。
react-router 不依赖于 DOM,因此可以在服务器端渲染(SSR)和非浏览器环境中使用。 -
react-router-dom
react-router-dom 是专门为在 web 浏览器中运行的 React 应用程序设计的。它建立在 react-router 之上,添加了与 DOM 绑定的额外功能和组件,如 BrowserRouter、HashRouter、Link 和 NavLink。
这个包封装了用于网页应用的更高级的路由功能,并且依赖于 DOM 作为其环境。
通常在构建一个浏览器中运行的 React Web 应用程序时,你会使用 react-router-dom 而不是直接使用 react-router。
如果你正在使用 React 来构建一个 web 应用程序,你会安装 react-router-dom,因为它包含了 react-router 的所有功能,并且添加了一些专门用于浏览器环境的组件。实际上,当你安装 react-router-dom 时,react-router 也会作为其依赖项一起被安装。 -
这里是如何在一个 web 应用程序中使用 react-router-dom 的示例:
import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; const Home = () => <div>Home</div>; const About = () => <div>About</div>; const App = () => ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> </ul> </nav> <Route path="/" exact component={Home} /> <Route path="/about" component={About} /> </div> </Router> ); ReactDOM.render(<App />, document.getElementById('root'));
在这个例子中,BrowserRouter 被导入为 Router,并用于包裹整个应用的路由系统。Link 组件用于创建导航链接,而 Route 组件用于渲染与当前 URL 匹配的组件。这个例子展示了一个非常基础的路由设置。
Vue-Router和React-Router区别
-
Vue Router 和 React Router 是两个流行的前端路由库,分别用于 Vue.js 和 React 框架。虽然它们都用于创建单页应用程序(SPA)的路由系统,但它们之间存在一些设计和使用上的区别。以下是一些主要区别:
-
设计哲学和集成
Vue Router 是 Vue.js 的官方路由库,与 Vue.js 的核心深度集成。它与 Vue 的响应式系统紧密配合,确保路由状态的改变能高效地反映在视图上。
React Router 是为 React 设计的一个独立的路由库,它并非 React 官方的一部分,但广泛被 React 社区接受和使用。React Router 以组件为中心,符合 React 的设计理念。 -
路由配置
- Vue Router 允许你使用一个 JavaScript 对象数组来声明式地配置所有路由。这种配置方法使得路由规则和它们的组件非常清晰地映射出来。
const router = new VueRouter({ routes: [ { path: '/', component: Home }, { path: '/about', component: About } ] });
- React Router 则通常在组件内部使用 JSX 来声明路由。这样可以更灵活地与应用程序的其他组件和逻辑集成。
<Router> <Route path="/" exact component={Home} /> <Route path="/about" component={About} /> </Router>
- Vue Router 允许你使用一个 JavaScript 对象数组来声明式地配置所有路由。这种配置方法使得路由规则和它们的组件非常清晰地映射出来。
-
路由匹配
Vue Router 默认进行模糊匹配,但可以通过配置来进行精确匹配。路由匹配到后,可以渲染对应的组件。
React Router 使用的是优先级匹配,最先匹配到的路由会被渲染。在 v4 及以后版本中,React Router 引入了 Switch 组件,它会渲染第一个与当前路径匹配的 或 。 -
导航守卫
- Vue Router 提供了强大的导航守卫功能。你可以在全局、路由配置或组件内部定义守卫,以控制路由的进入和离开。
router.beforeEach((to, from, next) => { // 在路由全局前置守卫中进行检查或修改 ... });
- React Router 没有内置类似的导航守卫概念,但可以通过组件生命周期方法或使用 React Hooks 来模拟类似的行为。
- Vue Router 提供了强大的导航守卫功能。你可以在全局、路由配置或组件内部定义守卫,以控制路由的进入和离开。
-
动态路由和懒加载
Vue Router 支持动态路由匹配,并且可以很容易地与 Vue 的异步组件和 webpack 的代码拆分功能结合使用,实现路由级别的懒加载。
React Router 也支持动态路由,通常结合 React.lazy 和 Suspense 实现懒加载。 -
其他
模式(Mode):Vue Router 支持 hash、history 和 abstract 模式,而 React Router 支持 browser(类似于 Vue 的 history)、hash 和 memory 路由模式。
链接激活状态:Vue Router 提供了<router-link> 组件,用于创建链接并在当前路由匹配时自动应用激活状态,而 React Router 通过 NavLink 组件提供类似的功能。 -
总结
- vue-router是全局配置方式, react-router是全局组件方式
- vue-router仅支持对象形式的配置,react-router支持对象形式和JSX语法的组件形式配置。
- vue-router任何路由组件都会被渲染到<router-view/>位置,react-router子组件作为children被传入父组件,而根组件被渲染到<Router/>位
- vue
//对象形式的配置 let routerConfig = { linkActiveClass: 'active', routes: [ { path: '/person', redirect: '/person/0' }, { path: '/', redirect: '/person' }, { path: '/person/:id', name: 'person', component: Person }] const router = new Router(routerConfig); vueInstance.vueInstanceNew = new Vue({ i18n, router: routerEntry, store: storeEntry, template: '<App/>', render: h => h(app) }).$mount('#app');
- react
//JSX语法的组件形式配置 function AppRouter() { return ( <Router> <ul> <li> <Link to="/">首页</Link> </li> <li><Link to="/list/">列表</Link> </li> </ul> <Route path="/" exact component={Index} /> <Route path="/list/" component={List} /> </Router> ); } 对象形式 export const routerConfig = [ { path: '/', component: loadable( () => import('../pages/Index') ), exact: true, children: [] }, { path: '/search', exact: false, component: loadable( () => import('../pages/SearchAll') ) }] const App = () => { return ( <HashRouter> <Suspense fallback={<Loading />}> <Provider rootStore={rootStore}> <Switch> { routerConfig.map( (route) => { return ( <Route component={route.component} path={route.path} key={route.path} exact={route.exact} > </Route> ); } ) } </Switch> </Provider> </Suspense> </HashRouter> ); };