Skip to content

Instantly share code, notes, and snippets.

@edwardlorilla
Created May 14, 2021 15:24
Show Gist options
  • Save edwardlorilla/1c5db1cd51ede0a86ba16e5106c66dde to your computer and use it in GitHub Desktop.
Save edwardlorilla/1c5db1cd51ede0a86ba16e5106c66dde to your computer and use it in GitHub Desktop.
Vue seamless carousel effect (Marquee) using transition
<template id="swiper">
<div class="Sweiper">
<slot></slot>
</div>
</template>
<template id="Sweiper-item">
<transition>
<div class="Sweiper-item" v-show="isShow">
<slot></slot>
</div>
</template>
<div id="app">
<Sweiper v-model="selected">
<Sweiper-item name="item1">
<div class="item">
<img :src="getImg('01')" alt="">
</div>
</Sweiper-item>
<Sweiper-item name="item2">
<div class="item">
<img :src="getImg('02')" alt="">
</div>
</Sweiper-item>
<Sweiper-item name="item3">
<div class="item">
<img :src="getImg('03')" alt="">
</div>
</Sweiper-item>
</Sweiper>
</div>
Vue.component('Sweiper', {
template: "#swiper",
data() {
return{
current:''
}
},
props:{
value:{
type:String,
default:""
},
},
mounted(){
this.names=this.$children.map(child=>{
return child.name
});
this. showImg();
this. paly()
},
methods:{
showImg(){
this.current=this.value||this.$children[0].name;
this.$children.map(vm=>{
vm.selected=this.current
})
},
paly(){
//Adjust the picture every time in the carousel
this.timer=setInterval(()=>{
//indexOf returns the position of the first occurrence of a specified string
const index=this.names.indexOf(this.current);
let newIndex=index+1;
//Be strict
if (newIndex===this.names.length){
newIndex=0;
}
this.$emit("input",this.names[newIndex])
},3000)
}
},
watch:{
//Monitor the value value, change selected if it changes
value(){
this. showImg()
}
},
beforeDestroy() {
//Before the actual column is destroyed
clearInterval(this.timer)
}
})
Vue.component('SweiperItem', {
template:"#Sweiper-item",
data(){
return{
selected:""
}
},
props:{
name:{
type:String,
required:true
},
},
mounted(){
},
computed:{
isShow(){
return this.selected===this.name;
}
}
})
new Vue({
data() {
return {
selected: "item1",
}
},
methods:{
getImg(url){
return "https://via.placeholder.com/200?text=" + url
},
},
mounted(){
}
}).$mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
.Sweiper{
/*border: 1px solid black;*/
width: 100%;
overflow: hidden;
margin: 0 auto;
position: relative;
}
.v-enter-active,.v-leave-active{
transition: all 1s linear;
}
.v-leave-to{
transform:translate(-100%);
}
.v-enter{
transform: translate(100%);
}
.v-enter-active{
position: absolute;
top:0;
left: 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment