Swiper - после первого цикла первый элемент отображается неправильно, но данные верны - PullRequest
0 голосов
/ 23 марта 2019

Я использую фреймворк Swiper , чтобы получить функциональность слайдера в Vue. Все работает нормально, за исключением того, что он показывает мне неправильный элемент, если я фильтрую свои данные и после первого цикла заканчивается после прокрутки. Фильтр возвращает правильные элементы, но отображенный первый элемент неправильный.

То, что я обнаружил, было то, что, только если я скатился "вниз". Если я скользю "вверх". Тогда все работает нормально.

Я думаю, что проблема с обновлением. Я хотел бы обновить его, прежде чем вернуть отфильтрованные данные в геттер, но я не знаю, как я могу ссылаться на мой экземпляр swiper? Но тогда идея vuex исчезает, потому что vuex не должен ничего знать о внешнем интерфейсе.

Это мой метод получения vuex, который фильтрует мои данные (всегда возвращает правильные данные):

  filterByCategory(state, getters, rootState) {
      if (rootState.shared.selectedCategory !== 'All') {
        return state.items.filter(
          item => crypto.decrypt(item.category) === rootState.shared.selectedCategory,
        );
      }
      return state.items.filter(item => item.title.toLowerCase().indexOf(getters.filters.searchString.toLowerCase()) >= 0);
    },

Я использую mapGetter для вычисления данных следующим образом: ...mapGetters('data', ['filterByCategory']),

Это компонент, который отображает слайды (первый слайд продукта отображается неправильно):

  <swiper
    ref="productSlider"
    :options="swiperOptions"
    class="product-slider"
    @slideChange="onSlideChange"
  >
    <product-slide
      v-for="item in items"
      :key="item.id"
      :item="item"
    /> 
    <div
      slot="pagination"
      class="product-slider__pagination"
    />
  </swiper>

А это мои data() и способы обновления свайпера:

props: {
    items: {
      type: Array,
      default: () => [],
      required: true,
    },
  },
  data() {
    const self = this;
    return {
      swiperOptions: {
        direction: 'vertical',
        loopedSlides: 1,
        spaceBetween: 30,
        slidesPerView: 1,
        effect: 'fade',
        loop: true,
        mousewheel: {
          invert: false,
        },
        // autoHeight: true,
        pagination: {
          el: '.product-slider__pagination',
          clickable: true,
          dynamicBullets: true,
          dynamicMainBullets: 1,
        },
      },
    };
  },
  computed: {
    swiper() {
      return this.$refs.productSlider.swiper;
    },
  },
  updated() {
    if(this.swiper) {
      this.swiper.update();
      console.log('swiper-updated');
    }
  },
  beforeDestroy() {
    if(this.swiper) {
      console.log('swiper-before-destroy');
      this.swiper.destroy();
    }
  },
  watch: {
    items(newValue, oldValue) {
      if (this.swiper) {
        console.log(this.items);
        this.$nextTick(() => {
          this.swiper.update();
        });
      }
    },
  },
  methods: {
    onSlideChange() {
      console.log('Slide did change');
    },
  }

Я просто не могу понять, что я делаю неправильно. Я попытался также использовать observer: true, чтобы передать обновление в фреймворк для обработки. Даже тогда это не работает. Я перепробовал все, что смог найти в Google, но ничего не работает. Я хочу знать, если это я или ошибка в рамках. Любая помощь очень ценится.

Я создал простой CodePen пример.

1 Ответ

0 голосов
/ 25 марта 2019

Я наконец нашел ответ на свой вопрос из этого вопроса Github!

Я сделал следующее:

Я создал show переменную внутри data() и метод reRender() со следующим:

  reRender(){
      this.show = false
      this.$nextTick(() => {
        //re-render start
        this.show = true
        this.swiper.destroy();
        this.$nextTick(() => {
            //re-render end
            this.swiper.update();
        })
      })
    }

И я добавил :v-if="show" к компоненту <swiper></swiper>.

А в наблюдателе я вызываю функцию reRender().

Я не уверен, насколько он корректен, однако сейчас он работает.

...