# Vue Bridge（for Vue v3）

`@module-federation/bridge-vue3` 提供了用于 Vue v3 应用的 `bridge` 工具函数，其提供的 `createBridgeComponent` 可用于导出应用级别模块，`createRemoteComponent` 用于加载应用级别模块。[Demo](https://github.com/module-federation/core/tree/main/apps/router-demo)

### 安装

import { PackageManagerTabs } from '@theme';

<PackageManagerTabs
  command={{
    npm: 'npm install @module-federation/bridge-vue3@latest',
    yarn: 'yarn add @module-federation/bridge-vue3',
    pnpm: 'pnpm add @module-federation/bridge-vue3@latest',
  }}
/>

### 示例

> Remote

```tsx
// ./src/export-app.ts
import App from './App.vue';
import router from './router';
import { createBridgeComponent } from '@module-federation/bridge-vue3';

export default createBridgeComponent({
  rootComponent: App,
  appOptions: () => ({
    router,
  }),
});
```

```ts
// rsbuild.config.ts
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';

export default defineConfig({
  plugins: [
    pluginModuleFederation({
      name: 'remote1',
      exposes: {
        './export-app': './src/export-app.ts',
      },
      shared: ['vue', 'vue-router'],
    }),
  ],
});
```

> Host

```ts
//rsbuild.config.ts
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';

export default defineConfig({
  plugins: [
    pluginModuleFederation({
      name: 'host',
      remotes: {
        remote1: 'remote1@http://localhost:2001/mf-manifest.json',
      },
    }),
  ],
});
```

```tsx
// ./src/router.ts
import * as bridge from '@module-federation/bridge-vue3';

const Remote1 = bridge.createRemoteComponent({
  loader: () => loadRemote('remote1/export-app'),
});

const router = createRouter({
  history: createWebHistory(),
  routes: [
    // 在这里定义你的路由
    { path: '/', component: Home },
    { path: '/remote1/:pathMatch(.*)*', component: Remote1 },
    // 其他路由
  ],
});
export default router;
```

### 方法

#### createRemoteComponent

```tsx
function createRemoteComponent<T, E extends keyof T>(
  options?: {
    // 加载远程应用的函数，例如：loadRemote('remote1/export-app')、import('remote1/export-app')
    loader: () => Promise<T>,
    // 默认为 default，用于指定模块的 export
    export?: E;
  }
): (props: {
    basename?: string;
    memoryRoute?: { entryPath: string };
}) => DefineComponent;
```

* `options`
  * `loader`
    * type: `() => Promise<Module>`
    * 作用: 用于加载远程模块的函数，例如：`loadRemote('remote1/export-app')`、`import('remote1/export-app')`

```tsx
const Remote1App = createRemoteComponent({ loader: () => loadRemote('remote1/export-app') });
const Remote2App = createRemoteComponent({ loader: () => import('remote2/export-app') });
```

  * `export`
    * type: `string`
    * 作用: 可以指定模块的 export
```tsx
// remote
export const provider = createBridgeComponent({
  rootComponent: App
});

// host
const Remote1App = createRemoteComponent({
  loader: () => loadRemote('remote1/export-app'),
});

```

* ReturnType
  * type: `VueComponent`
  * 作用: 用于渲染远程模块组件

```tsx
import * as bridge from '@module-federation/bridge-vue3';

const remote1 = bridge.createRemoteComponent({
  loader: () => loadRemote('remote1/export-app'),
});

const router = createRouter({
  history: createWebHistory(),
  routes: [
    // 在这里定义你的路由
    { path: '/', component: Home },
    { path: '/remote1/:pathMatch(.*)*', component: Remote1 },
    // 其他路由
  ],
});
export default router;
```

#### createBridgeComponent

```tsx
function createBridgeComponent<T>(bridgeInfo: {
  rootComponent: VueComponent;
  appOptions?: ()=> ({
    router: Router
  })
}): () => {
  render(info: {
    name?: string;
    basename?: string;
    memoryRoute?: {
      entryPath: string;
    };
    dom?: HTMLElement;
}): void;
  destroy(info: { dom: HTMLElement}): void;
}
```

* `bridgeInfo`
  * type: `{ rootComponent: VueComponent; appOptions?: ()=> ({ router: Router }) }`
  * 作用: 用于传递根组件
* ReturnType
  * type: `() => { render: (info: RenderFnParams) => void; destroy: (info: { dom: HTMLElement}) => void; }`

```tsx
// ./src/export-app.ts
import { createBridgeComponent } from '@module-federation/bridge-vue3';
import App from './App.vue';
import router from './router';

export default createBridgeComponent({
  rootComponent: App,
  appOptions: () => ({
    router,
  }),
});
```
