inula/packages/inula-router
超级无敌数码暴龙战士 af32cb79f9 feat: 解耦reconciler 2024-10-15 21:56:37 +08:00
..
src feat:类型系统开发 2024-10-14 18:16:29 +08:00
README.md first commit 2023-09-21 09:56:36 +08:00
babel.config.js first commit 2023-09-21 09:56:36 +08:00
build-types.js first commit 2023-09-21 09:56:36 +08:00
build.js first commit 2023-09-21 09:56:36 +08:00
jest.config.js chore: 格式化代码,inula-core ut更换路径 2024-01-11 20:19:01 +08:00
package.json feat: 解耦reconciler 2024-10-15 21:56:37 +08:00
tsconfig.build.json first commit 2023-09-21 09:56:36 +08:00
tsconfig.cbuild.json first commit 2023-09-21 09:56:36 +08:00
tsconfig.json inula-router monorepo改造 2023-09-26 10:14:55 +08:00

README.md

InulaJS-router 路由组件

Inula-router 组件式API

BrowserRouter

功能介绍 使用BrowserRouter组件包裹整个应用它提供一个history对象来管理浏览器的历史记录BrowserRouter使用HTML5的history API来实现路由。

接口定义

type BrowserRouterProps = {
  basename: string;
  getUserConfirmation: (message: string, callBack: (isJump: boolean) => void) => void;
  children?: InualNode;
  forceRefresh: boolean;
};
  • basename:一个字符串,用于指定路由的根路径。如/app,这样所有的网页都会以/app开头,比如/app/home/app/user等。
  • getUserConfirmation一个函数作用是自定义用户在导航到新的历史记录条目时的确认提示。它接受两个参数message 和 callback。message 是一个字符串表示要显示给用户的提示信息。callback 是一个函数,它接受一个布尔值作为参数,表示用户是否确认导航。默认使用函数callBack(window.confirm(message))
  • forceRefresh:是否再路由跳转后强制页面刷新。

说明: BrowserRouter支持在history.pushhistory.replace方法中传递statestate 是一个任意对象它可以存储一些数据并通过浏览器APIhistory.stateuseLocation访问该对象。

示例

import { BrowserRouter, Link, Route, Switch } from 'inula-router';

function App() {
  return (
    <BrowserRouter>
      <Link to='/'>Home</Link>
      <Link to='/about'>About</Link>
      <Switch>
        <Route path='/' component={() => <h2>Home page</h2>} />
        <Route path='/about' component={() => <h2>About Page</h2>} />
      </Switch>
    </BrowserRouter>
  );
}

HashRouter

功能介绍 使用HashRouter组件包裹整个应用它提供一个history对象来管理浏览器的历史记录HashRouter使用URL的hash值来实现路由会在URL中显示#符号。

接口定义

type HashRouterProps = {
  basename: string;
  getUserConfirmation: (message: string, callBack: (isJump: boolean) => void) => void;
  children?: InualNode;
  hashType: urlHashType;
};
  • basename:一个字符串,用于指定路由的根路径。如/app,这样所有的网页都会以/app开头,比如/app/home/app/user等。
  • getUserConfirmation一个函数作用是自定义用户在导航到新的历史记录条目时的确认提示。它接受两个参数message 和 callback。message 是一个字符串表示要显示给用户的提示信息。callback 是一个函数,它接受一个布尔值作为参数,表示用户是否确认导航。默认使用函数callBack(window.confirm(message))
  • hashTypewindow.location.hash 使用的编码类型。可用值为“slash“和”noslash”默认为“slash”。
    • slash:创建如#/api/web的hash值。
    • noslash:创建如#api/web的hash值。

说明: HashRouter使用URL的hash来表示路由不使用history API因此不支持在history.pushhistory.replace中传递state。

示例

import { HashRouter, Link, Route, Switch } from 'inula-router';

function App() {
  return (
    <HashRouter>
      <Link to='/'>Home</Link>
      <Link to='/about'>About</Link>
      <Switch>
        <Route path='/' component={() => <h2>Home page</h2>} />
        <Route path='/about' component={() => <h2>About Page</h2>} />
      </Switch>
    </HashRouter>
  );
}

Switch

功能介绍

Switch 用于包裹多个 Route 或 Redirect ,并根据当前的 URL 匹配第一个合适的组件进行渲染。

接口定义

type SwitchProps = {
  location?: Location;
  children?: Inula.InualNode;
};
  • location:指定匹配子元素时的位置(默认为浏览器当前的URL)。

说明: 所有的Route组件和Redirect组件都应该被Switch组件包裹Switch会遍历所有的子元素第一个匹配成功的Route组件会被渲染其他的会被忽略。

示例

import { BrowserRouter, Link, Route, Switch } from 'inula-router';

// 定义一些页面组件
const Home = () => <h1>Home Page</h1>;
const About = () => <h1>About Page</h1>;
const Contact = () => <h1>Contact Page</h1>;
const NotFound = () => <h1>404 Not Found</h1>;

// 定义一个 App 组件,使用 BrowserRouter 和 Switch 来创建路由
const App = () => {
  return (
    <BrowserRouter>
      <div>
        <Link to='/'>Home</Link>
        <Link to='/about'>About</Link>
        <Link to='/contact'>Contact</Link>
        {/* 使用 Switch 来渲染匹配到的第一个子路由 */}
        <Switch>
          {/* 使用 exact 属性来确保只有当 URL 完全匹配时才渲染组件 */}
          <Route exact path='/' component={Home} />
          <Route path='/about' component={About} />
          <Route path='/contact' component={Contact} />
          {/* 使用 * 来匹配上述以外的 URL渲染 NotFound 组件 */}
          <Route path='*' component={NotFound} />
        </Switch>
      </div>
    </BrowserRouter>
  );
};

Route

功能介绍

Route 是一个定义了路径和组件的映射关系的组件其基本功能是当路径与当前URL匹配时呈现对应组件。

接口定义

type RouteProps<P extends Record<string, any> = {}, Path extends string = string> = {
  location?: Location;
  component?: Inula.ComponentType<RouteComponentProps<P>> | Inula.ComponentType<any> | undefined;
  children?: ((props: RouteChildrenProps<P>) => Inula.InulaNode) | Inual.InulaNode;
  render?: (props: RouteComponentProps<P>) => Inula.InulaNode;
  path?: Path | Path[];
  exact?: boolean;
  sensitive?: boolean;
  strict?: boolean;
};
  • location:指定匹配子元素时的位置(默认为浏览器当前的URL)。
  • rendercomponentchildren 是渲染组件的三种方式,这三种方式互斥,只会执行其中一个,优先级是children > component > render
  • path定义该组件对应的URL。
  • exact仅当path与浏览器URL完全匹配时才匹配到该路由。
  • sensitive:在路由匹配时是否忽略大小写。
  • strict路由匹配时是否忽略URL尾部的“/”。

说明: 当使用component传递组件渲染UI时router将会用createElement来将给定的组件创建一个新的element会执行组件对应的生命周期函数renderchildren这两种方式不会。

示例

import { BrowserRouter, Link, Route, Switch } from 'inula-router';

const Home = () => <h1>Home Page</h1>;
const About = () => <h1>About Page</h1>;
const Contact = () => <h1>Contact Page</h1>;

const App = () => {
  return (
    <BrowserRouter>
        <Link to='/'>Home</Link>
        <Link to='/about'>About</Link>
        <Link to='/contact'>Contact</Link>
        <Switch>
            {/* 使用 Route 渲染匹配到路径的对应组件 */}
            {/* 使用 exact 属性来确保只有当 URL 完全匹配时才渲染组件 */}
            <Route exact path='/' component={Home} />
            {/* 使用 render 属性来直接渲染一个内联函数返回的组件 */}
            <Route path='/about' render={() => <About />} />
            {/* 使用 children 属性来渲染一个无论是否匹配都会显示的组件 */}
            <Route path='/contact' children={<Contact />} />
        </Switch>
    </BrowserRouter>
  );
};

