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 是否正确

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

  • 分子表面(表面渲染)
  • 自定义高亮 / 标注
  • 点击原子显示信息
  • 多模型切换
  • 截图保存
  • 配体 + 蛋白 共展示
相关推荐
daols881 小时前
vxe-table 渲染器教程一:实现金额输入控件
javascript·vue.js·vxe-table
不好听6132 小时前
React vs Vue:两大前端框架技术选型深度对比
前端·vue.js·react.js
腻害兔3 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程
腻害兔5 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:支付模块 yudao-module-pay,一个让产品经理都看懂的支付中台设计
java·前端·vue.js·产品经理·ai编程
Larcher10 小时前
LangChain RAG 排错实录:.env 为什么没有生效
vue.js·后端
一个写前端的11 小时前
基于 Vue 3 的大文件分片上传组件,支持断点续传、并发上传、失败重试等功能
前端·javascript·vue.js
活于未来11 小时前
从零搭建期权波动率曲面可视化平台:FastAPI + Vue 3 实战
vue.js
橘子海全栈攻城狮12 小时前
【最新源码】基于SpringBoot + Vue的超市管理系统的设计与实现D002
java·开发语言·vue.js·spring boot·后端·spring
Cobyte15 小时前
使用 JavaScript 实现有限状态机的经典问题
前端·javascript·vue.js
acheding15 小时前
File System Access API 实战:让网页真正读写本地文件
前端·javascript·vue.js·编辑器·markdown