与 React.js 和 Vue.js 集成 — Soft8Soft
Description: 了解如何将 Verge3D 应用集成到 React.js/Vue.js 项目中。

# 与 React.js/Vue.js 集成

将 Verge3D 场景集成到项目中的最简单方法之一是通过 `<iframe>` HTML 元素单独加载。但如果您想直接在应用内使用，则可能会遇到一些困难。然而，很多项目配置都有其特定的问题和特性。本指南不能涵盖全部，只针对流行的 JavaScript 框架 React.js 和 Vue.js 做出介绍。

Verge3D 资产商店中提供了简单的 React 和 Vue.js 演示。如果您想了解如何从头开始创建 React/Vue.js + Verge3D 应用，请遵循以下指南。

Verge3D 提供了一个示例，说明如何制作一个简单的"Hello, world!" React 或 Vue 项目，并将一个标准的 Verge3D 应用集成到其中。相关文件位于 Verge3D 发行版中：Blender 版 - manager/templates/Embeddable，3ds Max 版 - manager/templates/Embeddable-Max，Maya 版 - manager/templates/Embeddable-Maya。

- Verge3D React.js 应用示例
- Verge3D Vue.js 应用示例
- 使用拼图编辑器

#

## Verge3D React.js 应用示例

以下是通过 Create React App 工具创建一个基本的 React.js + Verge3D 应用的简单说明。您可以在 Verge3D 发行版中的 manager/templates/Embeddable/README.md 找到此说明的副本。

1）通过 Create React App 工具创建 React.js 应用：

`npx create-react-app react-app-example`

2）进入 react-app-example 目录并安装 verge3d npm 包：

`cd react-app-example npm i verge3d`

3）将以下文件从 Verge3D 发行版复制到您的应用中：

- 将 Verge3D 的 manager/templates/Embeddable/public 目录内容复制到 react-app-example/public
- 将 Verge3D 的 manager/templates/Embeddable/src 目录内容复制到 react-app-example/src

或使用以下命令：

Linux/macOS/ChromeOS

将 V3D_PATH 和 MY_PATH 分别更改为 Verge3D 发行版和您的 React 应用所在的位置。

`V3D_PATH=/path/to/v3d/distribution MY_PATH=/path/to/my/react/app cp -r $V3D_PATH/manager/templates/Embeddable/public/* $MY_PATH/public/ cp -r $V3D_PATH/manager/templates/Embeddable/src/* $MY_PATH/src/`
Windows (PowerShell)

将 V3D_PATH 和 MY_PATH 分别更改为 Verge3D 发行版和您的 React 应用所在的位置。

`$V3D_PATH = "path\to\v3d\distribution" $MY_PATH = "path\to\my\react\app" Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\public\*" -Destination "$MY_PATH\public" -Recurse Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\src\*" -Destination "$MY_PATH\src" -Recurse`

4）创建一个名为 react-app-example/src/V3DApp.js 的文件，其内容如下：

