目次
params (明示的/暗黙的 (ページを更新すると表示されなくなります)) 差分インターフェイス
動的ルーティング (異なるパラメータ、同じコンポーネントへのアクセス)
ローダー コールバック関数 (ルーティング前にトリガーされる)
/src/components/BeforeEach.jsx
部分配線 (コンポーネント配線と比較して、部分配線を推奨、より優れた論理ブロック)
ブラウザは URL を入力して、ルートの対応するコンポーネントを表示します。
Vue プレースホルダー ルーター ビュー\ルーター リンク
ルーティング:異なる URL アドレスに応じて異なるコンテンツを表示、SPA (シングル ページ アプリケーション) のパス マネージャー
インストール
Vue3 は Vue Router4 とペアになっており、その他の使用法は vue2 から大きく変わりません。
//Vue.use() 方法进行安装和注册VueRouter插件
//自动调用插件对象中的 install 方法
Vue.use(VueRouter);
npm インストール vue-router
npm 私は反応ルーターダム
ブラウザのルーティングパターン
history
このモードはブラウザの History API を使用して URL 内の余分な文字を非表示にし、ほとんどの一般的なブラウザ環境に適しています。- ハッシュ記号を使用しない方がルーティングがより美しくなります
#
。 - ブラウザの進む機能と戻る機能を最大限に活用できます。
- ルートに直接アクセスするときに正しいページが返されるようにするには、サーバー構成のサポートが必要です。
- HTML5の履歴 API はURL の変更を監視するため、ブラウザーの互換性の問題があります
//Vue 2.x 或 3.x Options API
const router = new VueRouter({
mode: 'history',
routes
});
// Vue 3.x Composition API
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
history: createWebHistory(),
routes
})
hash
このパターンは URL のハッシュ値を使用します (#
、ハッシュの変更をリッスンすることでルート ナビゲーションを実装できます)- サーバー構成のサポートは必要ありません (ハッシュはサーバーに送信されません)。
- History API がサポートされていない場合、または古いブラウザとの互換性が必要な場合に適しています。
- ブラウザの「進む」および「戻る」機能を最大限に活用せず、履歴エントリは 1 つだけです。
- window.addEventListenerを通じてブラウザのonhashchange()イベントの変更をリッスンして、対応するルーティング ルールを見つけます。
//Vue 2.x 或 3.x Options API
const router = new VueRouter({
mode: 'hash',
routes
});
// Vue 3.x Composition API
import { createRouter, createWebHashHistory} from 'vue-router';
const router = createRouter({
history: createWebHashHistory(),
routes
})
- ルーティング モードは指定されていません。現在の環境に応じて適切なモードが自動的に選択されます。
const router = new VueRouter({
routes
})
構成( /src/router/index.js
)
ルーティングテーブルの設定フィールド
-
パス: パスを指定します
-
要素(React)/コンポーネント(Vue): 対応するコンポーネント
-
子: ネストされたルート
ヴュー
名前付きルート (名前)
パラメータの自動エンコード/デコード
{
path: '/about/foo/:id',
name: 'foo',
component: Foo
}
{ name: 'foo', params: {id: 123} }
名前付きビュー (兄弟表示)
ルーティングメタ情報(メタ、認可などの追加情報)
meta: { auth: false }
this.$route.meta.auth
import { useLocation, matchRoutes, Navigate } from 'react-router-dom'
import { routes } from '../../router';
export default function BeforeEach(props) {
const location = useLocation();
const matchs = matchRoutes(routes, location)
const meta = matchs[matchs.length-1].route.meta
if(meta.auth){
return <Navigate to="/login" />
}
else{
return (
<div>{ props.children }</div>
)
}
}
パラメータを渡す
URLパラメータ
http://example.com/page?param1=value1¶m2=value2#section1
? | 実際の URL とパラメータを分離する |
& | URLで指定されたパラメータ間の区切り文字 |
= | 左側がパラメータ名、右側がパラメータ値です |
# | アンカー (アンカー) は、文書内の特定の位置または要素を識別するために使用されます。 クライアント側でのみ使用され、ブラウザによって処理され、サーバーには送信されません。 ブラウザに . |
location属性値
窓
現在のページを表す window のグローバル オブジェクト http://www.example.com/path/index.html
window.location.href: URL を取得/設定します
window.location.orgin: プロトコル、ホスト名、およびポート番号セクション
//https://www.example.com:8080/page.html
// :// :
//https%3A%2F%2Fwww.example.com%3A8080。
encodeURIComponent(window.location.origin)
//encodeURIComponent用于将字符串中的特殊字符(空格、&、+、= 、?)转换为编码形式,确保URL中不包含任何无效字符
//查询参数时 或者 动态参数时 需要encodeURIComponent
const url = 'https://example.com/api?param=' + encodeURIComponent(queryParam);
window.location.href =`https://www.example.com/path/to/resource.html/domain=${location.host}&req=${encodeURIComponent(location.pathname)}&protocol=https${location.hash}`
window.location.protocol: プロトコル http
window.location.host: ホスト + ポート (ホスト:8080)/IP アドレス (127.123.32.1 一意)/ドメイン名 (www.example.com ニーモニック)
window.location.hostname: ホスト host
window.location.port: ポート 8080
window.location.pathname: リソースパス path/index.html、リソースindex.html
ウィンドウの場所のハッシュ:
window.location.search: 検索
var searchParams = new URLSearchParams(window.location.search);
console.log(searchParams.get('name')); // 输出 "John"
useLocation()
「react-router-dom」からインポート { useLocation }
-
ハッシュ: ハッシュ値
-
キー: 一意の識別子
-
パス名: パス
-
search: クエリ値 (文字列をオブジェクトに解析する必要があります。)
-
状態: 暗黙的なデータ
クエリ (明示的) は補助情報を伝達します
パス: '/user/'、
$route.query
import { useSearchParams } from 'react-router-dom'
const [searchParams, setSearchParams] = useSearchParams()
console.log( searchParams.get('age') );
const handleClick = () => {
setSearchParams({ age: 22 })
}
params (明示的/暗黙的 (ページを更新すると表示されなくなります)) 差分インターフェイス
$route.params
明示的: パス: '/user/:id'、
暗黙的: パス: '/user/'、
明示的な /workbenchConfiguration/upload をクエリします?wpReleId= 59
params 明示的な /workbenchConfiguration/upload / 59
動的ルーティング (異なる parmas、同じコンポーネントへのアクセス)
import { Outlet, Link } from 'react-router-dom'
export default function About() {
return (
<div>
<Link to="/about/foo/123">foo 123</Link> | <Link to="/about/foo/456">foo 456</Link>
</div>
)
}
//...
{
path: 'foo/:id',
element: <Foo />
}
//...
import { useParams } from 'react-router-dom'
export default function Foo() {
const params = useParams()
return (
<div>Foo, { params.id }</div>
)
}
//Vue与React唯一不同
this.$route.params.id
プログラムによるルーティング (非リンク モード)
//vue
this.$router.push({
path: `/about/foo/${id}`
})
//react
import {useNavigate } from 'react-router-dom'
const navigate = useNavigate()
const handleClick= () => {
navigate('/about/foo/123')
}
デフォルト ルート (一致なし)、リダイレクト ルート (リダイレクト/ナビゲート)、404 (*/errorElement)
ヴュー
import VueRouter from 'vue-router'
import Home from '@/views/Home.vue'
const About={template:'<div>About</div>'}
const routes: Array<any> = [
{
path: '/',
redirect: '/workbenchConfiguration'
},
{
path: '/404',
meta: { title: '404' },
component: () => import('@/views/404.vue')
},
{ path: '*', redirect: '/404' }
]
const router = new VueRouter({
routes
})
反応する
import { createBrowserRouter, createHashRouter } from 'react-router-dom'
//路由表
export const routes = [
// 默认路由
{
index: true,
//重定向
element: <Navigate to="/about/foo/123" />,
//自带errorElement
errorElement: <div>404</div>,
},
//*局部404
{
path: '*',
element: <div>404</div>
}
];
//路由对象
const router = createBrowserRouter(routes);
export default router;
ローダー コールバック関数 (ルーティング前にトリガーされる)
デフォルトでは同期し、リダイレクトと連携して権限のインターセプトを行います。
{
path: 'bar',
element: <Bar />,
//async,await异步,Promise用于表示一个异步操作的最终完成(或失败)及其结果值。
loader: async() => {
let ret = await new Promise((resolve)=>{
setTimeout(()=>{
resolve({errcode: 0})
}, 2000)
})
return ret;
}
}
useLoaderData() は、ローダー関数によって返されたデータを取得します。
import { useLoaderData } from 'react-router-dom'
export default function Bar() {
const data = useLoaderData()
console.log(data)
return (
<div>Bar</div>
)
loader
関数内でリダイレクトに <Navigate> コンポーネントを使用する方法はありません。
{
path: 'bar',
element: <Bar />,
loader: async() => {
let ret = await new Promise((resolve)=>{
setTimeout(()=>{
resolve({errcode: Math.random() > 0.5 ? 0 : -1})
}, 2000)
})
if(ret.errcode === 0){
return ret;
}
else{
return redirect('/login')
}
}
}
正面玄関
//index.js
import { RouterProvider } from 'react-router-dom'
import router from './router';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<RouterProvider router={router}></RouterProvider>
</React.StrictMode>
);
ガード(権限、ルート遮断)
ナビゲーション解析プロセス
-
ナビゲーションがトリガーされます。
-
非アクティブ化されたコンポーネントでガードを呼び出します
beforeRouteLeave
。 -
グローバル
beforeEach
ガードを呼んでください。 -
再利用可能なコンポーネントのコール
beforeRouteUpdate
ガード (2.2+) 。 -
ルーティング設定で呼び出されます
beforeEnter
-
非同期ルーティング コンポーネントを解析します。
-
アクティブ化されたコンポーネントで呼び出されます
beforeRouteEnter
。 -
グローバル
beforeResolve
ガード (2.5 以降) を呼び出します。 -
ナビゲーション確認済みです。
-
グローバル
afterEach
フックを呼び出します。 -
DOM の更新をトリガーします。
-
beforeRouteEnter
ガードに渡されたコールバック関数を呼び出すnext
と、作成されたコンポーネント インスタンスがコールバック関数のパラメータとして渡されます。
グローバル
ヴュー
//to
router.beforeEach((to, from, next)=>{
if(to.meta.auth){
next('/');
}
else{
next();
}
})
//vue+ts
router.beforeEach((to: any, from: any, next: any) => {
const metaTitlt = (to.meta && to.meta.title) || ''
document.title = `${metaTitlt} - 默认模版`
//是否从根路径而来,当前路由的来源路径和即将进入的路由的路径是否相同
if (from.path !== '/' && from.matched[0].path !== to.matched[0].path) {
message.destroy()
}
next()
})
反応する
/src/components/BeforeEach.jsx
import React from 'react'
import { Navigate } from 'react-router-dom'
import { routes } from '../../router';
export default function BeforeEach(props) {
if(true){
return <Navigate to="/login" />
}
else{
return (
<div>{ props.children }</div>
)
}
}
export const routes = [
{
path: '/',
element: <BeforeEach><App /></BeforeEach>//包裹根组件APP
}
]
部分配線 (コンポーネント配線と比較して、部分配線を推奨、より優れた論理ブロック)
const routes = [
{
name: 'bar',
component: Bar,
beforeEnter(to, from, next){
if(to.meta.auth){
next('/');
}
else{
next();
}
}
}
];
コンポーネントのルーティング
<script>
export default {
name: 'FooView',
beforeRouteEnter(to, from, next){
if(to.meta.auth){
next('/');
}
else{
next();
}
}
}
</script>
ブラウザは URL を入力して、ルートの対応するコンポーネントを表示します。
プレースホルダーがない場合、デフォルトはページ全体です
Vue プレースホルダー ルーター ビュー\ルーター リンク
<template>
<div>
<router-link to="/">首页</router-link> |
<router-link to="/about">关于</router-link>
<router-view></router-view>
</div>
</template>
React プレースホルダー アウトレット\リンク
import React from "react";
import { Outlet, Link } from 'react-router-dom'
function App() {
return (
<div className="App">
<h2>hello react</h2>
<Link to="/">首页</Link> | <Link to="/about">关于</Link>
<Outlet />
</div>
);
}
export default App;
スタイル付き宣言型ルーティング NavLink
ナビゲーションの繰り返し (プロトタイプのプッシュおよび置換メソッドを変更)
プッシュ: 新しいルートをブラウザの履歴に追加します。これにより、ユーザーはブラウザの戻るボタンを使用して前のルートに戻ることができます。
this.$router.push('/about')
replace: ブラウザの履歴に新しいエントリを残しませんが、現在の履歴エントリを直接置き換えます。
this.$router.replace('/contact')
たとえば、ログイン
replace
ページを処理するときに、ユーザーが [戻る] ボタンからログイン ページに戻れないようにするために、現在のルートがログイン成功後のメソッドに置き換えられることがあります。
VueRouter のプロトタイプ メソッドを変更しpush
、replace
ナビゲーションの繰り返しエラーをキャプチャして処理するように、
コンソールにエラーをスローする代わりに、不要なエラー メッセージや潜在的な問題を回避します。
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => {
if (err.name !== 'NavigationDuplicated') {
throw err;
}
});
};
const originalReplace = VueRouter.prototype.replace;
VueRouter.prototype.replace = function replace(location) {
return originalReplace.call(this, location).catch(err => {
if (err.name !== 'NavigationDuplicated') {
throw err;
}
});
};
const router = new VueRouter({
// 路由配置...
});
export default router;