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 incontainerAnd 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 datamarkerListRender to the map
  • For each marker pointmarkerRegister 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 titletitleAnd 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:

  1. Render HTML structure
  2. Design Component API
  3. scalability

This hack map component only meets my business needs for the time being, but it still leaves a lot to be desired:

  1. You need to modify the contents of the information windowcreateInfoWindowPart of the code does not achieve component encapsulation
  2. You cannot select a specific icon for a specific marker point

Finally, I hope you can put forward suggestions and opinions!!