功能介绍

Link是一个可以生成超链接的组件可以在不刷新页面的情况下跳转到其他路由。

接口定义

type LinkProps = {
  component?: Inula.ComponentType<any>;
  to: Partial<Location> | string | ((location: Location) => string | Partial<Location>);
  replace?: boolean;
  tag?: string;
} & Inula.AnchorHTMLAttributes<HTMLAnchorElement>;
  • to:将一条记录加入到历史栈中来导航到一个新的 URL可以为字符串、Location对象或函数。
  • replace:单击链接将替换而不是加入一个新的历史记录。
  • component:自定义导航组件。
  • tag生成Link使用的HTML标签默认为<a>

示例

import { HashRouter, Link, Route, Switch } from 'inula-router';

function App() {
  return (
    <HashRouter>
      {/* 使用 Link 跳转到对应的路径Link组件只能在Router下使用 */}
      <Link to='/'>Home</Link>
      <Link to='/about'>About</Link>
      <Switch>
        <Route path='/' component={() => <h2>Home page</h2>} />
        <Route path='/about' component={() => <h2>About Page</h2>} />
      </Switch>
    </HashRouter>
  );
}

功能介绍

与Link组件相同可以在不刷新页面的情况下跳转到其他路由。当呈现的组件与当前URL匹配时NavLink会为元素添加对应的样式。

接口定义

type NavLinkProps = {
  to: Partial<Location> | string | ((location: Location) => string | Partial<Location>);
  isActive?: (match: Matched | null, location: Location) => boolean;
} & LinkProps;
  • isActive:指定一个函数,以确定该链接是否处于激活状态,当处于激活状态<NavLink>标签的aria-current属性为page

示例

import { HashRouter, Link, Route, Switch } from 'inula-router';

function App() {
  return (
    <HashRouter>
      {/* 使用 NavLink 跳转到对应的路径NavLink组件只能在Router下使用 */}
      <NavLink to='/' isActive={true}>Home</NavLink>
      <NavLink to='/about'>About</NavLink>
      <Switch>
        <Route path='/' component={() => <h2>Home page</h2>} />
        <Route path='/about' component={() => <h2>About Page</h2>} />
      </Switch>
    </HashRouter>
  );
}

Redirect

功能介绍

Redirect是一个可以执行重定向操作的组件它可以在路由匹配时跳转到另一个路由。

接口定义

type RedirectProps = {
  to: string | Partial<Location>;
  push?: boolean;
  path?: string;
  from?: string;
  exact?: boolean;
  strict?: boolean;
};
  • to:重定向跳转到的位置。
  • push:重定向是否替换而不是加入一个新的历史记录。
  • pathfrom用来指定重定向的目标路径当URL为path或from的地址时触发重定向。
  • exact仅当path与浏览器URL完全匹配时才匹配到该路由。
  • strict路由匹配时是否忽略URL尾部的“/”。

说明: pathfrom两个属性都可以用来指定重定向的目标路径,若两者同时设置,path的优先级高于from

示例

import { HashRouter, Link, Route, Switch, Redirect } from 'inula-router';

function App() {
  return (
    <HashRouter>
      {/* 使用 Link 跳转到对应的路径Link组件只能在Router下使用 */}
      <Link to='/'>Home</Link>
      <Link to='/about'>About</Link>
      <Switch>
        <Route path='/' component={() => <h2>Home page</h2>} />
        <Route path='/about' component={() => <h2>About Page</h2>} />

        {/* 当URL匹配不到时使用Redirect组件跳转到Home页面 */}
        <Redirect path='*' to='/'/>
      </Switch>
    </HashRouter>
  );
}

Prompt

功能介绍

Prompt组件用于在用户离开页面时弹出提示确认用户是否执行跳转行为提示的回调函数返回布尔值如果为true则离开页面如果为false则停留在该页。

