本文最后更新于 42 天前,其中的信息可能已经有所发展或是发生改变。
本文将带你快速在Vue3项目中集成Three.js,通过组合式API实现动态3D效果。最终成果包含自动旋转的彩色立方体、灯光效果和响应式布局。
🌟环境准备
1. 创建Vue3项目
npm create vue@latest
2. 安装依赖
npm install three @types/three
# 可选轨道控制器(推荐)
npm install three-orbitcontrols-ts
🚀 核心实现代码
<!-- src/components/ThreeScene.vue -->
<template>
<div ref="canvasContainer" class="scene-container"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three-orbitcontrols-ts'
const canvasContainer = ref(null)
// 初始化场景
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
const renderer = new THREE.WebGLRenderer({ antialias: true })
// 创建几何体
const geometry = new THREE.BoxGeometry(2, 2, 2)
const material = new THREE.MeshPhongMaterial({
color: 0x00ff00,
shininess: 100
})
const cube = new THREE.Mesh(geometry, material)
// 添加灯光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
const pointLight = new THREE.PointLight(0xffffff, 1.5)
pointLight.position.set(5, 5, 5)
onMounted(() => {
// 场景初始化
scene.add(cube, ambientLight, pointLight)
camera.position.z = 7
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(window.devicePixelRatio)
canvasContainer.value.appendChild(renderer.domElement)
// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
// 动画循环
const animate = () => {
requestAnimationFrame(animate)
cube.rotation.x += 0.01
cube.rotation.y += 0.005
controls.update()
renderer.render(scene, camera)
}
animate()
// 响应式处理
window.addEventListener('resize', onWindowResize)
})
const onWindowResize = () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
}
onUnmounted(() => {
window.removeEventListener('resize', onWindowResize)
canvasContainer.value?.removeChild(renderer.domElement)
})
</script>
<style scoped>
.scene-container {
width: 100vw;
height: 100vh;
background: linear-gradient(45deg, #1a1a1a, #2d2d2d);
}
canvas {
display: block;
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
border-radius: 10px;
}
</style>
📌 关键实现点解析
1. Vue3集成方案
- 使用
<script setup>
语法糖 - 通过
onMounted
生命周期初始化Three.js - 在
onUnmounted
中清理资源防止内存泄漏
2. 性能优化
// 开启抗锯齿
renderer = new THREE.WebGLRenderer({
antialias: true
})
// 设置设备像素比
renderer.setPixelRatio(window.devicePixelRatio)
3. 交互增强
// 启用阻尼效果(惯性滑动)
controls.enableDamping = true
// 每帧需要调用update
controls.update()
💡 效果升级建议
添加纹理贴图
const textureLoader = new THREE.TextureLoader()
const material = new THREE.MeshStandardMaterial({
map: textureLoader.load('/textures/wood.jpg')
})
实现模型加载
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
new GLTFLoader().load('/models/scene.gltf', (gltf) => {
scene.add(gltf.scene)
})
🛠️ 常见问题解决
Q: 为什么出现空白页面?
- 检查容器元素是否设置宽高
- 确认camera.position正确设置
- 验证材质是否需要灯光
Q: 如何提升渲染性能?
- 使用
BufferGeometry
代替普通Geometry - 合并相似材质
- 开启WebGL2支持:
renderer = new THREE.WebGLRenderer({ antialias: true, powerPreference: "high-performance" })
🌈 扩展资源
提示:本文示例需要现代浏览器支持WebGL2,建议在Chrome/Firefox最新版中运行