vue使用Swiper做轮播图时,浏览器窗口变化,图片跟着变化实现

您所在的位置:网站首页 轮播图大小不随浏览器页面的增大而变化吗为什么 vue使用Swiper做轮播图时,浏览器窗口变化,图片跟着变化实现

vue使用Swiper做轮播图时,浏览器窗口变化,图片跟着变化实现

2023-10-03 13:25| 来源: 网络整理| 查看: 265

首先轮播图是这样的:

 

 很美好,都显示出来了,但是当我缩小浏览器窗口时:

 图片显示不全,即使我外面设置了等比例缩小,它里面的图片尺寸还是根据原来的尺寸不变化。

下面解决方法1:

HTML部分:

js部分,图片以数组方式传入

data() { return { imgList: ["http://we-teach.humianyuan.cn/home1.png", "http://we-teach.humianyuan.cn/home2.png", "http://we-teach.humianyuan.cn/home3.png" ], Swiper: null, }

css部分:

.lb_home1{ /* 这里是一个技巧,设置高度为0,再设置padding-bottom百分比, 此时高度就是父元素高度的百分比,用来设置自适应 */ height: 0%; width: 100%; padding-bottom: 50%; background-color: black; } /* 设置图片大小,100%,让图片都显示出来 */ .lb_home1 img{ width: 100%; height: 100%; }

此时看一下结果:

 

 你以为没变化吗,其实已经改变了,只是因为没刷新,所以我自己上网找了别人说的什么几把玩意,说调一下update,resize一下,可是这些几把方法不适合我,没有用,swiper不会自动刷新,看了官方文档,用了它推荐的几把方法也不起效果。

最后一气之下,自己按了F5,

 达到了我想要的结果,那就自己实现刷新了,vue有个provide方法,可以实现reload注入,实现局部刷新。

在app.vue下

 

 实现该方法注册,那么在其他组件都可以用这个方法了,用之前必须注入

 然后实时监听窗口onresize,就可以刷新了,下面是全部代码:

APP.vue:

import Public_Nav from 'components/content/nav/Public_Nav.vue' export default { name: 'App', //给全局注册一个reload,需要使用时就注入该方法 provide(){ return{ reload:this.reload } }, data() { return {isRouterAlive:true} }, methods: { reload(){ this.isRouterAlive = false; this.$nextTick(function(){ this.isRouterAlive = true; }) } }, components:{ Public_Nav } } /* @import 'https://at.alicdn.com/t/font_2391663_8sx9tzlzzhl.css'; */ /* #app{ overflow: hidden; } */

自己封装的Swiper

import Swiper from 'swiper'; //轮播 export default { name: 'HomeSwiper', inject: ['reload'], data() { return { imgList: ["http://we-teach.humianyuan.cn/home1.png", "http://we-teach.humianyuan.cn/home2.png", "http://we-teach.humianyuan.cn/home3.png" ], Swiper: null, } }, methods: { initMySwiper() { let mySwiper = this.Swiper = new Swiper(this.$refs.home_swiper, { // direction:'vertical', loop: true, // 循环模式选项 width: window.innerWidth * 0.9 * 0.65, //分页器 scrollbar: { el: '.swiper-scrollbar', draggable: true, }, autoplay: { delay: 2000, disableOnInteraction: false, //用户触摸后静止关闭 } }) } }, mounted() { this.initMySwiper(); window.onresize = () => { this.reload()//窗口变化实时刷新 } }, } .lb_home1{ /* 这里是一个技巧,设置高度为0,再设置padding-bottom百分比, 此时高度就是父元素高度的百分比,用来设置自适应 */ height: 0%; width: 100%; padding-bottom: 50%; /* background-color: black; */ } /* 设置图片大小,100%,让图片都显示出来 */ .lb_home1 img{ width: 100%; height: 100%; }

测试结果:

 

 

 

 大功告成!

第二种方法设置样式还是要用到reload注入,只不过控制图片样式是通过背景图片方式:

import Swiper from 'swiper'; //轮播 export default { name: 'HomeSwiper', inject: ['reload'], data() { return { imgList: ["http://we-teach.humianyuan.cn/home1.png", "http://we-teach.humianyuan.cn/home2.png", "http://we-teach.humianyuan.cn/home3.png" ], Swiper: null, } }, methods: { initMySwiper() { let mySwiper = this.Swiper = new Swiper(this.$refs.home_swiper, { // direction:'vertical', loop: true, // 循环模式选项 width: window.innerWidth * 0.9 * 0.65, //分页器 scrollbar: { el: '.swiper-scrollbar', draggable: true, }, autoplay: { delay: 2000, disableOnInteraction: false, //用户触摸后静止关闭 } }) } }, mounted() { this.initMySwiper(); window.onresize = () => { this.reload() } }, } .lb_home1 { height: 0%; width: 100%; padding-bottom: 50%; background: url('http://we-teach.humianyuan.cn/home1.png') no-repeat; background-size: 100%;//让图片都显示出来 } .lb_home2 { height: 0%; width: 100%; padding-bottom: 50%; background: url('http://we-teach.humianyuan.cn/home2.png') no-repeat; background-size: 100%; } .lb_home3 { height: 0%; width: 100%; padding-bottom: 50%; background: url('http://we-teach.humianyuan.cn/home3.png') no-repeat; background-size: 100%; }

 最后测试结果和上面一样,用都说好,就不展示了。

 

----------------------------------3月9日第二次更新--------------------------------

上面那种方法是通过mouted加window.resize进行实时监听刷新的,但是实际应用中我们要做的是局部刷新,所以需要在router-view加keepalive属性。

一旦加上keepalive属性,mouted就不销毁了。原来的vue会在页面切换就销毁,然后重新执行渲染mounted,但是有时候我们需要记录我们之前在这个页面做的一些操作,比如点击了某样东西,这个东西变色了,加了keepalive之后,跳转到其它页面,再切回来,这个东西还是原来变色的那种样式。

但是keppAlive在带来方便的同时也带来了不会重复mounted,需要手动F5按刷新才有效,下面就是页面加了keepAlive属性后,轮播图不会刷新的样子,因为虽然有检测到窗口变化,但是由于keppAlive属性,reload函数不起作用。

 

 所以我们此时reload函数失去作用。

所以接下来我想出了第二个方法,就是在检测到窗口变化时实时初始化Swiper,例如下面:

window.onresize=()=>{ this.initMySwiper()//自己封装的初始化函数,窗口变化时就初始化 }

缩小窗口后,得到的是想要的结果:

 但是随之而来的另一个问题是,监听窗口变化这个window.resize这个函数会在窗口发生变化时触发执行,有时候还触发了不止一次,那么重复初始化Swiper之后,它会创建多个实例对象,且不会销毁,看起来切换轮播图的大小虽然没变,但是速度变得是原来的几倍,因为实例化了很多个对象,多个对象在不同时间执行,串在一起时就像开高铁一样快得惊人。

所以有了问题,我们就得解决问题,解决方案那就是:

(1)在创建新的Swiper实例化对象之前先判断上一个是否销毁;

(2)在销毁对象时,判断是否为当前的Swiper实例化对象。

翻译为更加形象一点就是:吃面包的故事。

每天起床第一件事就是吃面包和买面包:

(1)吃面包:判断今天吃的面包是否是今天买的?

(2)买面包:判断昨天的面包吃了没有?

总结起来就是,今天面包今天买,今天吃。每天要吃的面包,每天买,每天吃完。

所以翻译代码为:

data() { return { Swiper: null,//保存当前的Swiper isReload: false, oldSwiper:null//要销毁的Swiper } }, methods: { initMySwiper() { let mySwiper; return mySwiper = this.Swiper = new Swiper(this.$refs.home_swiper, { // direction:'vertical', loop: true, // 循环模式选项 width: window.innerWidth * 0.9 * 0.65,//可以修改宽度 //分页器 scrollbar: { el: '.swiper-scrollbar', draggable: true, }, autoplay: { delay: 2000, disableOnInteraction: false, //用户触摸后静止关闭 } }) } }, mounted() { this.oldSwiper = this.initMySwiper();//初始化时,把刚刚实例化产生的Swiper保存在oldSwiper中 console.log("新老swiper:"+(this.oldSwiper==this.Swiper)) window.onresize = () => { console.log("新老swiper:"+(this.oldSwiper==this.Swiper)) //销毁的是否为当前对象 if(this.oldSwiper==this.Swiper){ this.Swiper.destroy(); console.log("destroy"); this.Swiper = null;//摧毁Swiper之后赋值空 } //判断上一个对象是否销毁了,销毁了才能创建新对象,计时器加不加都可以 setTimeout(() => { if(this.Swiper==null){ this.oldSwiper=this.initMySwiper(); console.log("初始化swiper") } }, 10); console.log("resize") } console.log("mounted") }, }

 ---------------------------3月10日第三次更新------------------------------------

上面那种方案是组件处于keepalive情况下的,但是有一个问题,就是mouted函数只会触发一次了,因为保持了keepalive属性;当我们退出页面重进后,窗口实时监听就会失效,此时我们应该把监听窗口变化的函数写在activated

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3