一、前言
背景:开发一个WebGIS系统时有多个界面或者说多个函数都需要查看/调用同一个地图实例。
这时候就可以用上单例的设计模式进行开发,单例模式:
- 保证一个类仅有一个实例,并提供一个它的全局访问点
- 主要解决一个全局使用的类频繁地创建和销毁的问题
二、实现一个简单的地图单例
利用es6的class创建一个简单地图单例:
export class CesiumMap {
constructor (target, Option = viewerOption) {
// 首次使用构造器实例
if (!CesiumMap.instance) {
this.target = target
this.map = new Cesium.Viewer(target, Option)
// 将this挂载到CesiumMap这个类的instance属性上
CesiumMap.instance = this
}
return CesiumMap.instance
}
}
实验一下:在一个界面中创建两个div作为渲染地图的容器。
<template>
<div>
<button @click="showInstance">看看地球</button>
<div id="map" style="width: 100%;height: 100%;"></div>
<div id="other" style="width: 100%;height: 100%;"></div>
</div>
</template>
<script>
import {
CesiumMap } from '@/utils/createCesium.js'
export default {
data () {
return {
mapA: {
}
}
},
mounted () {
this.mapA = new CesiumMap('map') // 将地图渲染到id为map的div上
console.log('mapInstance: ', this.mapA)
},
methods: {
showInstance () {
const mapB = new CesiumMap('other') // 将地图渲染到id为other的div上
console.log('mapInstance点击按钮: ', mapB)
console.log('mapInstance一样吗: ', this.mapA === mapB) // 结果为true
}
}
}
</script>
页面加载时,首先会在id为map
的div中渲染一个地球,这时候我们看控制台,打印出来的target确实是map
然后我们点击一下按钮,发现target没有变,还是map
同时,this.mapA === mapB
三、最后
此外,我们还可以通过代理模式对创建地图单例做出拓展,实现代理单例。(但是我还不是很熟练,将在后续更新)