`import React from 'react'; import { createApp } from './v3dApp/app'; import './v3dApp/app.css'; class V3DApp extends React.Component { #app = null; #PL = null; #uuid = window.crypto.randomUUID(); #containerId = `v3d-container-${this.#uuid}`; #fsButtonId = `fullscreen-button-${this.#uuid}`; #sceneURL = 'v3dApp/app.gltf'; async loadApp() { ({ app: this.#app, PL: this.#PL } = await createApp({ containerId: this.#containerId, fsButtonId: this.#fsButtonId, sceneURL: this.#sceneURL, })); } disposeApp() { this.#app?.dispose(); this.#app = null; // dispose Puzzles' visual logic this.#PL?.dispose(); this.#PL = null; } reloadApp() { this.disposeApp(); this.loadApp(); } componentDidMount() { this.loadApp(); } componentWillUnmount() { this.disposeApp(); } render() { return <div id={this.#containerId}> <div id={this.#fsButtonId} className="fullscreen-button fullscreen-open" title="Toggle fullscreen mode" ></div> </div>; } } export default V3DApp;`

5）将 react-app-example/src/index.js 的内容替换为以下代码：

`import React from 'react'; import ReactDOM from 'react-dom/client'; import V3DApp from './V3DApp'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<V3DApp/>);`

6）通过在 react-app-example 目录中执行以下命令来运行开发服务器：

`npm start`

默认情况下，应用现在应该可以在 http://localhost:3000/ 地址中访问了。

#

## Verge3D Vue.js 应用示例

以下是通过 Vite 创建一个基本的 Vue.js + Verge3D 应用的简单说明。您可以在 Verge3D 发行版中的 manager/templates/Embeddable/README.md 找到此说明的副本。

1）通过 Vite 创建 Vue.js 应用：

`npm create vite@latest vue-app-example -- --template vue`

2）进入 vue-app-example 目录并安装 verge3d npm 包：

`cd vue-app-example npm i verge3d`

3）将以下文件从 Verge3D 发行版复制到您的应用中：

- 将 Verge3D 的 manager/templates/Embeddable/public 目录内容复制到 vue-app-example/public
- 将 Verge3D 的 manager/templates/Embeddable/src 目录内容复制到 vue-app-example/src

或使用以下命令：

Linux/macOS/ChromeOS

将 V3D_PATH 和 MY_PATH 分别更改为 Verge3D 发行版和您的 Vue 应用所在的位置。

`V3D_PATH=/path/to/v3d/distribution MY_PATH=/path/to/my/vue/app cp -r $V3D_PATH/manager/templates/Embeddable/public/* $MY_PATH/public/ cp -r $V3D_PATH/manager/templates/Embeddable/src/* $MY_PATH/src/`
Windows (PowerShell)

将 V3D_PATH 和 MY_PATH 分别更改为 Verge3D 发行版和您的 Vue 应用所在的位置。

`$V3D_PATH = "path\to\v3d\distribution" $MY_PATH = "path\to\my\vue\app" Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\public\*" -Destination "$MY_PATH\public" -Recurse Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\src\*" -Destination "$MY_PATH\src" -Recurse`

4）创建一个文件 vue-app-example/src/components/V3DApp.vue，包含以下代码：

Vue 3 `<template> <div :id="containerId"> <div :id="fsButtonId" class="fullscreen-button fullscreen-open" title="Toggle fullscreen mode" ></div> </div> </template> <script> import { createApp } from '../v3dApp/app'; export default { name: 'V3DApp', created() { this.app = null; this.PL = null, this.uuid = window.crypto.randomUUID(); this.containerId = `v3d-container-${this.uuid}`; this.fsButtonId = `fullscreen-button-${this.uuid}`; this.sceneURL = 'v3dApp/app.gltf'; this.loadApp = async function() { ({ app: this.app, PL: this.PL } = await createApp({ containerId: this.containerId, fsButtonId: this.fsButtonId, sceneURL: this.sceneURL, })); } this.disposeApp = function() { this.app?.dispose(); this.app = null; // dispose Puzzles' visual logic this.PL?.dispose(); this.PL = null; } this.reloadApp = function() { this.disposeApp(); this.loadApp(); } }, mounted() { this.loadApp(); }, beforeUnmount() { this.disposeApp(); }, } </script> <style> @import '../v3dApp/app.css'; </style>` Vue 2 `<template> <div :id="containerId"> <div :id="fsButtonId" class="fullscreen-button fullscreen-open" title="Toggle fullscreen mode" ></div> </div> </template> <script> import { createApp } from '../v3dApp/app'; export default { name: 'V3DApp', created() { this.app = null; this.PL = null, this.uuid = window.crypto.randomUUID(); this.containerId = `v3d-container-${this.uuid}`; this.fsButtonId = `fullscreen-button-${this.uuid}`; this.sceneURL = 'v3dApp/app.gltf'; this.loadApp = async function() { ({ app: this.app, PL: this.PL } = await createApp({ containerId: this.containerId, fsButtonId: this.fsButtonId, sceneURL: this.sceneURL, })); } this.disposeApp = function() { this.app?.dispose(); this.app = null; // dispose Puzzles' visual logic this.PL?.dispose(); this.PL = null; } this.reloadApp = function() { this.disposeApp(); this.loadApp(); } }, mounted() { this.loadApp(); }, beforeDestroy() { this.disposeApp(); }, } </script> <style> @import '../v3dApp/app.css'; </style>`

5）将 vue-app-example/src/App.vue 的内容替换为以下代码：

`<template> <V3DApp></V3DApp> </template> <script> import V3DApp from './components/V3DApp.vue'; export default { name: 'App', components: { V3DApp, }, } </script>`

6）通过在 vue-app-example 目录中执行以下命令来运行开发服务器：

`npm run dev`

默认情况下，应用现在应该可以在 http://localhost:5173/ 地址中访问了。

#

## 使用拼图编辑器

React/Vue 和 拼图编辑器/应用管理器 之间没有直接的整合方式。尽管如此，您仍然可以使用拼图为您的 React/Vue 应用添加行为场景。本节解释了如何做到这一点以及所选方法的局限性。

应用管理器不知道典型的 React/Vue 项目的目录结构是什么样的。然而，经过一些调整后，管理器至少可以识别拼图的可视化逻辑脚本。这意味着您可以从应用管理器网页中启动拼图编辑器。

这里的缺点是，使用拼图只能通过在应用管理器内创建的标准 Verge3D 应用来完成。因此，无法访问 React/Vue 的功能、组件、逻辑等......而且只能以单独的方式添加拼图。不过，一个完整的 React/Vue 应用可以加载、运行并与拼图编辑器中创建的逻辑脚本进行通信。

### 应用管理器设置

假设我们有一个根据本手册中描述的指南创建的 React 或 Vue 应用。为了"连接"应用管理器和 React/Vue 项目，我们需要创建一个专用的"适配器"应用。这是一个自定义应用模板，默认情况下不在应用管理器中，但可以在应用管理器设置中添加。让我们按照创建模板教程进行操作，但在命名新模板时将 Embeddable/adapter 放入名称字段。接下来，点击 Apply Changes 按钮，模板将成功添加到应用管理器中：

然后，我们需要使用新添加的模板创建一个新的应用。我们命名它为 my_awesome_app：

最后，我们需要创建指向 React/Vue 项目中资源的符号链接，应用管理器需要这些资源才能启动拼图编辑器。假设 React/Vue 项目位于路径 MY_PATH，而您的 Verge3D applications 文件夹位于路径 V3D_APPS_PATH。

您可以在 应用管理器设置 → General → Applications Folder 中查看 Verge3D 存储应用的位置。

我们将创建一个符号链接，从 V3D_APPS_PATH/my_awesome_app/v3dApp 指向 MY_PATH/public/v3dApp ——后者是 React/Vue 项目中存储 verge3d 相关场景资源的位置。此外，我们还需要为拼图逻辑的 JS 和 XML 文件创建更多符号链接。具体方法如下：

Linux/macOS/ChromeOS

将 V3D_APPS_PATH 和 MY_PATH 分别更改为 Verge3D applications 文件夹和您的 React/Vue 应用所在的位置。此外，将 my_awesome_app 替换为您在应用管理器中创建应用时指定的名称。

`V3D_APPS_PATH=/path/to/v3d/applications MY_PATH=/path/to/my/app ln -s $MY_PATH/public/v3dApp $V3D_APPS_PATH/my_awesome_app/v3dApp ln -s $MY_PATH/src/v3dApp/visual_logic.js $V3D_APPS_PATH/my_awesome_app/visual_logic.js ln -s $MY_PATH/src/v3dApp/visual_logic.xml $V3D_APPS_PATH/my_awesome_app/visual_logic.xml`
Windows (PowerShell)

以下命令需要以管理员权限运行 PowerShell。

将 V3D_APPS_PATH 和 MY_PATH 分别更改为 Verge3D applications 文件夹和您的 React/Vue 应用所在的位置。此外，将 my_awesome_app 替换为您在应用管理器中创建应用时指定的名称。

`$V3D_APPS_PATH = "path\to\v3d\applications" $MY_PATH = "path\to\my\app" cmd /c mklink /D $V3D_APPS_PATH\my_awesome_app\v3dApp (Resolve-Path $MY_PATH\public\v3dApp) cmd /c mklink $V3D_APPS_PATH\my_awesome_app\visual_logic.js (Resolve-Path $MY_PATH\src\v3dApp\visual_logic.js) cmd /c mklink $V3D_APPS_PATH\my_awesome_app\visual_logic.xml (Resolve-Path $MY_PATH\src\v3dApp\visual_logic.xml)`

现在您可以在应用管理器中看到您的项目，并可以使用拼图编辑器了。

### 加载拼图中的资源

诸如 替换纹理、加载场景、加载声音、加载视频、加载数据 等拼图可能需要指定 URL 来加载纹理、媒体和其他类型的文件。

将拼图编辑器与 React/Vue 应用一起使用时，此类拼图中指定的所有文件路径都是相对于应用根路径计算的，该路径通常指向应用的 public 目录。如果拼图编辑器按照本手册中描述的方式与 React/Vue 应用集成，则编辑器只能访问应用的 public/v3dApp 目录。

因此，举例说明：如果我们想通过拼图加载一个声音文件，比如 sound.mp3，应该放在 public/v3dApp 目录（或其子目录）中。之后就可以在 加载声音 拼图的 URL 字段中使用 v3dApp/mySound.mp3 来加载文件了：