This is the 7th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.
⏳ preface
I am a front-end 🐥. Recently, WHEN I learned the package of components, I began to package the Amap component for learning to use. There are a lot of corrections to be made in this component.
🚚 Component requirements
-
templated
We need to render the HTML template when creating the component instance, so we need to templatethe component
-
scalability
Marker points in the Map are dynamically passed in based on back-end data, which means we need to pass the data source to the Map component, which then uses this data source to render the marker points into HTML
-
api
We need to design apis for components based on their business requirements, such as adding information forms for tag points and customizing information form content
🔧 implementation
Before we start writing the code, let’s review the component requirements:
templated
- When a user instantiates a component, the id name of the container is passed in
container
And configuration optionsoptions
(Optional, default if not passed), register the map instance and render it to the container
Design of the API
- The user can pass in marker point data
markerList
Render to the map - For each marker point
marker
Register the information form and pop up the corresponding information form when clicking the mark point - The user can customize the form content, passing in information about the form’s title
title
And the contentcontent
- Add life cycle and click events to the map, listen for map loading completion and click map events
Based on the above requirements, I designed the following six apis
- Init () – Initializes the map instance
- RenderMarkers (markerList) – renderMarkers
- RegisterInfoWindow () – Registration information window
- CreateInfoWindow (title, content) – createInfoWindow style
- OnMounted () – Component life cycle
- HandleClickMap () – Map click event
class GaodeMap {
constructor(container, options) {
this.container = container
this.options = options
this.map = {}
this.markers = []
this.init(container, options)
}
init(container, options) {
this.map = new AMap.Map(container, options);
this.map.on('complete'.() = > {
this.onMounted() // register lifecycle hook for component})}renderMarker(markerList) {
markerList.map(item= > {
const marker = new AMap.Marker({
position: new AMap.LngLat(item.Lng, item.Lat),
title: item.title
});
marker.address = item.address // Assign the corresponding item attribute address to marker
this.markers.push(marker)
})
this.map.add(this.markers)
}
registerInfoWindow() {
const content = [];
this.markers.map(marker= > {
const title = marker.w.title
const address = marker.address
const infoWindow = new AMap.InfoWindow({
isCustom: true.content: this.createInfoWindow(title, address, content.join("<br/>")),
offset: new AMap.Pixel(16, -45)
})
AMap.event.addListener(marker, 'click'.(e) = > {
// Listen for the tag point click event
infoWindow.open(this.map, marker.getPosition()) }); })}createInfoWindow(title, content) {
var info = document.createElement("div");
info.className = "custom-info input-card content-window-card";
// You can modify the width and height of a custom form in the following ways
//info.style.width = "400px";
// Define the top title
var top = document.createElement("div");
var titleD = document.createElement("div");
var closeX = document.createElement("img");
top.className = "info-top";
titleD.innerHTML = title;
closeX.src = "https://webapi.amap.com/images/close2.gif";
closeX.onclick = this.closeInfoWindow()
top.appendChild(titleD);
top.appendChild(closeX);
info.appendChild(top);
// Define the middle content
var middle = document.createElement("div");
middle.className = "info-middle";
middle.style.backgroundColor = 'white';
content += "Address:" + `<a href="javascript:;" >${address}</a>`
middle.innerHTML = content;
info.appendChild(middle);
// Define the bottom content
var bottom = document.createElement("div");
bottom.className = "info-bottom";
bottom.style.position = 'relative';
bottom.style.top = '0px';
bottom.style.margin = '0 auto';
var sharp = document.createElement("img");
sharp.src = "https://webapi.amap.com/images/sharp.png";
bottom.appendChild(sharp);
info.appendChild(bottom);
return info;
}
closeInfoWindow() {
return () = > {
this.map.clearInfoWindow(); }}onMounted() {
// do something when the map is completed
console.log('Map is mounted! ');
this.map.on('click', handleClickMarker)
}
handleClickMarker(e) {
console.log('Clicked on the map',[e.lnglat.lng, e.lnglat.lat]); }}Copy the code
Specific use:
; (async function() {
const options = {
resizeEnable: true.// Whether to monitor map container size changes
zoom: 11.// Initialize the map hierarchy
center: [113.122717.23.008762].// Initializes the map center point
}
const myMap = new GaodeMap('container', options)
const { data: markerList } = await axios.post('http://localhost:3000/api')
myMap.renderMarker(markerList)
myMap.registerInfoWindow()
})();
Copy the code
The effect is shown below:
conclusion
Through this gaudamap gaudamap component package, we can summarize the general steps of component package:
- Render HTML structure
- Design Component API
- scalability
This hack map component only meets my business needs for the time being, but it still leaves a lot to be desired:
- You need to modify the contents of the information window
createInfoWindow
Part of the code does not achieve component encapsulation - You cannot select a specific icon for a specific marker point
Finally, I hope you can put forward suggestions and opinions!!