Есть компонент блока с карточками товара, который принимает в props соответственно массив товаров, и с помощью v-for генерирует карточки товара:
<template>
<div class="block">
<Item
v-for="item in items"
:key="item.id"
:item="item"
:bigImg="item.imgCatalogBig"
:variantsBig="item.variantsBig"
/>
</div>
</template>
<script>
import Item from './Item'
export default {
name: 'Block',
props: {item: Array},
components: {
Item
}
}
</script>
Структура "item" приблизительно такова:
{
"id": 1,
"name": "name",
"imgCatalogBig": "name-catalog-big.jpg",
"imgSmall": ["...jpg.","....jpg","....jpg","....jpg"],
"variantsBig": ["....jpg","....jpg","....jpg","....jpg"],
"title": "TITLE",
}
Из-за того, что изображений товара может не быть, приходится выполнять проверку на их наличие, и если проверка пройдена, через v-for перебирать изображения и рендерить их в карточку товара. Также в карточке товара присутствует "router-link" c динамическими параметрами, в зависимости от отображаемого "item". Приблизительно так выглядит код карточки товара:
<article class="catalog__item" @mouseover="stopAnim" @mouseleave="startAnim">
<div class="catalog__item-img">
<div class="catalog__item-imgBig">
<img
:src="require('@/img/Catalog/'+imgDefault)"
:alt="item.name"
>
</div>
<div
v-if="item.imgSmall.length"
class="catalog__item-variants"
>
<div
v-for="(img, index) in item.imgSmall"
:key="index"
:data-id="index+1"
class="catalog__item-imgSmall"
@click="changeBigImg(index)"
ref="arr"
>
<img :src="require('@/img/Catalog/'+img)" :alt="index">
</div>
</div>
</div>
<div class="catalog__item-content">
<h3 class="catalog__item-title" v-html="item.title"></h3>
<router-link
:to="{name: 'Product', params: {id: item.id}}"
class="catalog__item-btn"
>Подробнее</router-link>
</div>
</article>
По задумке изображения в карточке переключаются автоматически с определенным интервалом, как следствие реализован такой код (вероятно из-за него и проблема):
export default {
name: 'CatalogItem',
props: { item: Object, bigImg: String, variantsBig: Array },
data () {
return {
imgDefault: this.bigImg,
idx: null,
change: null
}
},
methods: {
changeBigImg (index) {
this.imgDefault = this.variantsBig[index]
this.$refs.ar.find(el => el.classList.contains('active')).classList.remove('active')
this.$refs.ar[index].classList.add('active')
this.idx = index
},
stopAnim () {
if (this.variantsBig) {
clearInterval(this.change)
}
},
startAnim () {
if (this.variantsBig) {
this.change = setInterval(() => {
if (this.idx === this.variantsBig.length) {
this.idx = 0
}
this.changeBigImg(this.idx)
this.idx++
}, 2000)
}
}
},
mounted () {
if (this.variantsBig) {
this.$refs.ar[0].classList.add('active')
this.idx = this.$refs.ar.indexOf(this.$refs.ar.find(el => el.classList.contains('active')))
this.startAnim()
}
}
}
Надеюсь код понятен, и сильно вдаваться в подробности не нужно, но из основных моментов:
Для каждого "item" выполняется проверка на наличие вариантов изображений. Если таковы имеются, для них запускается метод, который поочередно из вариантов маленького изображения меняет большое, и присваивает активный класс маленькому. Соответственно, у каждого "item" своя анимация.
Проблема заключается в том, что при нажатии на ссылку "router-link" с параметром id в карточке товара, приложение отображает нужную страницу, но в консоль бьются ошибки присвоения класса. Т.е., при переходе на страницу подробного описания товара компоненты и карточками товара все еще активны, и выполняют каждый свой метод по смене изображения, хотя страница уже не активна. При перезагрузке страницы проблема исчезает.
У меня 2 варианта:
1. Неправильно реализована логика присвоения класса
2. Неправильное использование router
Вот код роутера:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
...,
{
path: '/product/:id',
name: 'Product',
component: () => import('../views/Product'),
props: true
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
}
})
И, соответственно, в main.js:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')