You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue及Nuxt中使用Spline 3D?解决交互事件无响应问题

解决Vue中集成Spline 3D的交互问题与组件封装方案

一、交互失效的原因

你直接在main.js中提前初始化Spline,此时Vue实例还未完成挂载,后续Vue的DOM操作可能干扰Spline的事件监听绑定;另外代码存在变量错误(objectToAnimate未定义,应为obj),会导致后续逻辑中断。

二、封装Vue组件的正确方式

将Spline逻辑封装为Vue单文件组件,利用Vue生命周期钩子管理Spline实例,确保DOM就绪后再初始化,同时正确处理事件绑定与销毁:

1. 创建SplineScene.vue组件

<template>
  <canvas ref="splineCanvas" class="spline-canvas"></canvas>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { Application } from '@splinetool/runtime'

const splineCanvas = ref(null)
let splineInstance = null

onMounted(async () => {
  if (!splineCanvas.value) return
  
  // 初始化Spline应用
  splineInstance = new Application(splineCanvas.value)
  await splineInstance.load('你的Spline场景URL')
  
  // 绑定交互事件示例:点击球体触发动作
  const sphere = splineInstance.findObjectByName('sphere')
  if (sphere) {
    // 监听对象点击事件
    sphere.addEventListener('mouseDown', () => {
      sphere.emitEvent('follow')
    })
    
    // 也可以监听全局Spline事件
    splineInstance.addEventListener('mouseDown', (e) => {
      console.log('点击了场景中的元素:', e.target.name)
    })
  }
})

onUnmounted(() => {
  // 销毁Spline实例,避免内存泄漏
  splineInstance?.dispose()
})
</script>

<style scoped>
.spline-canvas {
  width: 100%;
  height: 100vh;
  display: block;
}
</style>

2. 在App.vue中使用组件

<template>
  <div id="app">
    <SplineScene />
    <!-- 你的其他Vue内容 -->
  </div>
</template>

<script setup>
import SplineScene from './components/SplineScene.vue'
</script>

三、在Vue应用旁渲染的方案

如果你希望Spline场景独立于Vue应用DOM容器,可保留index.html中的canvas,但要调整初始化时机,确保Vue挂载完成后再初始化Spline:

修改main.js:

import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { Application } from "@splinetool/runtime";

const app = createApp(App)
app.use(router)

// 等待Vue挂载完成后再初始化Spline
app.mount('#app').$nextTick(() => {
  const canvas = document.getElementById("spline3d");
  const spline = new Application(canvas);
  spline.load('你的Spline场景URL')
  .then(() => {
    const obj = spline.findObjectByName('sphere');
    if (obj) {
      obj.emitEvent('follow');
      // 绑定交互事件
      obj.addEventListener('mouseDown', () => {
        console.log('球体被点击')
      })
    }
  });
})

四、Nuxt.js适配方案

由于Nuxt.js是服务端渲染框架,Spline只能在客户端环境运行,需做以下处理:

  • 创建客户端组件:在components目录下创建SplineScene.client.vue(后缀.client表示仅在客户端渲染)
  • 页面中使用组件时,用<ClientOnly>包裹:
<template>
  <ClientOnly>
    <SplineScene />
  </ClientOnly>
</template>
  • 组件内的初始化逻辑仍放在onMounted钩子中,和前面的Vue组件逻辑一致

关键注意事项

  • 确保Spline场景URL正确,且场景已发布为可嵌入状态
  • 组件销毁时必须调用dispose()方法清理Spline实例,防止内存泄漏
  • 交互事件绑定需在load()方法完成后执行,确保对象已加载完成

内容的提问来源于stack exchange,提问作者user21369091

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 16:57:35