完整代码如下:
BannerList.vue文件
<template>
<div class="banner">
<ul class="banner-list">
<template v-for="(item,index) in bannerList">
<!-- 有相同父元素的子元素必须有独特的 key -->
<BannerLi v-bind:key="index" v-bind:li="item" />
</template>
</ul>
<ul class="banner-point-list" v-if="bannerList.length > 1 || bannerList.length <= 4">
<li v-for="(item, index) in bannerList" v-bind:class="{'active':item.active ? 'active' : ''}" v-bind:key="index" v-on:click="changeBanner(index)" ></li>
</ul>
<div v-if="bannerList.length > 1 || bannerList.length <= 4">
<div class="banner-btn banner-prev" v-on:click="changeBanner(prevIndex)"><</div>
<div class="banner-btn banner-next" v-on:click="changeBanner(nextIndex)">></div>
</div>
</div>
</template>
<style type="text/css">
.banner{width:100%;height:300px;position: relative;}
.banner-list{width: 100%;height:100%;overflow: hidden;position: relative;}
.banner-list>li{width:100%;height:100%;position: absolute;top:0;left:0;}
.banner-point-list{position: absolute;width: 128px;bottom: 10%;height: 12px;z-index: 1;text-align: center;left:50%;margin-left:-64px;}
.banner-point-list>li{display: inline-block;width: 12px;height:12px;background-color:#fff;opacity: 0.7;border-radius: 6px;margin: 0 10px;cursor: pointer;}
.banner-point-list>li.active{background-color:#000;}
.banner>div{display:none;}
.banner:hover>div{display:block;}
.banner-btn{width:30px;height:80px;background-color: #000;position: absolute;top: 50%;margin-top: -40px;z-index: 1;color: #fff;font-size: 20px;line-height: 80px;text-align: center;opacity: 0.8;font-weight: lighter;cursor: pointer;-moz-user-select:none;/* 火狐 */ -webkit-user-select:none; /* 谷歌 */ -ms-user-select:none;/* IE */ user-select:none;}
.banner-prev{left:0;border-top-right-radius: 3px;border-bottom-right-radius: 3px;}
.banner-next{right:0;border-top-left-radius: 3px;border-bottom-left-radius:3px;}
</style>
<script type="text/javascript">
// 引入页面所需组件
import BannerLi from "@/components/shareTemp/banner/BannerLi.vue";
export default{
name : "BannerList",
components: {
BannerLi // 包含 Vue 实例可用组件的哈希表。
},
data:function(){
// 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
return {
bannerListArr : [ // 初始数据值
{"name" : "lunbo01", "href":"", "target":"_self","active":false},
{"name" : "lunbo02", "href":"", "target":"_self","active":false},
{"name" : "lunbo03", "href":"", "target":"_self","active":false},
{"name" : "lunbo04", "href":"", "target":"_self","active":false}
],
selectedIndex: 0, // 默认当前选中为0
timeout:null // setTimeout存放变量
}
},
computed:{
// 计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。
// 注意,如果某个依赖 (比如非响应式属性) 在该实例范畴之外,则计算属性是不会被更新的。
bannerList:function(){ // 模板文件循环所需list
var returnArr = this.bannerListArr.slice(); // slice()返回所选元素,不传参则返回所有
returnArr[this.selectedIndex].active = true;
return returnArr;
},
nextIndex:function(){ // 下一个的索引值,小于数组长度,否则为0
var that = this;
return that.selectedIndex >= that.bannerListArr.length - 1 ? 0 : (that.selectedIndex + 1);
},
prevIndex:function(){ // 上一个的索引值,不小于0,否则数组最后一位索引值
var that = this;
return that.selectedIndex <= 0 ? that.bannerListArr.length - 1 : (that.selectedIndex - 1);
}
},
created:function(){
// 在实例创建完成后被立即调用。
// 在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。
// 然而,挂载阶段还没开始,$el 属性目前不可见。
var that = this;
// 在实力创建后调用setTimeout方法执行changeBanner方法,使得banner能够开始切换
that.timeout = setTimeout(function(){
// vm.$options 用于当前 Vue 实例的初始化选项。
// call() 提供新的 this 值给当前调用的函数/方法。
that.$options.methods.changeBanner.call(that);
},3000);
},
methods:{
// 切换数据,用这一个来调,通过computed属性来获取其它所需数据
changeBanner:function(index){
var that = this;
var arrLength = that.bannerList.length;
if(arrLength <= 1) return; // 如果数组长度
// 如果不传index就默认下一个自动切换
if(index === "" || index == null || index == undefined || index < 0 || index >= arrLength){
index = that.selectedIndex + 1;
if(index >= arrLength){
index = 0;
}
}
// clearTimeout() 方法 取消由 setTimeout() 方法设置的 timeout
clearTimeout(that.timeout);
that.bannerList[that.selectedIndex].active = false;
that.bannerList[index].active = true;
that.selectedIndex = index;
// 继续切换下一个banner
that.timeout = setTimeout(function(){
that.$options.methods.changeBanner.call(that);
},3000)
}
}
};
</script>
BannerLi.vue文件
<template>
<li class="banner-li" v-bind:class="{'active':active}" v-bind:style="liStyle">
<!-- <img :src="src" /> -->
<a v-bind:href="liObj.href" v-bind:target="liObj.target" v-bind:style="liObj.styleObj"></a>
</li>
</template>
<style type="text/css">
.banner-li{opacity:0;,z-index: 0;}
.banner-li.active{opacity:1;z-index:1;}
.banner-li>a{display:block;width:100%;height:100%;}
</style>
<script type="text/javascript">
export default{
name : "BannerLi",
props : {
li:Object
},
data:function(){
return {
liStyle:{
// 设置动画时长
"transitionDuration" : "1s"
}
}
},
computed:{
liObj:function(){
var that = this;
// 动态的图片用require进来
var Img = require("../../../assets/imgs/bannerList/" + that.li.name + ".jpg");
return {
href: that.li.href ? that.li.href : "javascript:void(0);",
target : that.li.target ? that.li.target : "_self",
styleObj: {
"backgroundPosition" : "top center",
"backgroundRepeat" : "no-repeat",
"backgroundImage" : "url(" + Img +")"
}
}
},
active:function(){
var that = this;
// 通过切换active来切换banner
return that.li.active ? "active" : "";
}
}
};
</script>
页面效果如下