vue-three-glb-viewer
v0.1.2
Published
Vue 3 + Three.js GLB viewer component with anchor binding, icons, and camera persistence.
Readme
Vue 3 + TypeScript + Three.js GLB 查看器(可复用组件)
封装好的 GLB 交互组件,支持锚点绑定、图标+名称显示、右键菜单、拖拽换锚、连线、相机保存/恢复(含 2D/3D 视角),并暴露完整方法供业务方调用。
� 看不到模型?
如果组件加载成功但看不到 3D 模型,请查看 快速修复指南 👈
🐛 绑定成功但看不到标记?
如果可以点击绑定组件,但看不到标记图标,请查看 标记调试指南 👈
�📚 文档
- 快速上手
- 快速修复:看不到模型 ⭐- 在你的项目中使用 - 直接传递在线 URL 的用法 🔥- 在线 URL 加载问题 - CORS 跨域解决方案
- 使用示例 - 详细的代码示例
- 故障排查 - 完整的问题诊断指南
快速上手(作为依赖使用)
1. 安装依赖
npm install vue-three-glb-viewer three vue2. 准备模型文件
将 .glb 模型文件放到项目的 public/models/ 目录下。
3. 使用组件
⚠️ 重要:确保容器有明确的高度!
3. 使用组件
⚠️ 重要:确保容器有明确的高度!
<template>
<!-- 容器必须有高度! -->
<div style="height: 100vh;">
<GLBViewer
ref="viewerRef"
modelUrl="/models/model.glb"
/>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { GLBViewer } from 'vue-three-glb-viewer'
import type { GLBViewerPublicAPI, BoundComponentData } from 'vue-three-glb-viewer'
const viewerRef = ref<GLBViewerPublicAPI | null>(null)
onMounted(() => {
// 示例:加载已有锚点数据
const saved: BoundComponentData[] = []
viewerRef.value?.setBoundComponentsData?.(saved)
})
// 示例:保存/恢复相机
const save2D = () => viewerRef.value?.saveCamera2D()
const load2D = () => viewerRef.value?.loadCamera2D()
</script>常见问题:看不到模型?
如果组件加载成功但看不到模型,请检查:
- 容器高度:父容器必须有明确的高度(如
height: 100vh或height: 600px) - 模型路径:确保模型文件存在于
public/models/model.glb,或指定正确的modelUrl - 控制台错误:打开浏览器控制台(F12)查看是否有加载错误
详细排查步骤请查看 故障排查文档。
模型加载可配置:
- 默认使用静态地址
modelUrl(默认/models/model.glb)。- 可传入
fetchModel,返回 url / Blob / ArrayBuffer(例如从 API 获取),组件会自动创建 object URL 后加载。- 若加载失败将回退到默认立方体。
- 若不希望点击模型自动创建绑定,传入
:enableBindOnClick="false"。- 设计/运行模式:传入
:isDesignMode="false"时仅查看,不可绑定/拖拽/右键取消绑定。
示例:从接口拉取二进制再加载
const fetchModel = async () => {
const res = await fetch('/api/model')
if (!res.ok) throw new Error('fetch model failed')
return await res.arrayBuffer()
}示例:改用自定义静态地址
<GLBViewer modelUrl="/assets/scene.glb" />暴露的 API(通过模板 ref 调用)
- 相机:
getCameraState()/setCameraState(state)saveCameraToLocalStorage()/loadCameraFromLocalStorage()saveCamera2D()/loadCamera2D()saveCamera3D()/loadCamera3D()
- 绑定数据:
getBoundComponentsData(): BoundComponentData[]setBoundComponentsData(data: BoundComponentInput[]): boolean
- 图标与元数据:
setComponentIcon(id, iconSrc)setComponentsIcons(iconMap: Record<number, string>)setComponentsMeta([{ id, name?, iconSrc? }, ...])
- 回调:
setOnBindCallback((component) => void)(用户点击模型新建锚点时触发)setOnBindEnd((component) => boolean | void)(绑定结束回调,可用于业务自定义)setOnUnbind((componentId) => boolean | void)(取消绑定时触发)setOnMarkerClick((component) => void)(用户点击标记时触发)setOnMarkerContextMenu((component, event) => boolean | void)(标记右键时触发;返回 false 可阻止默认菜单)setOnMarkerDragEnd((component) => boolean | void)(标记拖拽结束时触发)unbindComponent(id: number)(直接取消绑定并触发回调)
主要数据结构(从包内导出):
CameraState:{ position: {x,y,z}, target: {x,y,z} }AnchorData:{ objectUUID: string, local: { x, y, z } }BoundComponentData:{ id, name, meshName?, iconSrc, anchor: AnchorData }BoundComponentInput:用于导入,anchor必填,其余可选。
运行与构建(本仓库)
- 开发:
npm run dev - 生产构建:
npm run build - 库构建:
npm run build:lib
发布到 npm(提示)
- 确保 Node ≥ 20.19。2) 更新
package.json的 version。3) 登录 npm:npm login。4) 发布:npm publish(若包名带 scope 用npm publish --access public)。
常见问题
1. 组件引入成功但看不到模型?
可能原因:
- ✅ 模型文件路径不正确:默认模型路径是
/models/model.glb,请确保你的项目中有这个文件,或者传入正确的modelUrl属性。 - ✅ 容器没有高度:组件本身高度为
100vh,确保父容器有明确的高度。 - ✅ 没有提供模型数据:如果使用
fetchModel从 API 加载,确保该函数正确返回数据。
解决方案:
<template>
<!-- 方案1: 指定正确的静态模型路径 -->
<GLBViewer modelUrl="/assets/your-model.glb" />
<!-- 方案2: 从 API 加载模型 -->
<GLBViewer :fetchModel="fetchModelFromServer" />
<!-- 方案3: 确保容器有高度 -->
<div style="height: 600px;">
<GLBViewer modelUrl="/path/to/model.glb" />
</div>
</template>
<script setup>
// 从服务器加载模型示例
const fetchModelFromServer = async () => {
const response = await fetch('/api/models/my-model.glb')
if (!response.ok) throw new Error('模型加载失败')
return await response.arrayBuffer()
}
</script>2. 控制台显示模型加载失败?
检查以下几点:
- 模型文件是否存在于指定路径
- 服务器是否正确配置了
.glb文件的 MIME 类型(model/gltf-binary) - 是否存在跨域问题(CORS)
如果模型加载失败,组件会自动显示一个默认的绿色立方体。
3. 如何在生产环境中使用?
<template>
<GLBViewer
:modelUrl="modelPath"
:isDesignMode="false"
:enableBindOnClick="false"
/>
</template>
<script setup>
import { ref } from 'vue'
const modelPath = ref('/static/models/production-model.glb')
</script>4. TypeScript 类型支持
确保在项目中安装了类型依赖:
npm install --save-dev @types/three然后就可以使用完整的类型提示:
<script setup lang="ts">
import type { GLBViewerPublicAPI } from 'vue-three-glb-viewer'
const viewerRef = ref<GLBViewerPublicAPI | null>(null)
</script>许可证
MIT
