Stenciljs: сторонняя библиотека карусели уничтожается, когда я меняю область видимости: 'true' на shadow: 'true'

У меня есть карусель на основе сторонней библиотеки Swiperjs. Проблема в том, что когда я использую scope: true, у меня нет проблем, и он работает нормально, однако, когда я пытаюсь настроить компонент с shadow: true, он уничтожается, и ничего не работает. Я использую библиотеку следующим образом:

...
import  Swiper, { SwiperOptions }  from 'swiper';
...

@Component({
  tag: 'my-swiper-slider',
  styleUrl: './styles.css',
  assetsDirs: ['assets'],
  shadow: true,
})
export class Carousel {
@Prop() options: SwiperOptions = {
    slidesPerView: 3,
    spaceBetween: 40,
    autoplay: false,
    loop: false,
    autoHeight: true,
    breakpoints: {
      640: {
        slidesPerView: 5,
        spaceBetween: 20,
      },
      768: {
        slidesPerView: 5,
        spaceBetween: 40,
      },
      1024: {
        slidesPerView: 5,
        spaceBetween: 50,
      },
    }
  }
 private setSwiper() {
    this.swiper = new Swiper('.swiper-container', this.options);
  }

  componentDidLoad() {
    this.setSwiper();
  }

  render() {

    return (
      <Host class={{"container": true}}>

        <PrevBtn
          goBack={this.goBack.bind(this)} />

        <div class="swiper-container">
          <div class="swiper-wrapper">
            <slot></slot>
          </div>
        </div>

        <NextBtn
          goForward={this.goForward.bind(this)} />

      </Host>
    );
  }
}

По какой-то причине, когда я настраиваю компонент как «shadow: true», он не может получить доступ к трафарету, или я так думаю.


person Ricky    schedule 17.02.2020    source источник


Ответы (1)


Когда вы включаете shadow, все дочерние элементы компонента будут перемещены в его теневую DOM и, следовательно, будут скрыты как детали реализации. Это означает, что вы больше не сможете найти свой контейнер с помощью селектора запросов .swiper-container.

Однако конструктор Swiper также может принимать элемент HTML вместо селектора запроса, поэтому вместо этого вы можете использовать ref в элементе контейнера:

@Component({ tag: 'my-swiper-slider', shadow: true })
export class Carousel {
  @Prop() options: SwiperOptions;

  @State() swiper?: Swiper;
  @State() swiperContainerRef?: HTMLDivElement;

  componentDidLoad() {
    if (this.swiperContainerRef) {
      this.swiper = new Swiper(this.swiperContainerRef, this.options);
    }
  }

  render() {
    return (
      <Host>
        <div ref={el => this.swiperContainerRef = el)} />
      </Host>
    );
  }
}

Ссылка контейнера всегда должна быть доступна в ловушке componentDidLoad жизненного цикла, но вы также можете использовать _ 7_, чтобы дождаться его доступности.

person Simon Hänisch    schedule 18.02.2020
comment
Привет, Саймон, спасибо за ответ. Я получаю следующее предупреждающее сообщение, и оно не работает: изменение состояния / опоры во время componentDidLoad (), это вызывает дополнительные повторные отрисовки, попробуйте настроить componentWillLoad (). Но когда я изменяю привязку жизненного цикла, я получаю ошибка: не удается прочитать свойство $ hostElement $ неопределенного - person Ricky; 18.02.2020
comment
Да, ссылка доступна только после первоначального рендеринга (когда был создан элемент DOM). Вот почему в этом случае действительно требуется повторный рендеринг. Так что можете смело игнорировать предупреждение. - person Simon Hänisch; 20.02.2020