Использование jQuery и начальной загрузки JS с компонентами stenciljs - PullRequest
0 голосов
/ 26 октября 2019

У нас есть приложение, созданное с использованием Angular, и теперь для всех требований заказчика мы хотим создавать веб-компоненты с использованием трафарета js.

Идея состоит в том, чтобы поддерживать чистоту основного приложения и не смешивать код для конкретных требований клиента.

Итак, мы подошли к веб-компонентам и придерживаемся Stencil JS.

Первая проблема, с которой мы сталкиваемся, заключается в том, что нашему веб-компоненту необходимо будет использовать jquery, начальной загрузки js и некоторые сторонние js.

Мы хотим, чтобы наши компоненты были инкапсулированы извне, что означает, что они будут в теневом домике.

Теперь у меня есть два вопроса

1) Это хорошая практика, чтобы каждый компонент включал библиотеки JS, такие как jQuery, bootstrap js и т. Д., Потому что это не кажется мне хорошей идеей 2) Какмы можем включить jQuery, например, в веб-компонент.

Я пробовал много способов, и последним было включить тег в конструктор веб-компонента трафарета, но он не работает.

export class TestComponent {

  @Prop() token: string;

  @State() test: string;
  @Element() private element: HTMLElement;

  constructor() {

    this.element.innerHTML = `
    <script src="../../assets/js/jquery.min.js"></script>

`;

Таким образом, вопрос заключается в том, как использовать сторонние библиотеки JS в веб-компоненте, встроенном в шаблон, который находится в shadow dom (для параметра shadow установлено значение true)

Любые мнения по этому поводу в целом приветствуются и будутценится :)

Ответы [ 3 ]

1 голос
/ 27 октября 2019

Для меня это звучит так, будто вы немного сгибаете назначение Stencil и Web-компонентов. У меня никогда не было этой боли, но я отвечал на твой вопрос: это зависит от того, чего ты хочешь достичь. Например, вы можете использовать Jquery непосредственно внутри shadow-dom при импорте Jquery в Light-dom.

Index.html

<script src="/jquery.min.js"></script>
</head>
<body>
  <my-component></my-component>
  <div id="test2"></div>
</body>

my-component.tsx

  testfunc(){
    console.log($().jquery);
    console.log($("#test"));
    console.log($("#test2"));
  }
  render() {
    return <div id="test">
            <button onclick={this.testfunc.bind(this)}>asd</button>
           </div>;
  }

Результат testfunc находится здесь: Console results:

Итак, как вы можете видеть - вы уже можете использовать Jquery, просто вставив его в основное приложение. Но есть некоторые ограничения, поскольку вы можете видеть, что у вас есть доступ ко всем элементам DOM из light-dom, но нет из shadow-dom. Вот почему #test не был найден, а # test2 был.

Но интересно отметить, что я также смог загрузить файл внутри этого контейнера # test2 div, который находится в index.html. Просто используя функцию jquery .load из веб-компонента.

$( "#test2" ).load( "/index.html" );

Все становится немного сложнее, когда вы хотите использовать селектор $ для получения элементов внутри веб-компонента (shadow-dom), но для этого нет абсолютно никаких причин: у Stencil есть собственный this.el.shadowRoot.querySelector (), который вы можете использовать внутри компонента или напрямую прикрепить переменную к элементу DOM, например:

  render() {
    return <div ref={el => this.element = el}>
            <button onclick={this.testfunc.bind(this)}>Press Button</button>
           </div>;
  }

Чем вы можете использовать this.element внутри веб-компонента для доступа к div. Но в целом вы также можете попробовать использовать флаг scoped в компонентном декораторе. Чем обычно вы можете использовать все из «легкого дома», потому что нет такой жесткой изоляции:

    @Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true ---> instead of this
  scoped: true ---> try this
})

Подводя итог: я думаю, что никогда не бывает веской причины использовать эти библиотеки внутри веб-компонента. в общем. Но если вам действительно нужно - это всегда зависит от ваших потребностей и того, чего вы хотите / должны достичь. Трафарет имеет несколько действительно полезных и хороших встроенных функций.

0 голосов
/ 27 октября 2019

Я бы подумал об использовании трафарета с точностью до наоборот. Создайте свой общий материал в Stencil, а затем в Angular. Например, вы начинаете с простой «кнопки» в качестве веб-компонента в трафарете.

export class CoolestButton {
      render() {
        return <button class="coolest-button"></button>
      }
}

Чем вы создаете другой «выпадающий» веб-компонент, который использует «кнопку» в качестве основы.

export class CoolestDropdown {
      ...
       someDropdownFunctions(){}
      ...
      render() {
        ...
        return [<coolest-button></coolest-button>, ...dropdownSpecific]
      }
}

Чем вы создаете компонент Header, который существует из выпадающих списков.

export class CoolestHeader {
      render() {
        return [
<coolest-dropdown data="NavPoint1,NavPoint2,NavPoint3">Home</coolest-dropdown>, 
<coolest-dropdown data="About-us,Impress">Home</coolest-dropdown>
];
      }

Удивительной особенностью Stencil является то, что вы можете использовать 10000x раз самую крутую кнопку, но она загрузит ее только один раз. Вот почему вложение таких веб-компонентов является абсолютным кодированием сахара. Чем у вас есть действительно сильная библиотека, которую вы можете использовать во всех ваших клиентских проектах. И когда вы пишете свои тесты - каждое клиентское приложение также тестируется, поскольку оно имеет одинаковую базу.

0 голосов
/ 26 октября 2019

Для большинства веб-компонентов я бы не использовал jQuery, так как в любом современном фреймворке манипуляции с dom не нужны, в основном вы просто сосредоточены на функции рендеринга.

Я сделал тест, и после добавления это работает нормальноjquery-зависимость с npm i jquery:

import { Component, h } from '@stencil/core';
import $ from "jquery";

@Component({
    tag: 'app-test'
})
export class AppTest {  
    render() {
        const version = $().jquery;
        return [
            <div>
                jQuery Version: {version}
            </div>
        ];
    }
}
...