vue と React ルーティング

目次

インストール

ブラウザのルーティングパターン

設定 (/src/router/index.js)

ルーティングテーブルの設定フィールド 

ヴュー

名前付きルート (名前)

名前付きビュー (兄弟表示)

ルーティングメタ情報(メタ、認可などの追加情報)

パラメータを渡す

URLパラメータ

location属性値

useLocation()

クエリ (明示的) は補助情報を伝達します

params (明示的/暗黙的 (ページを更新すると表示されなくなります)) 差分インターフェイス 

動的ルーティング (異なるパラメータ、同じコンポーネントへのアクセス)

プログラムによるルーティング (非リンク モード)

デフォルト ルート (一致なし)、リダイレクト ルート (リダイレクト/ナビゲート)、404 (*/errorElement)

ヴュー

反応する

ローダー コールバック関数 (ルーティング前にトリガーされる)

正面玄関

ガード(権限、ルート遮断)

ナビゲーション解析プロセス

グローバル

ヴュー

反応する

/src/components/BeforeEach.jsx

部分配線 (コンポーネント配線と比較して、部分配線を推奨、より優れた論理ブロック)

コンポーネントのルーティング

ブラウザは URL を入力して、ルートの対応するコンポーネントを表示します。

Vue プレースホルダー ルーター ビュー\ルーター リンク

React プレースホルダー アウトレット\リンク

ナビゲーション複製(修正プロトタイプ方式)


ルーティング:異なる 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で指定されたパラメータ間の区切り文字
= 左側がパラメータ名、右側がパラメータ値です
#

アンカー (アンカー) は、文書内の特定の位置または要素を識別するために使用されます。

クライアント側でのみ使用され、ブラウザによって処理され、サーバーには送信されません。

ブラウザに .id="section1"の付いた要素までスクロールするように指示します。

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>
);

ガード(権限、ルート遮断)

ナビゲーション解析プロセス

  1. ナビゲーションがトリガーされます。

  2. 非アクティブ化されたコンポーネントでガードを呼び出しますbeforeRouteLeave

  3. グローバルbeforeEachガードを呼んでください。

  4. 再利用可能なコンポーネントのコールbeforeRouteUpdateガード (2.2+) 。

  5. ルーティング設定で呼び出されますbeforeEnter

  6. 非同期ルーティング コンポーネントを解析します。

  7. アクティブ化されたコンポーネントで呼び出されますbeforeRouteEnter

  8. グローバルbeforeResolveガード (2.5 以降) を呼び出します。

  9. ナビゲーション確認済みです。

  10. グローバルafterEachフックを呼び出します。

  11. DOM の更新をトリガーします。

  12. 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 のプロトタイプ メソッドを変更しpushreplaceナビゲーションの繰り返しエラーをキャプチャして処理するように、

コンソールにエラーをスローする代わりに不要なエラー メッセージや潜在的な問題を回避します。

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;

おすすめ

転載: blog.csdn.net/qq_28838891/article/details/131691290