接口定义

type PromptProps = {
  message?: string | ((location: Partial<Location>, action: Action) => string | boolean);
  when?: boolean | ((location: Partial<Location>) => boolean);
};

enum Action {
  pop = 'POP',
  push = 'PUSH',
  replace = 'REPLACE',
}

type Location = {
  pathname: string;
  search: string;
  hash: string;
  state?: object;
};
  • message:当用户尝试离开时提示用户的消息。将通过用户尝试导航到的下一个位置时。返回一个字符串以向用户显示提示,或返回 true 以允许用户跳转。
  • when:指定在对应条件下渲染Prompt以阻止用户跳转页面。

示例

在该实例中,当用户在Input中输入字符后再跳转到其他页面时,Prompt组件会阻止路由跳转并询问用户是否执行跳转。

import { useState } from 'openinula';
import { BrowserRouter, Link, Switch, Route, Prompt } from 'inula-router';

function PromptDemo() {
  return (
    <BrowserRouter>
      <Link to='/'>Form</Link>
      <Link to='/page'>Other Page</Link>

      <Switch>
        <Route path='/' exact children={<InputForm />} />
        <Route path='/page' children={<h3>Other Page</h3>} />
      </Switch>
    </BrowserRouter>
  );
}

function InputForm() {
  let [isBlocking, setIsBlocking] = useState(false);

  return (
    <form
      onSubmit={event => {
        event.preventDefault();
        setIsBlocking(false);
      }}
    >
      <Prompt
        when={isBlocking}
        message={location =>
          `你是否确认前往 ${location.pathname}`
        }
      />

      <input
        onChange={event => {
          setIsBlocking(event.target.value.length > 0);
        }}
      />
    </form>
  );
}

Inula-router 函数式API

useHistory

功能介绍

useHistory是一个函数,调用useHistory返回Inula-router中的history对象。

定义

function useHistory(): History
  • History对象具有的属性
    • length: 历史记录栈的长度。
    • action: 当前导航的动作类型可以是PUSH、REPLACE或POP。
    • location: 当前的位置对象包含pathname、search、hash和state等属性。
  • history具有的方法
    • push(path,state): 用于向历史记录栈中添加一个新的位置,并导航到该位置。
    • replace(path,state): 用于替换历史记录栈中的当前位置,并导航到新的位置。
    • go(n): 用于在历史记录栈中向前或向后跳转指定的步数。
    • goBack(): 用于回退到历史记录栈中的上一个位置等价于go(-1)。
    • goForward(): 用于前进到历史记录栈中的下一个位置等价于go(1)。
    • block(): 用于阻止导航,并在导航发生时执行一个回调函数。
    • listen(): 用于注册一个监听器,当历史记录发生变化时执行。

示例

import { useHistory } from 'inula-router';

function HomeButton() {
  let history = useHistory();

  function handleClick() {
    history.push('/home');
  }

  return (
    <button type='button' onClick={handleClick}>
      Go home
    </button>
  );
}

useLocation

功能介绍 useLocation是一个函数,调用useLocation返回一个Location对象包含当前 URL 信息如路径名、查询字符串、哈希。当浏览器的URL发生变化useLocation就会随之变化。

定义

function useLocation(): Location;

// Location对象结构
type Location = {
  pathname: string; // URL路径名
  search: string; // URL查询字符串
  hash: string; // URL哈希值
  state: Object; // 额外状态数据
};

示例

import { useLocation } from 'inula-router';

function App() {
  {/* 使用useLocation获取当前位置 */}
  let location = useLocation();

  useEffect(() => {
    console.log('location change to ', location);
  }, [location]);
}

useParams

功能介绍

useParams是一个函数,调用useParams返回一个包含当前URL下路由参数的对象比如 /user/:id 中的 id 。

定义

function useParams(): Params | {};

type Params = { [K in keyof P]?: P[K] };

示例

import { HashRouter, Switch, Route, useParams } from 'inula-router';

