我有一个VUE 2旋转木制组件,使用v-for
生成幻灯片子组件。使用v-show
显示幻灯片并隐藏。我无法在工作幻灯片之间获得CSS transition
s。
我尝试包装<transition>
中的幻灯片,但mode=out-in
什么都没做,最终在过渡过程中旋转木马中的两个幻灯片,一个褪色,另一个褪色。当我将幻灯片包装在<transition-group>
中时,CSS transition
S根本不显示,幻灯片仅被替换。
我研究了组件之间的过渡,但是幻灯片是根据API的链接列表生成的,我看不到将动态生成与此解决方案相结合的方法。
这是一个带有问题的JSFIDDLE
如果您不打算交叉图像(即,在任何给定时间点实际上只在屏幕上只有一个图像),则可以重组代码,例如只有一个<Slide>
组件一次渲染。您只需分配一个动态更新的唯一键,例如您的active
滑块组件的数据。
您的模板现在看起来像这样:
<div class="carousel-wrapper" id="promotions">
<transition name="component-fade" mode="out-in">
<!-- Bind image url dynamically, bind key to active index -->
<Slide class="slide" :url="imageUrl" :key="active"></Slide>
</transition>
</div>
imageUrl
只是一个计算属性,它通过索引返回图像URL:
imageUrl() {
return this.list[this.active].url;
}
Slide
组件应像我们需要的那样"愚蠢":在这种情况下,它只是接收动态结合的图像URL,而仅此而已:
<div>
<img :src="url" class="image">
</div>
注意:
- 您应该使用与
active
属性更新的时间间隔相等或短的过渡持续时间。在您的原始代码中,幻灯片循环3s,但过渡效果设置为4s,导致了真正的Janky Transitions - 如果您想要一个Crossfade动画,该解决方案将更加复杂。
这是概念验证示例:
Vue.component('Slide', {
template: `
<div>
<img :src="url" class="image">
</div>`,
props: ['url']
});
Vue.component('component-2', {
template: `<div>
<p>component 2</p>
</div>`
});
new Vue({
el: '#example',
template: `
<div class="carousel-wrapper" id="promotions">
<transition name="component-fade" mode="out-in">
<Slide class="slide" :url="imageUrl" :key="active">
</Slide>
</transition>
</div>`,
data() {
return {
list: [{
url: 'https://static.pexels.com/photos/572741/pexels-photo-572741.jpeg'
},
{
url: 'https://static.pexels.com/photos/575739/pexels-photo-575739.jpeg'
},
{
url: 'https://static.pexels.com/photos/576832/pexels-photo-576832.jpeg'
}
],
active: 0
}
},
computed: {
numberOfSlides() {
return this.list.length - 1
},
imageUrl() {
return this.list[this.active].url;
}
},
created() {
this.rotate()
},
methods: {
moveSlide(event) {
this.active = event.srcElement.dataset.slide
this.list.forEach(el => {
el.active = false
})
this.list[event.srcElement.dataset.slide].active = true
},
rotate() {
if (this.active < this.numberOfSlides) {
this.active = this.active + 1
} else {
this.active = 0
}
let _this = this
setTimeout(_this.rotate, 3000)
}
}
});
.carousel-wrapper {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
}
.carousel {}
.dots {
max-width: 100%;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
position: absolute;
bottom: 2em;
z-index: 1;
}
.dot {
height: 1em;
width: 1em;
margin: 0 1em 0 1em;
border-radius: 50%;
background-color: red;
}
.component-fade-enter-active,
.component-fade-leave-active {
transition: opacity 1s ease;
}
.component-fade-enter,
.component-fade-leave-to {
opacity: 0;
}
.slide {
width: 100%;
height: 650px;
}
.image {
max-width: 100%;
max-height: 650px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="example">
</div>
我认为这是因为您不需要使用v-show
。
您应该只使用<transition name="slide-fade"><slides></slides></transition>
,然后在CSS中定义过渡。
您应该看到此文档,对我有用。