# CorsLink 跨模块跳转

- 来源：[E10 UI 组件库](https://www.e-cology.com.cn/ui/cors-link/freepass)
- 平台：PC
- 维护者：揭志胜、李戈峰
- Issue：http://gitlab.ecology10.cn/FRONTEND/weapp-ui/-/issues?state=all&search=[CorsLink]

## 代码演示

### 基础用法

直接引入组件进行使用 CorsLink

```jsx
import { Button, CorsLink, utils } from "@weapp/ui";
import { Component } from "react";
import { RouteComponentProps, withRouter } from "react-router-dom";

const { formatParentPath } = utils;

// @ts-ignore
@withRouter
export default class Demo extends Component<RouteComponentProps> {
  option = {
    app: '@weapp/demo',
    compName: 'ViewDialog',
    onClose: () => console.log('dialog close')
  }
  render() {
    const parentPath: string = formatParentPath(this.props);
    return (
      <div>
        <CorsLink
         
          to={`${parentPath}/view-dialog/1/test`}
          path={`${parentPath}/view-dialog/:id/:name`}
          option={this.option}
        >
          <Button>打开弹框</Button>
        </CorsLink>
      </div>
    );
  }
}
```

### CorsLink

跨模块数据通信

```jsx
import { Button, CorsLink, utils } from "@weapp/ui";
import { Component } from "react";
import { withRouter } from "react-router-dom";

const { formatParentPath } = utils;

// @ts-ignore
@withRouter
export default class Demo extends Component {
  state = {
    data: {
      username: 'jason'
    },
  }
  handleChange = (data: any) => {
    console.log('change data:', data);
    this.setState({ data });
  }
  render() {
    const parentPath: string = formatParentPath(this.props as any);
    const { data } = this.state;
    return (
      <div>
        <p>
          <span>当前数据：{data.username}</span>
        </p>
        <CorsLink
         
          to={`${parentPath}/communicate-dialog`}
          option={{
            app: '@weapp/demo',
            compName: 'CommunicateDialog',
            data,
            onDataChange: this.handleChange
          }}
        >
          <Button>打开弹框</Button>
        </CorsLink>
      </div>
    );
  }
}
```

### CorsComponent

跨模块调用组件

```jsx
import { Button, CorsComponent, CorsDialogProps } from "@weapp/ui";
import { Component } from "react";

export default class Demo extends Component {
  state = {
    visible: false,
    visible2: false,
  }

  handleClose = () => {
    this.setState({ visible: false });
  }

  handleClose2 = () => {
    this.setState({ visible2: false });
  }

  handleClick = () => {
    this.setState({ visible: true });
  }

  handleClick2 = () => {
    this.setState({ visible2: true });
  }

  customRender =(module: any) => {
    const { visible2 } = this.state;
    const ViewDialog = module.ViewDialog;
    return (
      <>
        <Button onClick={this.handleClick2}>自定义按钮</Button>
        <ViewDialog visible={visible2} onClose={this.handleClose2} />
      </>
    );
  }

  render() {
    const { visible } = this.state;
    return (
      <div>
        <h4>引用组件</h4>
        <Button onClick={this.handleClick}>打开弹框</Button>
        <CorsComponent<CorsDialogProps>
         
          app='@weapp/demo'
          compName='ViewDialog'
          visible={visible}
          onClose={this.handleClose}
        />
        <h4>自定义渲染</h4>
        <CorsComponent
         
          app='@weapp/demo'
          onReady={console.log}
          customRender={this.customRender}
        />
      </div>
    );
  }
}
```

### CorsRouter

跨模块平级打开路由

```jsx
import { Component } from "react";
import { RouteComponentProps, withRouter, Link } from "react-router-dom";
import { CorsRouter, Button, utils } from "@weapp/ui";
import { moduleRouter } from '@weapp/utils';

const { formatParentPath } = utils;

// @ts-ignore
@withRouter
export default class Demo extends Component<RouteComponentProps> {
  openDialog = () => {
    // @ts-ignore
    moduleRouter.open(this.props, 'demo', '123');
  }
  openSideDialog = () => {
    // @ts-ignore
    moduleRouter.open(this.props, 'demo', '123', 'side');
  }
  render() {
    const parentPath: string = formatParentPath(this.props);
    return (
      <div>
        <p>跨模块同级打开使用CorsRouter组件</p>
        <p>
          <h5>打开弹框</h5>
          <Button onClick={this.openDialog}>打开弹框</Button>
          <h5>打开侧边框</h5>
          <Button onClick={this.openSideDialog}>打开侧边弹框</Button>
          <CorsRouter rootPath={parentPath} />
        </p>
      </div>
    );
  }
}
```

## API

### 参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认 |
| --- | --- | --- | --- | --- |
| option | 打开的弹框的配置 | CorsDialogProps | 是 | - |
| to | 跳转的路由地址 | string | 是 | - |
| path | 跳转的路由 | string | 否 | - |
#### option 参数说明（CorsDialogProps）：

| 参数 | 说明 | 类型 | 是否必填 | 默认 |
| --- | --- | --- | --- | --- |
| app | 模块名称（本地开发注意点以 app 名称为 weapp/demo 为例。 本地需要执行命令 yarn add @weapp/demo && yarn upwedep ） | string | 是 | - |
| compName | 异步加载的组件名称，如果需要加载子组件，可以通过'.'连缀，例如 'ebcoms.Form'，也可以是更多级的 'ebcoms.Form.FormItem' | string | 是 | - |
| data | 需要传给模块的数据 | AnyObj | 否 | - |
| loading | 异步加载时的 loading 效果 | ReactNode | 否 | noop |
| onDataChange | 模块数据修改时触发回调 | (...otherParams: any[]) => any | 否 | - |
| onClose | 弹框关闭时触发回调 | () => void | 否 | - |
#### CorsComponent API 说明

| 参数 | 说明 | 类型 | 是否必填 | 默认 |
| --- | --- | --- | --- | --- |
| app | 模块名称（本地开发注意点以 app 名称为 weapp/demo 为例。 本地需要执行命令 yarn add @weapp/demo && yarn upwedep ） | string | 是 | - |
| compName | 异步加载的组件名称，如果需要加载子组件，可以通过'.'连缀，例如 'ebcoms.Form'，也可以是更多级的 'ebcoms.Form.FormItem' | string | 是 | - |
| customRender | 自定义渲染内容 | (module: any, com?: any) => void | 否 | - |
| loading | 异步加载时的 loading 效果 | ReactNode | 否 | noop |
| unmount | 组件卸载时触发回调 | () => void | 否 | - |
| onReady | 组件异步加载成功时触发回调 | (module: any) => void | 否 | - |
| onError | 异步加载错误时触发回调 | (err: Event) => void | 否 | - |
> 注：CorsComponent 和 CorsComponentProps 支持传入第三方模块组件的 props 类型，默认为 any 类型

#### CorsSwitch API 说明 (组件还在试验阶段，谨慎使用！)

| 参数 | 说明 | 类型 | 是否必填 | 默认 |
| --- | --- | --- | --- | --- |
| paths | 需要加载路由 | CorsSwitchPathType[] | 是 | - |
| rootPath | 加载的 route 的根路由 | string | 是 | - |
#### CorsSwitchPathType 属性说明 (组件还在试验阶段，谨慎使用！)

| 参数 | 说明 | 类型 | 是否必填 | 默认 |
| --- | --- | --- | --- | --- |
| app | 模块名称 | string | 是 | - |
| compName | 异步加载的组件名称 | string | 是 | - |
| routePath | 路由 | string | 是 | - |
#### CorsRouter API 说明 (组件还在试验阶段，谨慎使用！)

| 参数 | 说明 | 类型 | 是否必填 | 默认 |
| --- | --- | --- | --- | --- |
| rootPath | 加载的 route 的根路由 | string | 是 | - |
### CorsLink 与 CorsComponent 对比

#### 相同点

> CorsLink,CorsComponent 可以通过 props 将数据传递给对应跨模块组件,作为模块组件的 props 从而达到控制组件的作用。

#### 区别

CorsLink(路由切换)

> 需要通过渲染 CorsLink 的 children 内容去渲染 Link 标签,由对应模块组件内进行处理,点击后触发对应模块内容渲染。 底层调用 CorsComponent 进行跨组件调用

CorsComponent

> 可以由 CorsComponent 直接控制,可以不产生路由切换。可以将 props 传递给对应的模块组件,模块组件通过参数传递进行交互。自定义渲染,可以对跨默认导入的组件进行自定义渲染。