const User = () => {
  // 使用 useParams 获取URL中对应的参数
  const { userid } = useParams();

  return <div>{userid} profile page</div>;
};

function App() {
  return (
    <HashRouter>
      <Switch>
        <Route path="/user/:userid" component={<User/>}/>
      </Switch>
    </HashRouter>
  );
}

useRouteMatch

功能介绍 useRouteMatch返回一个包含当前路由的匹配信息的match对象可以在无需<Route>的情况下访问匹配数据,useRouteMatch对于那些非路由但自身状态与当前路径相关的组件非常有用。

定义

function useRouteMatch<P>(path?: string): Matched<P> | null

// match对象结构
type Matched = {
  score: number[]; // 匹配到该URL的匹配分数
  params: Object; // 从URL中解析出来的与path对应的参数
  path: string; // 匹配使用的URL模板
  url: string; // 匹配到的URL部分
  isExact: boolean; // 是否完全匹配URL
};

示例

  • 不使用useRouteMatch
import { BrowserRouter, Switch, Route } from 'inula-router';

// Header组件只会在匹配`/detail/:id`时出现
const Header = () => {
  return (
    <Route
      path="/detail/:id"
      strict
      sensitive
      render={({ match }) => {
        return match && <div>Header</div>
      }}
    />
  )
}
function App() {
  return (
    <BrowserRouter>
      <Header/>
      <Switch>
        <Route exact path="/" render={()=><div>Home</div>}/>
        <Route exact path="/detail/:id" render={()=><div>Detail</div>}/> 
      </Switch>
    </BrowserRouter>
  );
}
  • 使用useRouteMatch
import { BrowserRouter, Switch, Route } from 'inula-router';

// Header组件只会在匹配`/detail/:id`时出现
const Header = () => {
  // 只有当前路径匹配`/detail/:id`时match不为null
  const match = useRouteMatch('/detail/:id')
  return (
    match && <div>Header</div>
  )
}
function App() {
  return (
    <BrowserRouter>
      <Header/>
      <Switch>
        <Route exact path="/" render={()=><div>Home</div>}/>
        <Route exact path="/detail/:id" render={()=><div>Detail</div>}/> 
      </Switch>
    </BrowserRouter>
  );
}

withRouter

功能介绍

withRouter是一个高阶函数组件可以将inula-router的historylocationmatch三个对象注入到任何自定义组件中的props中。

  • history
    • length: 历史记录栈的长度。
    • action: 当前导航的动作类型可以是PUSH、REPLACE或POP。
    • location: 当前的位置对象包含pathname、search、hash和state等属性。
    • push(path,state): 用于向历史记录栈中添加一个新的位置,并导航到该位置。
    • replace(path,state): 用于替换历史记录栈中的当前位置,并导航到新的位置。
    • go(n): 用于在历史记录栈中向前或向后跳转指定的步数。
    • goBack(): 用于回退到历史记录栈中的上一个位置等价于go(-1)。
    • goForward(): 用于前进到历史记录栈中的下一个位置等价于go(1)。
    • block(): 用于阻止导航,并在导航发生时执行一个回调函数。
    • listen(): 用于注册一个监听器,当历史记录发生变化时执行。
  • location
    • pathname: URL路径名。
    • search: URL查询字符串。
    • hash: URL哈希值。
    • state: 额外状态数据。
  • match
    • score: 匹配到该URL的匹配分数。
    • params: 从URL中解析出来的与path对应的参数.
    • path: 匹配使用的URL模板。
    • url: 匹配到的URL部分。
    • isExact: 是否完全匹配URL。

示例

import { withRouter } from 'inula-router'

class DemoComponent extends Inula.Component<any, any> {
  // 可以在这里使用this.props.history、this.props.location、this.props.match等属性

  toHome = () => {
    this.props.history.push('/home'); // 通过history对象push方法返回首页
  };

  render() {
    return (
      <button onClick={this.toHome}>Back Home</button>
    );
  }
}

export default withRouter(MyComponent) // 使用withRouter包裹组件