Using external JS libraries in a web component

前端 未结 2 1292
忘掉有多难
忘掉有多难 2021-02-07 07:24

I am developing a web component using Polymer 2, and would like to make use of a third-party JavaScript library, which was not specifically designed for use with web components.

相关标签:
2条回答
  • 2021-02-07 07:42

    I actually had to deal with that exact same issue yesterday so good timing ;) In my case the view in the first page has two sections one with radio buttons and because of business requirements depending on the user's radio button selection an input text with google maps autocomplete would get enabled (or stay disabled)

    In this scenario it was much more efficient to load the page without the google maps libraries and then dynamically load the gmaps code after the webcomponent was fully rendered which lead to a 50% drop in time to interactive :) Here is what I ended up doing.

    NOTE: The loadGoogleMaps() method and the initCalled variable declaration are outside the class and thus outside of the webcomponent (I put them under the import statements). I also omitted most of the class code from the example as it wasn't relevant to your question :)

    import { html } from '@polymer/lit-element';
    import { PageViewElement } from './page-view-element.js';
    import { SharedStyles } from './shared-styles.js';
    import '@vaadin/vaadin-radio-button/vaadin-radio-button.js';
    import '@vaadin/vaadin-radio-button/vaadin-radio-group.js';
    import { spinner } from './my-icons.js';
    
    let initCalled;
    
    function loadGoogleMaps() {
      //Only load gmaps if it has not been loaded before (tracked by the initCalled flag)
      if (!initCalled) {
        //Dynamically import the library and append it to the document header
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.async = true;
        script.onload = function () {
          //Code to execute after the library has been downloaded parsed and processed by the browser starts here :)
          initCalled = true;
    
          //TODO: Refactor this DOM traversing logic
          const searchAutocomplete = document.querySelector('my-app').shadowRoot.querySelector("home-property-view")
            .shadowRoot.querySelector('home-property').shadowRoot.querySelector("input[type='text']");
    
          const autocomplete = new google.maps.places.Autocomplete(
            searchAutocomplete, {
              types: ['address'],
              componentRestrictions: {  //Limit to only US addresses
                'country': 'us'
              }
            });
    
          autocomplete.addListener('place_changed', function () {
            const place = autocomplete.getPlace();
            dispatchEvent(new CustomEvent('propertyAddressChanged', {
              bubbles: true,
              composed: true,
              detail: place
            }));
          });
        };
        //Specify the location of the gmaps library
        script.src = '//maps.googleapis.com/maps/api/js?v=3.33&key=<YOUR-API-KEY-GOES-HERE>&libraries=places';
    
        //Append it to the document header
        document.head.appendChild(script);
      }
    }
    
    class HomeProperty extends PageViewElement {
      //....omitted class code for brevity...
    
      _didRender(props, changedProps, prevProps) {
        loadGoogleMaps();
      }
    
      //....omitted class code for brevity...
    }
    
    0 讨论(0)
  • 2021-02-07 07:50

    If you have an external library that does things like document.querySelector then you have two choices.

    1. Choose to not use ShadowDOM with any of your components. If that is not an option, or if you really, REALLY want to use shadowDOM then:
    2. You need to modify the third party library to allow a root element to be specified instead of always using document.

    Beyond those two options you will probably not be able to use a third party library that assumes document will work for everything.

    I guess the other option is to re-evaluate the third party library and see if it is REALLY worth using.

    On my team we don't use third party libraries that are not just solid logic. Things like moment.js are just logic and we can use them without problems.

    But something like jQuery? Yuck! I can't see needing something like that for a component.

    Good luck!

    0 讨论(0)
提交回复
热议问题