1、背景:
项目运用的言语是vue+iview,因为用到了3D,所以找公司买了3d舆图的产物,然则题目随之而来。把我们项目须要用到的3d舆图封装成一个组件叫3dMap.vue,轻易各个页面挪用,vue的事情机制是在脱离当前页面的时刻把当前页面举行烧毁,然则因为Cesium的特征,他并没有没烧毁,每当接见一次,就会从新new一个Cesium.
const Viewer = new Cesium.Viewer("newID", {
navigation: this.navigation,
infoBox: this.infoBox
});
检察计算机历程会发明,chrome浏览器会同事跑6个以上历程,个中一个是Cesium的,它所占用的内存会跟着接见次数的增添不停上涨。
2、处理思绪:
既然每接见一次3dMap.vue就会new一个Cesium,那能不能就制造一个全局的Cesium,让他一向存在,经由过程显现与隐蔽去控制在每一个单页面运用中的显现呢。
3、着手:
·3.1起首建立一个全局的Cesium,起名global3D.vue,这个只是用来初始化
<script>
import Cesium from "Cesium";
import aa from '../../static/serverconfig.json'
import Vue from 'vue';
//建立一个div,用来做3d的盒子
const _div = document.createElement("div");
_div.id = "newID";
_div.style.display = "none";
//挂载在body内里,因为全部体系加载的时刻,页面只要body,其他元素都还未加载
document.body.appendChild(_div);
//用Viewer来吸收
const Viewer = new Cesium.Viewer("newID", {
navigation: this.navigation,
infoBox: this.infoBox
})
//中心部份写初始化3d须要的要领
//把Viewer抛出去
export default {
Viewer,
};
</script>
3.2在main.js中举行挂载
import global_ from './components/global3D'
Vue.prototype.GLOBAL = global_
3.3 建立一个3DViewer.vue,用来吸收全局的Cesium,这个文件中能够写一些设置相机视角,猎取经纬度啊等等要领,
export default {
data() {
return {
//吸收全局的Viewer,这个Viewer是Cesium new 出来的
viewer: this.GLOBAL.Viewer,
scene: this.GLOBAL.Viewer.scene
};
},
}
3.4 单页面运用
<template>
<div class="GISbox" id="GISbox" ref="gisBox">
<SmViewer ref="TestSmViewer"></SmViewer>
</div>
</template>
<script>
import SmViewer from "../../../../components/Common/3D/3DViewer";
export default{
components: {SmViewer},
mounted() {
this.setGIS();
},
methods: {
setGIS() {
//猎取到3d的盒子
var gis = document.getElementById("newID");
//3d在页面中的款式,可根据本身的需求举行调解
gis.style.display = "block";
gis.style.position = "absolute";
gis.style.top = "0px";
gis.style.height = "100%";
gis.style.width = "99%";
//从body中移除
document.body.removeChild(gis);
//在本页面中的制订位置举行挂载
document.getElementById("GISbox").appendChild(gis);
// 加载视角,即写在3DViewer.vue中的要领,父音调
this.$refs.TestSmViewer.setViewAngAngle();
},
destory3D() {
//猎取到3d的盒子
var gis = document.getElementById("newID");
//隐蔽
gis.style.display = "none";
//从当前页面中移除
document.getElementById("GISbox").removeChild(gis);
//从新挂载回body
document.body.appendChild(gis);
}
},
beforeDestory(){
//在本页面烧毁前举行这一步操纵
this.destory3D()
}
</script>
3.4 假如你的3d只是运用在差别的模块中,且这些模块之间没有配合的组件,以下图,在demo1模块中,demo1Page1和demo1Page2配合运用demo1Menu,且只要demo1Page1页面运用3d组件,demo2同,那末到3.3,就能够圆满的处理这个题目,然则,假如你的3d是应该在同一个模块,且有配合的组件,那末在差别页面之间跳转的时刻就会涌现题目。比方,在demo1模块中,demo1Page1和demo1Page2配合运用demo1Menu,且demo1Page1页面和demo1Page2页面都运用了3d组件,demo2同,那末在由demo1内里的页面跳向demo2内里的页面的时刻,3d就会丧失了
demo1 demo2
demo1Menu demo2Menu
demo1Page1 demo2Page1
demo1Page2 demo2Page2
3.5 处理
处理这个题目主如果运用的vue的keep-Alive,
起首,在App.vue中,做推断,假如运用了keep-Alive,则走第一个,不然的话,走第二个
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
然后,在router内里,对须要被缓存的模块举行设置
{
path: 'homePage',
component: UMPatrolHomePage,
name: 'UMPatrolHomePage',
meta: {
keepAlive: true //须要被缓存
}
}
末了,在单页面中写入以下,to是要去的谁人页面的途径,from是从哪一个页面来的谁人途径,next()必需实行,不然跳转会被阻拦,假如要去的页面或许from的页面运用了3d,则这个页面须要被缓存,即keep.Alive=true,胜利缓存后,然后实行烧毁操纵,如许在差别页面之间切换的时刻,就不会涌现3d丧失的状况。道理感兴趣的同砚能够自行搜刮,网上有许多细致说明注解的文章
beforeRouteLeave(to, from, next) {
if (
to.name == "UMPatrolHomePage" ||
to.name == "UMDetailEquipment" ||
to.name == "假造巡检" ||
to.name == "职员定位概况" ||
to.name == "管廊安防监控列表" ||
to.name == "管廊环境监控列表" ||
from.name == "职员定位概况" ||
from.name == "假造巡检" ||
from.name == "UMDetailEquipment" ||
from.name == "UMPatrolHomePage" ||
from.name == "管廊安防监控列表" ||
from.name == "管廊环境监控列表"
) {
from.meta.keepAlive = true;
to.meta.keepAlive = true;
this.$destroy();
next();
} else {
from.meta.keepAlive = false;
to.meta.keepAlive = false;
this.$destroy();
next();
}
},