首先輪播圖是這樣的:

很美好,都顯示出來了,但是當我縮小瀏覽器窗口時:

圖片顯示不全,即使我外面設置了等比例縮小,它里面的圖片尺寸還是根據原來的尺寸不變化。
下面解決方法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

