将 google markerclusterer plus 实施到 stencil webcomponents

Implementing google markerclusterer plus into stencil webcomponents

我阅读了很多有关如何将外部文件实施到模板中的内容,但还没有达到我想要的效果。特色是模板在 Liferay 主题中运行。但我认为这应该无关紧要。

我通过 npm 从 google 安装了 MarkerClustererPlus,在模板配置中我将 min 文件复制到“资产”文件夹中,如下所示:

import { Config } from '@stencil/core';
import { sass } from '@stencil/sass';
import nodePolyfills from 'rollup-plugin-node-polyfills';

export const config: Config = {
  namespace: 'gwkp-components',
  srcDir: 'src/js/components',
  plugins: [
    sass({
      injectGlobalPaths: [
        'build/css/clay/_mixins.scss',
        'build/css/fonts/font-awesome/scss/_mixins.scss',
        'build/css/fonts/font-awesome/scss/_variables.scss',
        'build/css/fonts/font-awesome/scss/_core.scss',
        'src/js/components/utils/_stencilvars.scss',
        'build/css/fonts/font-awesome/scss/regular.scss',
        'build/css/fonts/font-awesome/scss/light.scss',
        'build/css/fonts/font-awesome/scss/solid.scss',
        'build/css/clay/bootstrap/_functions.scss',
        'build/css/clay/bootstrap/_mixins.scss',
        'build/css/clay/bootstrap/_variables.scss',
        'src/css/gw/_colors.scss',
        'src/css/gw/_variables.scss',
        'src/css/gw/bem/_includes.scss'
      ]
    })
  ],
  outputTargets: [
    {
      type: 'www',
      buildDir: '.',
      dir: 'build/js/components',
      serviceWorker: null, // disable service workers
      copy: [
        { src: '../../../build/css/fonts/font-awesome/webfonts', dest: 'webfonts' },
        { src: '../../../node_modules/@google/markerclustererplus/dist/markerclustererplus.min.js', dest: 'assets/js/markerclustererplus.min.js' }
      ]
    }
  ],
  rollupPlugins: {
    after: [
      nodePolyfills()
    ]
  }
};

现在的问题是如何获得对 min.js 文件的访问权限?我是否需要一个导入语句并声明一个变量或创建一个脚本标签?我以某种方式尝试了两种方法,但到目前为止没有任何效果。我只在一个组件中需要它。

最后我想在组件中使用以下代码:

var markerCluster = new MarkerClusterer(this.map, this.markerMap,
            {imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});

无需将 node_modules/@google/markerclustererplus/dist/markerclustererplus.min.js 复制到 assets/js/markerclustererplus.min.js

在您组件的 tsx 文件中,只需导入 MarkerCluster

import MarkerClusterer from "@google/markerclustererplus";

您需要已经加载 google 地图 javascript 库。据我所知,您必须通过脚本标签加载它,但这可以完成 dynamically.

我在示例中使用 // @ts-ignore,但如果您愿意,也可以 install the Google Maps types

最终组件应如下所示:

import { h, Component, Host, Element, Listen } from "@stencil/core";
import MarkerClusterer from "@google/markerclustererplus";

@Component({
  tag: "my-component",
  styles: `
    :host {
      position: absolute;
      width: 100%;
      height: 100%;
    }

    .map {
      height: 100%;
    }
  `,
  shadow: true,
})
export class MyComponent {
  @Element() el: HTMLElement;

  private googleMapsApiKey = "YOUR_API_KEY_HERE";
  private locations = [
    { lat: -31.56391, lng: 147.154312 },
    { lat: -33.718234, lng: 150.363181 },
    { lat: -33.727111, lng: 150.371124 },
    { lat: -33.848588, lng: 151.209834 },
    { lat: -33.851702, lng: 151.216968 },
    { lat: -34.671264, lng: 150.863657 },
    { lat: -35.304724, lng: 148.662905 },
    { lat: -36.817685, lng: 175.699196 },
    { lat: -36.828611, lng: 175.790222 },
    { lat: -37.75, lng: 145.116667 },
    { lat: -37.759859, lng: 145.128708 },
    { lat: -37.765015, lng: 145.133858 },
    { lat: -37.770104, lng: 145.143299 },
    { lat: -37.7737, lng: 145.145187 },
    { lat: -37.774785, lng: 145.137978 },
    { lat: -37.819616, lng: 144.968119 },
    { lat: -38.330766, lng: 144.695692 },
    { lat: -39.927193, lng: 175.053218 },
    { lat: -41.330162, lng: 174.865694 },
    { lat: -42.734358, lng: 147.439506 },
    { lat: -42.734358, lng: 147.501315 },
    { lat: -42.735258, lng: 147.438 },
    { lat: -43.999792, lng: 170.463352 },
  ];
  private _mapEl: HTMLElement;

  componentDidLoad() {
    if (document.getElementById("maps-script")) {
      this.initMap();
      return;
    }

    // Create the script tag, set the appropriate attributes
    var script = document.createElement("script");
    script.id = "maps-script";
    script.src = `https://maps.googleapis.com/maps/api/js?key=${this.googleMapsApiKey}&callback=initMap`;
    script.defer = true;

    // Attach your callback function to the `window` object
    // @ts-ignore
    window.initMap = () => this.initMap();

    // Append the 'script' element to 'head'
    document.head.appendChild(script);
  }

  initMap() {
    // @ts-ignore
    const map = new google.maps.Map(this._mapEl, {
      zoom: 3,
      center: { lat: -28.024, lng: 140.887 },
    });

    // Create an array of alphabetical characters used to label the markers.
    const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    // Add some markers to the map.
    // Note: The code uses the JavaScript Array.prototype.map() method to
    // create an array of markers based on a given "locations" array.
    // The map() method here has nothing to do with the Google Maps API.
    const markers = this.locations.map((location, i) => {
      // @ts-ignore
      return new google.maps.Marker({
        position: location,
        label: labels[i % labels.length],
      });
    });

    // Add a marker clusterer to manage the markers.
    const markerCluster = new MarkerClusterer(map, markers, {
      imagePath:
        "https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m",
    });
  }

  render() {
    return (
      <Host>
        <div class="map" ref={(el) => (this._mapEl = el)}></div>
      </Host>
    );
  }
}

这是一个Working example on webcomponents.dev