vue.js輪播圖組件使用方法詳解
之前用jQuery寫過(guò)輪播組件,用的jquery動(dòng)畫實(shí)現(xiàn)的圖片滑動(dòng)效果。這個(gè)組件的滑動(dòng)特效是原生js搭配vue的數(shù)據(jù)綁定實(shí)現(xiàn)的,不依賴其他庫(kù),雖然可以再vue.js中引入swiper,但是引入類庫(kù)的最大的缺點(diǎn)就是冗余代碼太多,所以還是自己寫一個(gè)比較好,簡(jiǎn)單扼要。(ps:組件的寬高設(shè)置還有有點(diǎn)小bug,子組件中需要改為用js動(dòng)態(tài)修改container的寬高,另外可能還有其他地方有不合理之處,歡迎各位批評(píng)指正)
github地址:git@github.com:cainiao222/vueslider-components.git
父組件代碼:
<template>
<div>
<slider :img="img" :width="width" :height="height"></slider>
</div>
</template>
<script>
// import swiper from 'swiper'
import slider from './slider1.vue'
export default {
data(){
return {
img:[{src:require('../assets/slideShow/pic1.jpg'),name:'hehe1'},
{src:require('../assets/slideShow/pic2.jpg'),name:'hehe2'},
{src:require('../assets/slideShow/pic3.jpg'),name:'hehe3'},
{src:require('../assets/slideShow/pic4.jpg'),name:'hehe4'}
],
width:460,
height:250
}
},
components:{
slider:slider
}
}
</script>
子組件代碼:
<template>
<div class="box">
<div @mouseenter="endInterval" @mouseleave="startInterval" class="container">
<div :style="{width:wrap_width+'px',height:wrap_height+'px',left:offset_left+'px'}" class="slider-wrap">
<div class='img' v-for="item in slider_des">
<img :src="item.src" alt="">
</div>
</div>
<div class="bottom">
<ul class="pointContainer">
<li @click="changeIndex(index)" :class="{point:true,active:nowIndex===index}" v-for="(point,index) in length"></li>
</ul>
</div>
<div @click="pre" class="click pre"><</div>
<div @click="next" class="click next">></div>
</div>
</div>
</template>
<script>
export default {
props:{
img:{
type:Array,
default:[]
},
width:{
type:Number,
default:460
},
height:{
type:Number,
default:250
}
},
mounted(){
this.startInterval();
},
data(){
console.log(this.width);
return{
length:new Array(this.img.length),
nowIndex:0,
wrap_width:this.width*(this.img.length+2),
wrap_height:this.height,
offset_left:-this.width,
isTransition:true,
timer:null,
animateFlag:true,
timerAuto:null
}
},
computed:{
slider_des:function () {
var arr=[];
var arr1=arr.concat(this.img);
arr1.push(this.img[0]);
arr1.unshift(this.img[this.img.length-1]);
return arr1;
}
},
methods:{
pre(){
if(this.nowIndex===0){
if(!this.animateFlag){
clearInterval(this.timer);
this.animateFlag=true;
this.offset_left=-(this.length.length)*this.width;
}
this.animate(-this.width,0,function (that) {
that.offset_left=-(that.length.length)*that.width;
});
this.nowIndex=this.img.length-1;
return
}else{
if(!this.animateFlag){
this.animateFlag=true;
clearInterval(this.timer);
this.offset_left=-(this.nowIndex*this.width);
}
this.animate(-(this.nowIndex+1)*this.width,-(this.nowIndex*this.width));
}
this.nowIndex-=1;
},
startInterval(){
this.timerAuto=setInterval(this.next,2000);
},
endInterval(){
// console.log("leave");
clearInterval(this.timerAuto);
},
next(){
if(this.nowIndex===this.length.length-1){
if(!this.animateFlag){
this.animateFlag=true;
clearInterval(this.timer);
this.offset_left=-this.width;
}
this.animate(-(this.length.length)*this.width,-(this.length.length+1)*this.width,function (that) {
that.offset_left=-that.width;
});
this.nowIndex=0;
return
}else{
if(!this.animateFlag){
this.animateFlag=true;
clearInterval(this.timer);
this.offset_left=-(this.nowIndex+2)*this.width;
}
this.animate(-(this.nowIndex+1)*this.width,-(this.nowIndex+2)*this.width);
this.nowIndex+=1;
}
},
animate(start,end,fuc){
var distance=end-start;
var pre_dis=distance/50;
var that=this;
this.timer=setInterval(function () {
that.animateFlag=false;
if(Math.abs(end-that.offset_left)<=Math.abs(pre_dis)){
that.offset_left=end;
if(fuc){
fuc(that);
}
that.animateFlag=true;
clearInterval(that.timer);
that.timer=null;
return
}
that.offset_left+=pre_dis;
},1);
},
changeIndex(index){
clearInterval(this.timer);
this.animate(-(this.nowIndex+1)*this.width,-(index+1)*this.width);
this.nowIndex=index;
}
}
}
</script>
<style scoped>
*{
margin: 0;
list-style: none;
/*height: 0;*/
}
.box{
position: relative;
}
.container{
width: 460px;
height: 250px;
margin: 0 auto;
border: 1px solid #3bb4f2;
overflow: hidden;
left: 0;
top: 0;
position: absolute;
}
.slider-wrap{
/*width: 2760px;*/
/*height: 250px;*/
position: absolute;
/*left: -460px;*/
/*overflow: hidden;*/
top: 0;
}
.transition{
transition: 0.5s;
}
.img{
width: 460px;
height: 250px;
float: left;
display: inline;
}
img{
width: 460px;
height: 250px;
/*float: left;*/
}
.click{
width: 20px;
background-color: rgba(255,255,255,.3);
color: aliceblue;
font-weight: bold;
position: absolute;
height: 40px;
line-height: 40px;
margin-top: -20px;
top: 50%;
cursor: pointer;
}
.pre{
left: 0;
}
.next{
right: 0;
}
.bottom{
position: absolute;
bottom: 0;
width: 100%;
height: 20px;
text-align: center;
}
.pointContainer{
height: 20px;
}
.point{
display: inline-block;
border: 5px solid #eeeeee;
border-radius: 5px;
line-height: 0;
margin-right: 3px;
}
.active{
border: 5px solid #42b983;
}
</style>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue線上部署請(qǐng)求接口報(bào)錯(cuò)net::ERR_CONNECTION_REFUSED
vue線上部署請(qǐng)求接口報(bào)錯(cuò)net::ERR_CONNECTION_REFUSED問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
vue v-on:click傳遞動(dòng)態(tài)參數(shù)的步驟
這篇文章主要介紹了vue v-on:click傳遞動(dòng)態(tài)參數(shù)的步驟,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
詳解Vue的computed(計(jì)算屬性)使用實(shí)例之TodoList
本篇文章主要介紹了詳解Vue的computed(計(jì)算屬性)使用實(shí)例之TodoList,具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08
vue路由跳轉(zhuǎn)攜帶參數(shù)的方式總結(jié)
我們知道在vue中每個(gè)頁(yè)面都需要在路由中聲明,下面這篇文章主要給大家介紹了關(guān)于vue路由跳轉(zhuǎn)攜帶參數(shù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10
解決vue3+vite配置unplugin-vue-component找不到Vant組件
這篇文章主要為大家介紹了vue3+vite配置unplugin-vue-component找不到Vant組件問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
vue兩個(gè)輸入框聯(lián)動(dòng)校驗(yàn)方式(最大值-最小值)
這篇文章主要介紹了vue兩個(gè)輸入框聯(lián)動(dòng)校驗(yàn)方式(最大值-最小值),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10

