首先輪播圖是這樣的:
很美好,都顯示出來了,但是當我縮小瀏覽器窗口時:
圖片顯示不全,即使我外面設置了等比例縮小,它里面的圖片尺寸還是根據原來的尺寸不變化。
下面解決方法1:
HTML部分:
<div ref="home_swiper" class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="(item,index) in imgList">
<div class="lb_home1"><img :src="imgList[index]"></div>
</div>
<!-- <div class="swiper-slide">
<div class="lb_home2">2</div>
</div>
<div class="swiper-slide">
<div class="lb_home3">3</div>
</div> -->
</div>
<div class="swiper-scrollbar"></div>
</div>
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:
<template> <div id="app"> <div v-show='this.$route.name=="Brief"?false:true'><Public_Nav></Public_Nav></div> <router-view v-if="isRouterAlive" /> </div> </template> <script> 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 } } </script> <style scoped> /* @import 'https://at.alicdn.com/t/font_2391663_8sx9tzlzzhl.css'; */ /* #app{ overflow: hidden; } */ </style>
自己封裝的Swiper
<template> <div ref="home_swiper" class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide" v-for="(item,index) in imgList"> <div class="lb_home1"><img :src="imgList[index]"></div> </div> </div> <div class="swiper-scrollbar"></div> </div> </template> <script> 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()//窗口變化實時刷新 } }, } </script> <style> .lb_home1{ /* 這里是一個技巧,設置高度為0,再設置padding-bottom百分比, 此時高度就是父元素高度的百分比,用來設置自適應 */ height: 0%; width: 100%; padding-bottom: 50%; /* background-color: black; */ } /* 設置圖片大小,100%,讓圖片都顯示出來 */ .lb_home1 img{ width: 100%; height: 100%; } </style>
測試結果:
大功告成!
第二種方法設置樣式還是要用到reload注入,只不過控制圖片樣式是通過背景圖片方式:
<template> <div ref="home_swiper" class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide" > <div class="lb_home1"></div> </div> <div class="swiper-slide"> <div class="lb_home2"></div> </div> <div class="swiper-slide"> <div class="lb_home3"></div> </div> </div> <div class="swiper-scrollbar"></div> </div> </template> <script> 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() } }, } </script> <style> .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%; } </style>
最后測試結果和上面一樣,用都說好,就不展示了。
----------------------------------3月9日第二次更新--------------------------------
上面那種方法是通過mouted加window.resize進行實時監聽刷新的,但是實際應用中我們要做的是局部刷新,所以需要在router-view加keepalive屬性。
<keep-alive>
<router-view v-if="isRouterAlive" />
</keep-alive>
一旦加上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") }, } </script>
---------------------------3月10日第三次更新------------------------------------
上面那種方案是組件處於keepalive情況下的,但是有一個問題,就是mouted函數只會觸發一次了,因為保持了keepalive屬性;當我們退出頁面重進后,窗口實時監聽就會失效,此時我們應該把監聽窗口變化的函數寫在activated