UE如何与Vue技术结合使用

UE如何与Vue技术结合使用?

先说结论:Vue 的 Composition API + Pinia + Element Plus,配上 UE 的 WebNativeBrowser 插件,是一套能直接交付数字孪生、数据大屏、工业控制台的完整技术方案。 你不再需要用 UMG 手写表格和表单,前端同学在 Chrome 里独立开发 Vue 页面,UE 同学在引擎里做三维场景,双方通过消息通道联动。改页面不需要重新编译引擎,开发效率提升 3 倍以上。

WebNativeBrowser 是面向 UE 5.1–5.8 的高性能企业级跨平台 Web UI 插件,基于 Chromium 内核,支持 Windows / Linux x86_64 / Linux ARM64 全平台。
在这里插入图片描述

为什么 Vue 特别适合和 UE 配合

1. 响应式数据天然适配 UE 的实时场景

Vue 的响应式系统让 UE 推过来的实时数据直接映射到页面 DOM。设备状态变了,页面自动更新,不需要手动操作 DOM:

// Pinia store:接收 UE 实时数据
const useDeviceStore = defineStore('device', () => {
  const devices = ref([]);

  // UE → Vue:收到场景选中事件
  WebNative.on("Scene.Device.Select", (messageBody) => {
    const { deviceId } = JSON.parse(messageBody);
    const device = findDeviceById(deviceId);
    if (device) device.highlighted = true; // 自动响应到 DOM
  });

  return { devices };
});

2. Composition API 让消息监听生命周期可控

onMounted 注册监听,onUnmounted 自动解除——组件卸载时不会产生内存泄漏,这是 UE 嵌入式场景最重要的工程保障。

3. 生态组件库直接可用

Element Plus 的表格、树形控件、表单、日期选择器都是开箱即用的——这些在 UMG 里每一个都需要从头造轮子。

第一步:搭建 Vue 项目

在 UE 项目中创建一个 Vue 前端工程。推荐 Vite + Vue 3:

npm create vite@latest ue-dashboard -- --template vue
cd ue-dashboard
npm install vue-router@4 pinia element-plus @element-plus/icons-vue

目录结构:

ue-dashboard/
├── public/
│   └── favicon.ico
├── src/
│   ├── components/
│   │   ├── DeviceTree.vue      # 设备树
│   │   ├── DeviceDetail.vue    # 设备详情面板
│   │   ├── AlertPanel.vue      # 告警列表
│   │   └── DataChart.vue       # 数据图表
│   ├── stores/
│   │   ├── device.js           # 设备状态管理 (Pinia)
│   │   └── scene.js            # 场景交互状态
│   ├── composables/
│   │   └── useWebNative.js     # WebNative 通信封装
│   ├── App.vue
│   └── main.js
└── package.json

第二步:封装 WebNative 通信层

WebNative.send / .on / .off 封装成一个 Composable,方便所有组件复用:

// src/composables/useWebNative.js
import { onMounted, onUnmounted } from 'vue';

export function useWebNative() {
  const listeners = new Map();

  function send(functionName, messageBody = {}) {
    WebNative.send(functionName, messageBody);
  }

  function on(functionName, callback) {
    WebNative.on(functionName, callback);
    // 记录监听,用于组件卸载时批量清理
    if (!listeners.has(functionName)) {
      listeners.set(functionName, []);
    }
    listeners.get(functionName).push(callback);
  }

  function off(functionName, callback) {
    WebNative.off(functionName, callback);
  }

  // 组件卸载时自动清理所有监听
  function cleanup() {
    listeners.forEach((callbacks, functionName) => {
      callbacks.forEach(cb => WebNative.off(functionName, cb));
    });
    listeners.clear();
  }

  onUnmounted(cleanup);

  return { send, on, off };
}

第三步:定义消息契约

前端和 UE 之间定义好业务事件名称,这是双方协作的接口文档:

// Vue → UE
Device.Tree.Click { deviceId }
Filter.Change { filter: { type, status, keyword } }
Layout.Save { panels: [...] }

// UE → Vue
Scene.Device.Select { deviceId, position, rotation }
Scene.Device.Status.Change { deviceId, status, temperature }
Scene.Camera.Move { position, direction }
Camera.Focus.Result { deviceId, duration }

第四步:构建设备管理面板

一个完整的设备树 + 详情面板示例:

<!-- DeviceTree.vue -->
<template>
  <div class="device-tree">
    <el-tree
      :data="treeData"
      node-key="id"
      @node-click="onDeviceClick"
      :props="{ label: 'name', children: 'children' }"
    />
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { useWebNative } from '../composables/useWebNative';

const { send, on } = useWebNative();
const treeData = ref([]);

function onDeviceClick(device) {
  // 点击设备 → 通知 UE 场景聚焦
  send("Device.Tree.Click", {
    deviceId: device.id,
    deviceName: device.name
  });
}

