例如在使用 Cytoscape.js 时,用下面这种声明方式。
这样做的确是方便后面的操作,但问题是,这种对象特别大,嵌套层级很深,如下图所示,如果直接放在data里,vue的响应式机制,会监听cy的每个属性,开销巨大,CPU占用瞬间到100%。
所以在使用 Cytoscape.js 、 Echarts.js 与vue结合时,要避免直接放在data属性中。一种方法是,在 mounted() 里引入该对象。
另一种方法是用 Object.freeze()
这两个方法,都能避免vue的响应式开销,后面也能够正常操作 this.cy 对象。
首先在html页面中引入<script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>
页面中
<template>
<div>
<div id="demo"></div>
</div>
</template>
<script>
export default {
data() {
return {
mesh: null,
renderer: null,
scene: null,
camera: null,
}
},
mounted() {
this.init()
},
methods: {
init() {
// 创建场景
this.scene = new THREE.Scene()
// 创建相机(第一个参数视野夹角0~180°,第二参数相机大小,第三,四参数可看像素)
this.camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
1,
1000
)
// 创建渲染器
this.renderer = new THREE.WebGLRenderer()
// 设置渲染器大小
this.renderer.setSize(window.innerWidth, window.innerHeight)
// 拿到dom
let demo = document.getElementById("demo")
// 把渲染器放到dom中
demo.appendChild(this.renderer.domElement)
// 创建一个立方体(长,宽,高)
let geometry = new THREE.BoxGeometry(10, 10, 10)
// 创建材料(定义立方体由这个材料组成)
let material = new THREE.MeshBasicMaterial({
color: 0xcccccc,
})
// 创建网格(合并立方体和材料)
this.mesh = new THREE.Mesh(geometry, material)
// 将网格放入场景中
this.scene.add(this.mesh)
// 因默认情况相机与场景重合,需要先设定相机位置
this.camera.position.z = 50
this.camera.position.y = 0
// 用渲染器渲染场景,相机
this.renderer.render(this.scene, this.camera)
this.animate()
},
// 定义3D效果
animate() {
// 执行动画函数,执行完上一帧在执行下一帧
requestAnimationFrame(this.animate)
this.mesh.rotation.x += 0.05
// this.mesh.rotation.y += 0.05
this.mesh.rotateY(0.01)
this.renderer.render(this.scene, this.camera)
},
},
}
</script>
<style>
body {
margin: 0
overflow: hidden
/* 隐藏body窗口区域滚动条 */
}
</style>