vue-slick
vue-slick copied to clipboard
asNavFor not working in vue-slick slider
I want to show the image in slick slider asNaVFor. On selecting image from the 2nd slick slider it will show in the 1st slider. There is break-point after each image and current image is shown on slider-1. Here is my code:
<template>
<app-card
:fullBlock="true"
>
<div class="top-selling-widget">
<slick :options="slickOptions" ref="slickSetting1">
<div v-for="news in newsData" :key="news.id">
<div class="thumbnail mb-2">
<img :src="news.newsSrc" width="100%" height="300" class="img-responsive">
</div>
</div>
</slick>
<slick :options="slickOptions2" ref="slickSetting2">
<div v-for="news in newsData" :key="news.id">
<div class="thumbnail mb-2">
<img :src="news.newsSrc" width="150" height="50px" class="img-responsive">
</div>
</div>
</slick>
</div>
</app-card>
</template>
<script>
import Slick from "vue-slick";
export default {
components: {
Slick
},
computed: {
slickOptions() {
return {
slidesToShow: 1,
slidesToScroll: 1,
arrows: false,
fade: true,
adaptiveHeight: true,
asNavFor: this.$refs.slickSetting2,
rtl: this.$store.getters.rtlLayout
}
},
slickOptions2() {
return {
slidesToShow: 4,
slidesToScroll: 1,
dots: false,
autoplay: true,
speed: 2000,
infinite: true,
cssEase: "linear",
focusOnSelect: true,
asNavFor: this.$refs.slickSetting1,
rtl: this.$store.getters.rtlLayout,
adaptiveHeight: true,
responsive: [
{
breakpoint: 1200,
settings: {
slidesToShow: 3,
slidesToScroll: 1,
}
},
{
breakpoint: 991,
settings: {
slidesToShow: 4,
slidesToScroll: 1,
}
}
]}
}
},
data() {
return {
newsData: [
{
id: 1,
newsSrc:"/static/img/gallery1.jpg",
newsTitle: "#WorldPopulationDay: India Likely to Overtake China by 2022",
newsContent: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s",
likes: "1k",
views: "3k",
comments:"200"
},
{
id: 2,
newsSrc: "/static/img/gallery2.jpg",
newsTitle: "Check status of Mumbai local, long-distance trains as rains continue",
newsContent: "when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries",
likes: "2k",
views: "5k",
comments: "600"
},
{
id: 3,
newsSrc: "/static/img/gallery3.jpg",
newsTitle: "Croatia lowest ranked team in history to reach World Cup final",
newsContent: "It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, ",
likes: "500",
views: "1k",
comments: "300"
},
{
id: 4,
newsSrc: "/static/img/gallery4.jpg",
newsTitle: "Telecom Commission approves net neutrality, new telecom policy",
newsContent: "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old",
likes: "4k",
views: "8k",
comments: "1k"
},
{
id: 5,
newsSrc: "/static/img/gallery5.jpg",
newsTitle: "Vistara orders Boeing, Airbus jets worth $3.1 billion",
newsContent: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s",
likes: "100",
views: "500",
comments: "50"
}
]
}
}
}
</script>
In order for the navigation block to work, it is necessary to declare the CSS classes slider-nav and slider-for directly in the slick attribute. For example:
<slick class="slider-for"
ref="slick"
:options="slickOptions"
@afterChange="handleAfterChange"
@beforeChange="handleBeforeChange"
@breakpoint="handleBreakpoint"
@destroy="handleDestroy"
@edge="handleEdge"
@init="handleInit"
@reInit="handleReInit"
@setPosition="handleSetPosition"
@swipe="handleSwipe"
@lazyLoaded="handleLazyLoaded"
@lazyLoadError="handleLazeLoadError">
Your content for main slide
</slick>
<slick class="slider-nav"
ref="slick"
:options="slickNavOptions"
@afterChange="handleAfterChange"
@beforeChange="handleBeforeChange"
@breakpoint="handleBreakpoint"
@destroy="handleDestroy"
@edge="handleEdge"
@init="handleInit"
@reInit="handleReInit"
@setPosition="handleSetPosition"
@swipe="handleSwipe"
@lazyLoaded="handleLazyLoaded"
@lazyLoadError="handleLazeLoadError">
Navigation slides list
</slick>
You can take an example configuration for slickOptions and slickNavOptions from the documentation: http://kenwheeler.github.io/slick/, Slider Syncing
asNavFor: this.$refs.slickSetting2,
how you fix this?
you use class instead of a ref elements , that is how you fix it . or just follow the instructions on the main slick page
It's important that you use the classes 'slider-for' and 'slider-nav.' I've had the same problem because I was using element IDs.
you use class instead of a ref elements , that is how you fix it . or just follow the instructions on the main slick page
It's works, thanks
Hello everyone, I am using vue-slick-carousel, based on vue-slick, I am trying this with classes and it doesn't work, I would appreciate help.
<div>
<VueSlickCarousel
ref="slider1"
v-bind="settings.first"
class="slider-for"
>
...
</VueSlickCarousel>
</div>
<div v-if="content.length" class="xxs:hidden md:block">
<VueSlickCarousel
ref="slider2"
v-bind="settings.second"
class="row slider-nav"
>
@SerlokPK, I wouldn't use VueSlickCarousel. I found a nasty bug that traps the users' vertical touch on mobile devices. I've filed it in the issues section but got no response, so I moved over to this build of slick because the bug doesn't exist and has more community support anyway.
At any rate, don't use classes, you don't want to classes in Vue wherever possible. This example works for me with two distinct sliders acting as navs for each other:
Slider 1:
<slick-slide
ref="gallery"
:options="topSliderOptions"
@beforeChange="syncSliders"
>
<div v-for="(slide, index) in scopedData" :key="index">
...
</div>
</slick-slide>
Slider 2:
<slick-slide
ref="featureList"
:options="bottomSliderOptions"
@beforeChange="syncSliders"
>
<div v-for="(slide, index) in scopedData" :key="index">
...
</div>
</slick-slide>
Options:
data() {
return {
topSliderOptions: {
slidesToShow: 1,
arrows: true,
asNavFor: this.$refs.featureList,
},
bottomSliderOptions: {
slidesToShow: 1,
arrows: false,
asNavFor: this.$refs.gallery,
}
}
}
onBeforeChange Method:
methods: {
syncSliders(currentPosition, nextPosition) {
this.$refs.gallery.next()
this.$refs.featureList.next()
}
}
Hope this is helpful for others.
Автор библиотеки предлагает использовать референции для взаимодействия со слайдерами, как это показано, например, здесь: https://gs-shop.github.io/vue-slick-carousel/#/example/as-nav-for
Но, как сказано в официальной документации по Vue здесь: https://ru.vuejs.org/v2/guide/components-edge-cases.html
$refs заполняются только после того, как компонент был отрисован, и они не реактивны. И что следует избегать доступа к $refs из шаблонов или вычисляемых свойств!
Следовательно asNavFor и не будет работать, так как доступ к референции связанного слайдера будет невозможен, так как этот слайдер может быть ещё вообще не инициализирован на странице!
В данном случае используется неправильный подход манипулированием связанными слайдерами, предложенный автором пакета.
Вариант mattkaye работает.
Seeman13
mattkaye А что это за вариант, не подскажешь ??
Пример компонента:
<vue-slick-carousel
ref="slider-big"
v-bind="{
fade: true,
responsive: [{
breakpoint: 640,
settings: {
dots: true
}
}]
}"
@beforeChange="syncSliders"
>
<div v-for="(image, index) in images" :key="index">
<img :src="`/images/${image}`" alt="">
</div>
</vue-slick-carousel>
Второй слайдер:
<vue-slick-carousel
:class="'slider-thumb'"
ref="slider-thumb"
v-bind="{ slidesToShow: 5 }"
:focusOnSelect="true"
@beforeChange="syncSliders"
>
<div v-for="(image, index) in images" :key="index">
<img :src="`/images/thumbs/${image}`" alt="">
</div>
</vue-slick-carousel>
Script:
export default {
name: 'Images',
async asyncData ({ $axios, error }) {
try {
const images = await $axios.$get('api/getImages')
return { images }
} catch (e) {
error({ statusCode: 404, message: 'Страница не найдена!' })
}
},
methods: {
syncSliders(currentPosition, nextPosition) {
this.$refs['slider-big'].goTo(nextPosition)
this.$refs['slider-thumb'].goTo(nextPosition)
}
}
}
Seeman13
mattkaye А что это за вариант, не подскажешь ??
Пример компонента:
<vue-slick-carousel ref="slider-big" v-bind="{ fade: true, responsive: [{ breakpoint: 640, settings: { dots: true } }] }" @beforeChange="syncSliders" > <div v-for="(image, index) in images" :key="index"> <img :src="`/images/${image}`" alt=""> </div> </vue-slick-carousel>Второй слайдер:
<vue-slick-carousel :class="'slider-thumb'" ref="slider-thumb" v-bind="{ slidesToShow: 5 }" :focusOnSelect="true" @beforeChange="syncSliders" > <div v-for="(image, index) in images" :key="index"> <img :src="`/images/thumbs/${image}`" alt=""> </div> </vue-slick-carousel>Script:
export default { name: 'Images', async asyncData ({ $axios, error }) { try { const images = await $axios.$get('api/getImages') return { images } } catch (e) { error({ statusCode: 404, message: 'Страница не найдена!' }) } }, methods: { syncSliders(currentPosition, nextPosition) { this.$refs['slider-big'].goTo(nextPosition) this.$refs['slider-thumb'].goTo(nextPosition) } } }Seeman13 mattkaye А что это за вариант, не подскажешь ??
very nice! work!
Good