onMounted(() => {
  // 加载设备树
  fetch('/api/devices').then(r => r.json()).then(data => {
    treeData.value = data;
  });

  // 监听 UE 场景中的设备选中事件
  on("Scene.Device.Select", (messageBody) => {
    const { deviceId } = JSON.parse(messageBody);
    // 高亮树中的设备节点
    highlightDeviceInTree(deviceId);
  });

  // 监听设备状态变更
  on("Scene.Device.Status.Change", (messageBody) => {
    const { deviceId, status } = JSON.parse(messageBody);
    updateDeviceStatus(deviceId, status);
  });
});
</script>

第五步:UE 端接收消息

// UE 蓝图 / C++
void ADeviceManager::OnMessageReceived(const FString& FunctionName, const FString& MessageBody)
{
    TSharedPtr<FJsonObject> Json;
    FJsonSerializer::Deserialize(TJsonReaderFactory<>::Create(MessageBody), Json);

    if (FunctionName == "Device.Tree.Click")
    {
        FString DeviceId = Json->GetStringField("deviceId");
        FocusCameraToDevice(DeviceId);
        HighlightDevice(DeviceId);
    }
    else if (FunctionName == "Filter.Change")
    {
        const TSharedPtr<FJsonObject> Filter = Json->GetObjectField("filter");
        ApplySceneFilter(Filter);
    }
}

Vue 特有最佳实践

1. 使用 Pinia 管理 UE 推过来的数据

// stores/device.js
export const useDeviceStore = defineStore('device', () => {
  const devices = ref([]);
  const selectedId = ref(null);
  const filterParams = ref({});

  // 从 UE 推过来的设备选中
  function handleSceneSelect(deviceId) {
    selectedId.value = deviceId;
  }

  // 从 UE 推过来的状态变更
  function handleStatusChange(deviceId, status) {
    const device = devices.value.find(d => d.id === deviceId);
    if (device) {
      device.status = status;
      device.lastUpdateTime = Date.now();
    }
  }

  return { devices, selectedId, filterParams, handleSceneSelect, handleStatusChange };
});

2. 用 watchEffect 实现筛选联动

// 用户修改筛选条件 → 自动通知 UE 场景更新
watchEffect(() => {
  const { type, status, keyword } = useDeviceStore().filterParams;
  if (Object.keys(filterParams).length > 0) {
    WebNative.send("Filter.Change", { filter: { type, status, keyword } });
  }
});

3. 高频消息合并更新

UE 镜头移动时可能每秒推几十条消息,直接用 ref 更新会导致页面卡顿。用 requestAnimationFrame 合并:

let framePending = false;
const pendingUpdates = [];

on("Scene.Camera.Move", (messageBody) => {
  const data = JSON.parse(messageBody);
  pendingUpdates.push(data);

  if (!framePending) {
    framePending = true;
    requestAnimationFrame(() => {
      // 一帧内合并所有更新
      batchApplyCameraUpdate(pendingUpdates);
      pendingUpdates.length = 0;
      framePending = false;
    });
  }
});

开发工作流

前端独立开发调试:Vue 页面在 Chrome 里开发和调试,UE 工程师不需要等页面。页面完成后,直接放进 UE 加载,双向消息通道接通即可。

热更新体验:Vite 的 HMR 在 UE 嵌入环境下同样工作——改样式、改逻辑、甚至加组件,页面即时刷新,不需要重启引擎。

发布打包npm run build → 把 dist/ 目录放到 UE 项目的 Content/webnative/ 下 → UE 通过 file:// 协议加载 index.html

WebNativeBrowser 为 Vue 项目提供了什么

Vue 页面跑在 WebNativeBrowser 里,不仅仅是"能显示",而是具备完整的生产级能力:

  • GPU 直通渲染:Vue 页面 + ECharts 图表 + Element Plus 组件,全部通过 GPU 共享内存直接进入 UE 渲染管线,最高 120 FPS,零 CPU 拷贝
  • 双向通信:Pinia store 和 UE 蓝图通过消息通道实时联动,单条延迟 < 1ms
  • 透明交互:Vue 面板的间隙区域可以让鼠标穿透到 UE 场景,实现面板与三维场景无缝共存
  • 跨平台:同一套 Vue 代码,在 Windows / Linux x86_64 / Linux ARM64 上完全一致
  • 中文输入:Vue 受控组件在 Linux 下完整支持拼音输入、候选词、中英切换

如果这篇对你有帮助,欢迎点赞收藏。WebNativeBrowser 支持 UE 5.1–5.8,覆盖 Windows / Linux x86_64 / Linux ARM64,已完成国产 GPU 专项适配。

GitHub:https://github.com/starTechnology1994/uewebbrowser

商务合作 / 授权咨询:startechnology1994@163.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值