工作中遇到一个需求,要求做一个轮播图,很常见的轮播图:例如7张图 1 2 3 4 5 6 7 第一次显示4张 1234 … 2345 … 3456 …4567 … 5671 … 6712 … 几张图片显示的时候长宽高一致。
在这里插入图片描述

刚开始想到用 element ui 但是看了一下,element ui的旋转木马走马灯 和我的需求样式不匹配,所以决定用 swiper
Vue安装依赖Swiper:npm install swiper@3.4.1 --save-dev
引用组件:main.js中:import Swiper from 'swiper'; import 'swiper/dist/css/swiper.min.css';
我用的swiper3;swiper6的.css文件位置有改变,详情请度娘

下面是引入轮播图的页面

我的轮播图图片是axios一步请求得来的,刚开始用的v-for 会发现有bug,轮播过程中轮播到某一部分图片会出现死循环。以下是当时问题代码

<div class="swiper-wrapper" >
	<div class="swiper-slide" v-if="ZTZLList.length>0" v-for="item in ZTZLList">
		<a :title="item.title" :href="item.url" target="_blank">
			 <img :src="item.src" width="278px" height="90px"  :alt="item.title">           
			  <span class="img_title img-title" style="display: none;">{{item.title}}</span> 
		</a>
	</div>
</div>
<script>
export default{
		name:"home",
		props:{},
		data:function(){
			return {
				ZTZLList:[], 
			}
		},
		filters: {},
		methods:{
			init:async function(){
				var that = this;
				var url = "";
				await this.$axios.get(url).then(res=>{
					if(res.data.code=="0"){
						that.ZTZLList = res.data.data["ZTZL_Info"]
					}else{
						alert("程序后台错误,请联系管理员修复")
					}
				});
		},
		mounted: function() {
			var that = this;
			this.init();
		 	this.$nextTick(function () {
				this.ztzlSwiper=new Swiper('.ztzlSwiper', {
						loopAdditionSlides:10,
				 		loop:true,    // 循环播放
						circular:true,
				 		autoplay: 2000,
				 		autoplayDisableOnInteraction: false,
				 		paginationClickable: true,
				 		observer:true,//修改swiper自己或子元素时,自动初始化swiper
						observeParents:false,//修改swiper的父元素时,自动初始化swiper 
					    slidesPerView:4,   // 一次显示4张图片
				 		loopedSlides:7
				 });
			 });
		},
	}
</script>

百度后发现:Vue更新DOM为异步更新,数据变化后,DOM不会立刻更新,而是等同一事件循环中的所有数据变化完成之后再统一进行视图更新,此时立刻进行swiper初始化,会按照DOM变化前进行初始化。

百度了很多办法:比如加:observer:true,//修改swiper自己或子元素时,自动初始化swiper observeParents:false,//修改swiper的父元素时,自动初始化swiper
比如:this.$nextTick(function () { this.ztzlSwiper=new Swiper('.ztzlSwiper', { }) }}
等等 都没有用。。。 也有可能是我用错了。
F12 异步加载内容都加载上了,去掉v-for以后自己手动把循环内容添加上是正常循环的,所以不是我使用方法的问题是vue v-for的问题;所以我的办法是异步加载结束后,拼凑html语句,然后再声明swiper
上代码:

<!-- v-html 解析了标签属性-->
<div class="ztzlSwiper swiper-container"  @mouseover="mouseOver()" @mouseleave="mouseOut()" v-html="ztzlSwiper_wrapper">

</div>
<script>
export default{
		name:"home",
		props:{},
		data:function(){
			return {
				ZTZLList:[], 
				ztzlSwiper_wrapper:"", // 初始化swiper html字符串
			}
		},
		filters: {},
		methods:{
			init:async function(){
				var that = this;
				var url = "";
				await this.$axios.get(url).then(res=>{
					if(res.data.code=="0"){
						that.ZTZLList = res.data.data["ZTZL_Info"]
						// html 字符串拼接
						if(that.ZTZLList.length>0){
							var ztzlHtmlString = "<div class='swiper-wrapper'>";
							for(var i = 0;i<that.ZTZLList.length;i++){
								ztzlHtmlString += "<div class='swiper-slide'><a :title='" +that.ZTZLList[i].title+"' href='"+that.ZTZLList[i].url +"' target='_blank'><img src='"+that.ZTZLList[i].src + "' width='278px' height='90px'  alt='"+that.ZTZLList[i].title+"'>  <span class='img_title img-title' style='display: none;'> "+that.ZTZLList[i].title+"</span>	</a></div>"
							}
							ztzlHtmlString+="</div>"
							that.ztzlSwiper_wrapper = ztzlHtmlString;
						}
					}else{
						alert("程序后台错误,请联系管理员修复")
					}
				});
				
				// 异步加载结束后直接初始化swiper
				this.ztzlSwiper=new Swiper('.ztzlSwiper', {
						loopAdditionSlides:10,
						loop:true,
						circular:true,
						autoplay: 2000,
						autoplayDisableOnInteraction: false,
						paginationClickable: true,
						observer:true,//修改swiper自己或子元素时,自动初始化swiper
						observeParents:false,//修改swiper的父元素时,自动初始化swiper 
					    slidesPerView:4,
						loopedSlides:7
					    
				});
		},
		mounted: function() {
			var that = this;
			this.init();
		},
	}
</script>

这样就成功啦!

Logo

前往低代码交流专区

更多推荐