关于 fivem-react-nui
面向 FiveM NUI 界面开发的 React 与 Vite 技能,适用于使用 React 18、TypeScript 和 Tailwind CSS 的开发者。它给出 CEF 渲染限制、Lua 通信方式及界面结构方面的约束。
主要功能
- 01提供 React 与 Vite 技术栈规范
- 02说明 NUI 与 Lua 双向通信方式
- 03涵盖界面可见性及输入焦点管理
- 04列出 FiveM CEF 的样式与性能限制
适用场景
- 01搭建 FiveM 的 React NUI 界面
- 02让 NUI 接收 Lua 消息并发送回调
- 03排查 CEF 中的样式或资源缓存问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ proelias7/ fivem-skill --skill fivem-react-nui安装后在 Claude Code 中输入/fivem-react-nui确认已加载。
附带文件ui-guide.md
详细介绍
FiveM NUI — React + Vite
语言规则: 内部推理使用简洁的英语。所有向用户显示的消息和输出都必须使用用户的语言。
技术栈:React 18 + TypeScript + Vite + Tailwind CSS v3.4.17 + Zustand
基本规则
- 在
vite.config.ts中设置base: "./"— 必需,否则资源无法在 FiveM 中加载 - 绝不要将 Vite 的
rollupOptions.output文件名固定为不含[hash]的名称 — FiveM CEF 会缓存 NUI;固定名称(assets/[name].css)会导致部分玩家看到过时的 CSS - 透明 html 上的覆盖层/外壳填充:使用不透明的 hex +
background-image: linear-gradient(#111,#111)— 绝不要在与面板填充相同的圆角元素上使用rgba()/ Tailwindbg-*/70/opacity(某些 iGPU 上会触发 CEF 错误)。屏幕变暗效果应使用不带border-radius的同级图层(::beforeinset-0)。通过display: flex|none切换 — 绝不要在覆盖层容器上使用 jQueryfadeIn/fadeOut - **背景缺失/
border-style: solid渲染缺陷:**尝试在受影响元素上使用顶部/左侧inset和底部/右侧outset;参见ui-guide.md§6 中的方向性边框回退方案。在 FiveM CEF 中进行目视验证;不要全局替换实线边框。 - 所有尺寸都使用
rem— 布局中绝不要使用px(会随玩家分辨率缩放) - Tailwind v4 使用 OKLCH,FiveM CEF 不支持 — 请使用 Tailwind v3.4.17
- 禁止:
backdrop-filter: blur()、filter: blur()、filter: drop-shadow()— 会导致 FPS 下降 - 禁止:framer-motion、GSAP、react-spring — 使用纯 CSS 过渡/关键帧
- 全局设置
overflow: hidden和user-select: none - 独立模块(Notify、Progress、HUD)放在
VisibilityProvider外部 - 主界面(面板、制作界面、对话框)放在
VisibilityProvider内部,并使用SetNuiFocus - 在开发环境中使用
isEnvBrowser()模拟数据 - 通信方式:使用
observe()监听 NUI 消息,使用Post.create()发送回调
架构
// main.tsx
ReactDOM.createRoot(document.getElementById("root")!).render(
<ThemeProvider>
{/* Always visible — do not block game input */}
<NotifyComponent />
<ProgressComponent />
{/* Controlled by VisibilityProvider — requires NuiFocus */}
<HashRouter>
<VisibilityProvider>
<AppContent />
</VisibilityProvider>
</HashRouter>
</ThemeProvider>
);
NUI Hooks
observe — 监听 Lua 消息
observe<NotifyData>("module:notify", (data) => {
addNotify(data);
});
Post — 向 Lua 发送回调
await Post.create("buy", { item: "water", qty: 1 });
Lua 端
-- Open
SendNUIMessage({ action = "setNui", nui = "panel", data = { ... } })
SetNuiFocus(true, true)
-- Close callback
RegisterNUICallback("removeFocus", function(data, cb)
SetNuiFocus(false, false)
cb("ok")
end)
fxmanifest.lua 集成
ui_page "src/ui/build/index.html"
files {
"src/ui/build/index.html",
"src/ui/build/**/*", -- covers index-[hash].js/css
"src/ui/project/public/**/*",
}
推荐依赖
{
"dependencies": {
"react": "^18", "react-dom": "^18",
"react-router-dom": "^7", "zustand": "^4",
"clsx": "^2", "tailwind-merge": "^3",
"lucide-react": "^0.5", "tailwindcss": "^3",
"autoprefixer": "^10", "postcss": "^8"
},
"devDependencies": {
"@vitejs/plugin-react-swc": "^3",
"typescript": "^5", "vite": "^5"
}
}
避免使用:MUI、Chakra UI、Ant Design、framer-motion、styled-components — 对 FiveM CEF 来说都过于笨重。
fxmind Agent 视觉能力(NUI dump)
优先使用结构化状态,而非截图。Agent 负责接入和解除接入 — 不要让用户修改脚本:
fxmind_fivem_nui_wire{ resource }— 修改 fxmanifest,并将 DOM 探针注入ui_pageensurebridge 和资源;用户在游戏中打开 NUIfxmind_fivem_nui_dump- 完成前执行
fxmind_fivem_nui_unwire(必须清理)
可选的永久集成(Agent 调试不需要):从 bridge 代码片段中调用 registerFxmindNuiDump(() => useStore.getState())。
完整的实现指南(项目结构、vite.config、响应式系统、CSS 限制、Hooks 源码、Visibility/Animation/Theme Providers、调试器):ui-guide.md
评论
支持 Markdown