3Dmol.js + Vue3快速上手

一、安装

复制代码
npm install 3dmol --save

二、Vue3 组件:完整封装(直接用)

创建 src/components/Molecule3DViewer.vue

复制代码
<template>
  <div class="viewer-container">
    <!-- 3D 画布容器(必须设置宽高) -->
    <div ref="viewerRef" style="width: 100%; height: 500px; position: relative"></div>

    <!-- 控制面板 -->
    <div class="control-bar">
      <button @click="setStyle('stick')">球棍</button>
      <button @click="setStyle('sphere')">空间填充</button>
      <button @click="setStyle('cartoon')">卡通(蛋白)</button>
      <button @click="setStyle('line')">线型</button>
      <button @click="autoRotate()">自动旋转</button>
      <button @click="zoomTo()">居中</button>
      <button @click="clearViewer()">清空</button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as $3Dmol from '3dmol/build/3Dmol.js'

// DOM 容器
const viewerRef = ref(null)
// 3D Viewer 实例
let viewer = null
// 自动旋转状态
let rotating = false

// ==============================================
// 1. 初始化 3Dmol 视图
// ==============================================
onMounted(() => {
  const config = {
    backgroundColor: 'white',
    antialias: true,
    fog: false
  }
  viewer = $3Dmol.createViewer(viewerRef.value, config)
  
  // 默认加载:阿司匹林(SMILES)
  loadMoleculeFromSmiles('CC(=O)Oc1ccccc1C(=O)O')
})

// ==============================================
// 2. 从 SMILES 加载小分子(最常用)
// ==============================================
function loadMoleculeFromSmiles(smiles) {
  if (!viewer) return
  viewer.clear()

  $3Dmol.download(`smiles:${smiles}`, viewer, {}, () => {
    viewer.setStyle({}, { stick: { radius: 0.25 } })
    viewer.zoomTo()
    viewer.render()
  })
}

// ==============================================
// 3. 从 PDB 加载蛋白质(示例:胰岛素 PDB)
// ==============================================
function loadProteinFromPDB(pdbId = '1AKE') {
  if (!viewer) return
  viewer.clear()

  const url = `https://files.rcsb.org/view/${pdbId}.pdb`
  $3Dmol.download(url, viewer, {}, () => {
    viewer.setStyle({}, { cartoon: { color: 'spectrum' } })
    viewer.zoomTo()
    viewer.render()
  })
}

// ==============================================
// 4. 切换显示样式
// ==============================================
function setStyle(type) {
  if (!viewer) return

  switch (type) {
    case 'stick':
      viewer.setStyle({}, { stick: { radius: 0.25 } })
      break
    case 'sphere':
      viewer.setStyle({}, { sphere: { radius: 0.5 } })
      break
    case 'line':
      viewer.setStyle({}, { line: { linewidth: 3 } })
      break
    case 'cartoon':
      viewer.setStyle({}, { cartoon: { color: 'spectrum' } })
      break
  }

  viewer.render()
}

// ==============================================
// 5. 自动旋转
// ==============================================
function autoRotate() {
  rotating = !rotating
  viewer.spin(rotating ? 'y' : false)
}

// ==============================================
// 6. 自适应居中
// ==============================================
function zoomTo() {
  viewer?.zoomTo()
  viewer?.render()
}

// ==============================================
// 7. 清空画布
// ==============================================
function clearViewer() {
  viewer?.clear()
  viewer?.render()
}

// ==============================================
// 8. 组件销毁时清理
// ==============================================
onUnmounted(() => {
  if (viewer) {
    viewer.clear()
    viewer = null
  }
})
</script>

<style scoped>
.viewer-container {
  max-width: 900px;
  margin: 20px auto;
}
.control-bar {
  margin-top: 12px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
button {
  padding: 6px 12px;
  border: none;
  border-radius: 4px;
  background: #42b983;
  color: white;
  cursor: pointer;
}
</style>

三、在 App.vue 中使用

复制代码
<template>
  <Molecule3DViewer />
</template>

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

四、3Dmol.js 核心 API 手册(Vue 版)

1. 创建 Viewer

复制代码
viewer = $3Dmol.createViewer(元素, {
  backgroundColor: 'white',
  antialias: true
})

2. 加载分子方式

(1)SMILES(小分子)
复制代码
$3Dmol.download(`smiles:${smiles}`, viewer, {}, () => {
  // 渲染完成回调
})
(2)PDB(蛋白质)
复制代码
$3Dmol.download(`https://files.rcsb.org/view/1AKE.pdb`, viewer, {}, () => {})
(3)直接传入 PDB/MOL 字符串
复制代码
viewer.addModel(pdbString, 'pdb')

3. 样式设置(最常用)

复制代码
// 球棍
viewer.setStyle({}, { stick: { radius: 0.25 } })

// 空间填充(CPK)
viewer.setStyle({}, { sphere: { radius: 0.5 } })

// 线型
viewer.setStyle({}, { line: {} })

// 蛋白卡通(彩虹色)
viewer.setStyle({}, { cartoon: { color: 'spectrum' } })

4. 选择器(筛选原子 / 残基)

复制代码
// 选择所有碳原子
viewer.setStyle({ elem: 'C' }, { stick: { color: 'gray' } })

// 选择 10-20 号残基
viewer.setStyle({ resi: [10, 20] }, { cartoon: { color: 'red' } })

5. 交互控制

复制代码
viewer.zoomTo()           // 自适应居中
viewer.spin('y')          // Y 轴旋转
viewer.spin(false)        // 停止旋转
viewer.render()           // 强制刷新画面
viewer.clear()            // 清空模型

6. 颜色设置

复制代码
{ color: 'white' }
{ color: 'red' }
{ color: '#ff0000' }
{ color: 'spectrum' }     // 彩虹渐变

五、Vue3 + 3Dmol.js 常见问题

1. 画布不显示

必须给容器设置 width + height + position: relative

2. 切换路由后报错

onUnmounted 中必须 viewer.clear()

3. 模型加载不出来

检查网络、SMILES 格式、PDB ID 是否正确

六、高级功能(可直接加)

  • 分子表面(表面渲染)
  • 自定义高亮 / 标注
  • 点击原子显示信息
  • 多模型切换
  • 截图保存
  • 配体 + 蛋白 共展示
相关推荐
镜宇秋霖丶7 小时前
2026.5.18@霖宇博客制作中遇见的问题
vue.js
w_t_y_y7 小时前
VUE3(二)VUE2和VUE3区别
前端·javascript·vue.js
不是山谷.:.7 小时前
Axios的【接口防抖 + 请求失败重试 + 弱网提示】三合一高阶版封装
前端·javascript·vue.js·笔记·elementui·typescript
w_t_y_y8 小时前
VUE3(一)VUE3语法
前端·javascript·vue.js
builderwfy8 小时前
VUE子页面调用父页面实现方式
前端·javascript·vue.js
小小荧8 小时前
Vue Native多分支迭代,Vue跨端原生生态迎来革新
前端·javascript·vue.js
欧阳天风9 小时前
vue+vite生产环境更新提示
前端·javascript·vue.js
布局呆星10 小时前
Pinia 综合笔记:介绍、两种 API、实例方法与持久化
前端·javascript·vue.js
fxshy10 小时前
Vue 项目中 vis-network 点击节点不生效的问题排查:外层 transform 缩放导致坐标偏移
前端·javascript·vue.js