Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swiper Vue as AsyncComponent #4613

Closed
jan-vodila opened this issue May 27, 2021 · 4 comments
Closed

Swiper Vue as AsyncComponent #4613

jan-vodila opened this issue May 27, 2021 · 4 comments
Labels

Comments

@jan-vodila
Copy link

  • Swiper Version: 6.6.2
  • Platform/Target and Browser Versions: doesn't matter

What You Did

Load swiper as AsyncComponent

Expected Behavior

It should be possible to load Swiper only if needed through defineAsyncComponent method.

Actual Behavior

It throws an error: cannot read property 'value' of undefined because swiperRef is undefined, see:
https://codesandbox.io/s/friendly-shape-0g0k8?file=/src/App.vue

@ahmedgadit
Copy link

same issue facing

"vue": "^3.0.5",
"swiper": "^6.7.1",

Same Error i am getting on if (!swiperRef.value) return;


var SwiperSlide = {
  name: 'SwiperSlide',
  props: {
    tag: {
      type: String,
      default: 'div'
    },
    swiperRef: Object,
    zoom: {
      type: Boolean,
      default: undefined
    },
    virtualIndex: {
      type: [String, Number],
      default: undefined
    }
  },
  setup: function setup(props, _ref) {
    var slots = _ref.slots;
    var eventAttached = false;
    var swiperRef = props.swiperRef;
    var slideElRef = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null);
    var slideClasses = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('swiper-slide');

    function updateClasses(swiper, el, classNames) {
      if (el === slideElRef.value) {
        slideClasses.value = classNames;
      }
    }

    (0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(function () {
      if (!swiperRef.value) return;
      swiperRef.value.on('_slideClass', updateClasses);
      eventAttached = true;
    });

this is the actual code where i am using

Slider Component


<template>
  <div class="slider-pro" id="index-slider">
    <div class="sp-slides">
      <!-- SLIDER STARTS -->
      <swiper :pagination="true" class="mySwiper">
        <div class="sp-slide">
          <swiper-slide>Slide 1</swiper-slide>
        </div>
        <div class="sp-slide">
          <swiper-slide>Slide 2</swiper-slide>
        </div>
        <div class="sp-slide">
          <swiper-slide>Slide 3</swiper-slide>
        </div>
        <div class="sp-slide">
          <swiper-slide>Slide 4</swiper-slide>
        </div>
        <div class="sp-slide">
          <swiper-slide>Slide 5</swiper-slide>
        </div>
      </swiper>
      <!-- END OF SLIDER -->
    </div>
  </div>
</template>


<script>
// Import Swiper Vue.js components
import { Swiper, SwiperSlide } from 'swiper/vue';

// Import Swiper styles
import 'swiper/swiper.min.css';

import "swiper/components/pagination/pagination.min.css"

// import Swiper core and required modules
import SwiperCore, {
  Pagination
} from 'swiper/core';

// install Swiper modules
SwiperCore.use([Pagination]);


export default {
  components: {
    Swiper,
    SwiperSlide,
  },
}
</script>

<style scoped>
#index-slider .sp-slide:after {
  background: #050a0d;
  opacity: .8;
  bottom: 0px;
  content: "";
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
}

#app { height: 100% }
html,
body {
  position: relative;
  height: 100%;
}

body {
  background: #eee;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
  font-size: 14px;
  color: #000;
  margin: 0;
  padding: 0;
}

.swiper-container {
  width: 100%;
  height: 100%;
}

.swiper-slide {
  text-align: center;
  font-size: 18px;
  background: #fff;

  /* Center slide text vertically */
  display: -webkit-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
}

.swiper-slide img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
</style>

This is my home page for sliders


<template>
  <Header>
    <Slider />
  </Header>
  <Feature />
  <AboutUs />
  <Testimonials />
  <Numbers />
</template>

<style scoped>
.row {
  max-width: 1270px;
  width: 100%;
}
.header .logo {
  margin-top: 5px;
  padding-left: 15px;
  padding-bottom: 7px;
}
#page-header.about1:after {
  background: #050a0d;
}
</style>

<script>
import Header from '../../components/Header'
import Slider from './components/Slider';
import Feature from './components/Feature';
import AboutUs from './components/AboutUs';
import Testimonials from './components/Testimonials';
import Numbers from './components/Numbers';

export default {
  components: {
    Header,
    Slider,
    Feature,
    AboutUs,
    Testimonials,
    Numbers,
  }
}
</script>

Thanks in advance

@ahmedgadit
Copy link

Solved:

<div class="sp-slide">
          <swiper-slide>Slide 1</swiper-slide>
        </div>

changing this into


    <swiper-slide>
          <div class="sp-slide">
          Slide 1
           </div>
  </swiper-slide>

@jan-vodila
Copy link
Author

Hello @nolimits4web,

thanks for a fix, however it fixes the issue only partially. I have updated the swiper version and tested it here: https://codesandbox.io/s/frosty-voice-dsfjb and the problem is, that you are not able to move to another slide until you resize the browser window. The issue is that swiper-slide doesn't get the width style property after swiper is initialized.

We should find a way to wait for swiper-slide being loaded and then initialize swiper itself.

@nolimits4web
Copy link
Owner

@jan-vodila just enable observer:

<swiper observer>
 ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants