#javascript #vuejs2 #nuxt.js #flickity
Вопрос:
Я пытаюсь связать свои собственные пользовательские кнопки с вращающейся каруселью в приложении nuxt. Мой родительский компонент установил для prop значение direction
по умолчанию left
.
<CarouselBase class="w-screen carousel" :direction="direction">
<items/>
</CarouselBase>
data() {
return {
direction: 'left',
},
Это код для моего компонента карусели.
<template>
<ClientOnly>
<Flickity
ref="flickity"
:key="keyIncrementer"
class="carousel"
:class="{ 'carousel--active': active }"
:options="computedOptions"
>
<slot />
</Flickity>
</ClientOnly>
</template>
<script>
export default {
name: 'BaseCarousel',
props: {
direction: {
type: String,
default: '',
},
},
mounted() {
if (this.direction === 'right') {
this.$refs.flickity.next()
} else if (this.direction === 'left') {
this.$refs.flickity.previous()
}
},
}
У меня есть этот файл vue-flickity.js
в папке плагинов
import Vue from 'vue'
import Flickity from 'vue-flickity'
Vue.component('Flickity', Flickity)
Я получил это сообщение об ошибке =>
Cannot read properties of undefined (reading 'previous')
Я не знаю, как это исправить…
Комментарии:
1. Почему бы вам не попробовать импортировать Flickity из ‘vue-flickity’ прямо в свой компонент вместо плагина и добавить его в свойство «компоненты»? Потому что до сих пор похоже, что Flickity по какой-то причине не извлекается из плагина.
2. Что вы на самом деле пытаетесь здесь сделать? Проведите ползунком по
mounted()
экрану ? Не следует ли вам использовать метод с a@click
, как в документах? Какой смысл скользить напрямую, когда компонент все равно смонтирован?3. @StasParshin это не работает, потому что пакет не обрабатывает SSR и просто вылетает. Мы выяснили это в одном из предыдущих вопросов автора.
4. Я не хочу сразу прокручивать ползунок на монтируемом, но я инициализировал его «влево» вместо пустой строки ( «» ), чтобы увидеть, что происходит, когда реквизит «слева», по очень простой причине, по которой сейчас я не знаю, как сделать повторное вращение карусели, когда реквизит меняет значение. В любом случае, теперь я только что попробовал использовать @click, как в документах, и получаю то же сообщение об ошибке.
5. На самом деле вам не нужно ничего инициализировать здесь. Внутреннее состояние карусели будет обрабатывать
previous
next
шаги и для вас. Вам не нужно заставлять его перерисовывать ни то, ни другое. Вы можете использовать свои Vue devtools, настроить элемент$vm0
и вручную переключить его, он будет правильно перемещаться. Можете ли вы отредактировать свой вопрос с помощью того, что вы пробовали до сих пор?
Ответ №1:
flickity
Ссылка на шаблон еще не доступна в mounted
крючке, как <Flickity>
показано в следующем цикле.
Дождитесь следующего цикла отрисовки с $nextTick()
обратным вызовом, прежде чем обращаться к ссылке шаблона в mounted()
:
export default {
async mounted() {
// wait until next render cycle for refs to be available
await this.$nextTick()
if (this.direction === 'right') {
this.$refs.flickity.next()
} else if (this.direction === 'left') {
this.$refs.flickity.previous()
}
},
}
Комментарии:
1. Я попробовал вашу демонстрационную версию, ваша карусель использует кнопки, предоставляемые flickity. Я прокомментировал весь асинхронный крючок с открытым ртом, и он работал так же. Похоже, что направляющая опора ничего не делает.
2. @Maxime не уверен, где вы видели, что вам все равно нужна направляющая опора. Как я уже говорил вам, просто используйте кнопки с
@click
событием, как в документации.3. @kissu Я сделал, как в документации, избавился от опоры направления.
4. @Maxime Да. Этот вопрос был о том, почему
this.$refs.flickity
не был определен вmounted
крючке. Не об использовании пользовательских кнопок илиdirection
реквизита, которые находятся в отдельных ваших вопросах.
Ответ №2:
Наличие карусели в качестве компонента, подобного этому
<template>
<ClientOnly>
<Flickity ref="flickity">
<slot />
</Flickity>
</ClientOnly>
</template>
export default {
name: 'BaseCarousel',
}
и использую его в своем указателе с помощью моих собственных пользовательских кнопок
<template>
<CarouselBase ref="flickityIndex">
<items for the carousel/>
</CarouselBase>
<button @click="previous">Custom Previous Button</button>
<button @click="next">Custom Next Button</button>
</template>
export default {
methods: {
next() {
this.$refs.flickityIndex.$refs.flickity.next();
},
previous() {
this.$refs.flickityIndex.$refs.flickity.previous();
}
}
}
При следующем или предыдущем вызове необходимо связаться flickity
и с тем, и с другим $refs
.