主要用于mapbox GL的Popup,Marker 如何与Vue前端框架融合,把popup里面的DOM抽离成vue组件,避免在js中大量拼接DOM写样式绑方法。
地图上创建marker时,可以使用dom元素.默认是一个浅蓝色、水滴状的SVG标记。
创建popup时,使用setDOMContent方法将弹窗内容设置为以 DOM 节点形式提供的元素。
1 2 3 4 5 6 7 8 9 10 let el =document .createElement ("div" );var marker = new mapboxgl.Marker (el) .setLngLat (e.lngLat ) .addTo (map); var popup = new mapboxgl.Popup () .setLngLat (e.lngLat ) .setDOMContent (el) .addTo (map);
vue组件中取dom vue官网上有实例的对象 vm.$el ,可以取到Vue 实例使用的根 DOM 元素。
1 2 3 4 5 6 7 8 9 10 11 12 import Vue from 'vue' ;var Comp = Vue .extend ({ props : ['msg' ], template : '<div>{{ msg }}</div>' }) var vm = new Comp ({ propsData : { msg : 'hello' } }) let dom =vm.$el ;
上面的例子中可以看到如何取到了我们想要的dom节点。
实例使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 import Vue from 'vue' ;import * as components from './src' ;import store from '@/store' let currentPopup;let instance;let Template ;const popovers = [];const getPopover = function (_str ) { Template = Vue .extend (components[_str]); }; const defaultCallback = action => { if (currentPopup) { const callback = currentPopup.callback ; if (typeof callback === 'function' ) { callback (action); } else { closePopover (); } } }; const initInstance = (data ) => { instance = new Template ({ propsData : data, store : store, el : document .createElement ('div' ), }); instance.callback = defaultCallback; }; const getPopoverElement = (type, options ) => { if (!type) return ; getPopover (type); initInstance (options); instance.action = '' ; if (popovers.length > 0 ) { const _options = options; if (_options.callback === undefined ) { instance.callback = defaultCallback; } Object .keys (_options).forEach (prop => { if (_options[prop]) { instance[prop] = _options[prop]; } }); document .body .appendChild (instance.$el ); Vue .nextTick (() => { instance.visible = true ; }); } return instance.$el ; }; const showPopover = function (type, map, options = {} ) { if (options.closeLast ) { closePopover (); } if (!options.coordinates || !options.coordinates [0 ] || !options.coordinates [1 ]) { console .warn ('无空间信息!' ); return false ; } const contentHtml = getPopoverElement (type, options); const popover = new mapboxgl.Popup (Object .assign ({}, { closeButton : true }, options)); const coords = options.coordinates ; popover.setLngLat (coords) .setDOMContent (contentHtml) .addTo (map); currentPopup = popover; popovers.push (currentPopup); if (options.autoCenter ) { map.animateTo ({ center : coords }); } }; function closePopover ( ) { if (currentPopup) { currentPopup.remove (); currentPopup = null ; instance.$destroy(); } } export { showPopover, closePopover,getPopoverElement };