const types = { control: { unload: 'removeControl' }, layer: { unload: 'removeTileLayer' }, overlay: { unload: 'removeOverlay' }, contextMenu: { unload: 'removeContextMenu' } } const getParent = $component => ($component.abstract || $component.$el === $component.$children[0].$el) ? getParent($component.$parent) : $component function destroyInstance() { const { unload, renderByParent, $parent } = this if (renderByParent) { $parent.reload() } unload() } class Mixin { constructor(prop) { this.methods = { ready() { const $parent = getParent(this.$parent) const mapLayers = this.mapLayers = $parent.mapLayers this.load() this.$emit('ready', { mapLayers }) }, transmitEvent(e) { this.$emit(e.type.replace(/^on/, ''), e) }, reload() { this && this.BMap && this.$nextTick(() => { this.unload() this.$nextTick(this.load) }) }, unload() { const { mapLayers, originInstance } = this try { switch (prop.type) { case 'search': return originInstance.clearResults() case 'autoComplete': case 'lushu': return originInstance.dispose() case 'markerClusterer': return originInstance.clearMarkers() default: mapLayers[types[prop.type].unload](originInstance) } } catch (e) { console.log(e) } } } this.computed = { renderByParent() { return this.$parent.preventChildrenRender } } this.mounted = function() { const $parent = getParent(this.$parent) const mapLayers = $parent.mapLayers const { ready } = this mapLayers ? ready() : $parent.$on('ready', ready) } this.destroyed = destroyInstance this.beforeDestroy = destroyInstance } } export default type => new Mixin({ type })