思路
banner部分首先的框架部分在mint里面的Swipe就可以直接拿過來用了,然后就是獲取到數據源,把圖片一個個循環渲染扔進去展示,那么就按著這樣的思路來做了。
開始
打開
項目名》src》components》banner
<template>
<div class="banner clearfix swiper-container" ref="banner">
<mt-swipe :auto="4000">
<mt-swipe-item>1</mt-swipe-item>
<mt-swipe-item>2</mt-swipe-item>
<mt-swipe-item>3</mt-swipe-item>
</mt-swipe>
</div>
</template>
<script>
export default {
name: 'banner',
data() {
return {
}
},
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.banner {
width: 100%;
height: 300px;
}
</style>
直接搬過來(加了點樣式)然后就會是這樣的顯示效果
如此樣子就長出來了,那就搗鼓里面的內容去了。
首先是數據源,我們看一下api的數據長什么樣子(先找到要用的數據先)
打開后找到最下面
用的是chrom瀏覽器,裝上插件JSONView即可格式化json(看得方便,感興趣的可以裝上。)
找到了紅框中需要的數據源了,那么就把它在代碼中獲取過來
打開
項目名》src》components》banner
<script>
// 載入axios
import axios from 'axios'
export default {
name: 'banner',
data() {
return {
}
},
mounted() {
// 調用函數,不然沒調用怎么會有操作
this.fetchData()
},
methods: {
fetchData() {
// 獲取數據
axios.get('https://zhihu-daily.leanapp.cn/api/v1/last-stories')
// 正確輸出
.then(response => {
var items = response.data.STORIES.top_stories;
console.log(items);
})
// 錯誤輸出
.catch(function (error) {
console.log(error);
});
},
}
}
</script>
如上圖代碼(我只拿取了script部分展示出來),先載入axios,這里就有個坑不太懂的了我,就是網上有說只要在main.js里面加上
import axios from 'axios';
Vue.prototype.$http = axios;
然后在其他組件用的時候就用 this.$http.get() ...
的就可以了。
但是我自己實踐的卻會報錯(不知道是不是我代碼有問題,如果有知道正確用法的請告知一聲,反正我暫時就是搞不來,最后只好在要用axios的組件上直接引用了,就像上面的代碼一樣)。
當中的mounted() {this.fetchData()}
我是網上查找的調用vue函數的方法(一開始我就是沒調用,結果愣是看著瀏覽器發呆,為什么沒有數據顯示呢??--你都只有這個函數方法,沒用到,有數據就見鬼了!!!)
如無意外,打開瀏覽器開發者模式里的Console就可以看到獲取到了這樣的數據
這就說明數據獲取成功了,那么就想辦法把里面關聯的數據放到banner上吧。
先在data里加上原始元素屬性,然后把axios里面得到的數據賦值給data里面的屬性,跟著使用到了vue的v-for來把數據循環輸出到banner上那么就可以實現banner了(主要是用到了數據源當中的image地址,和title標題:分析api上的數據可以得到)
想法就是上面這樣的,那么就動手實踐一下
繼續打開
項目名》src》components》banner
<script>
import axios from 'axios'
export default {
name: 'banner',
data() {
return {
//創建數組items,用來裝載axios獲取到的數據
items: [],
}
},
methods: {
fetchData() {
// 獲取數據
axios.get('https://zhihu-daily.leanapp.cn/api/v1/last-stories')
// 正確輸出
.then(response => {
// 在axios中,這里只有用箭頭函數this才指向vue
this.items = response.data.STORIES.top_stories;
console.log(this.items);
})
// 錯誤輸出
.catch(function (error) {
console.log(error);
});
},
}
}
</script>
這樣寫好的話,在瀏覽器上看到的應該會和之前一樣的效果(上一張Console里面看得的數據內容),這就說明賦值是成功的了。
這里有個坑,就像我注釋里一樣。
//在axios中,這里只有用箭頭函數this才指向vue
這個開始的時候,我是直接在axios的github上復制了一段代碼過來使用的,代碼如下
// Make a request for a user with a given ID
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
結果就是我在里面用this的時候一直報錯,后面查了下資料才知道只有用上箭頭函數時,axios里面的this才是指向vue的。
好了數據獲取到了,那么就該擺放上去banner上了,這里用到了v-for
打開
項目名》src》components》banner
<template>
<div class="banner clearfix swiper-container" ref="banner">
<mt-swipe :auto="4000">
<!-- 以items為數據源,循環 -->
<mt-swipe-item v-for="item in items" class="banner-img">
<!-- 圖片地址用v-bind縮寫":" -->
<img :src=“item.image” alt="banner">
<span>{{item.title}}</span>
</mt-swipe-item>
</mt-swipe>
</div>
</template>
使用v-for="item in items"
把items上的數據循環輸出到item上,然后里面主要是展示圖片,所以加了img標簽獲取圖片,還有一個span標簽用于獲取標題。(上面圖片行代碼<img :src=“item.image” alt="banner">
用了中文符號,半角打上去發布就變了,奇怪~)
其中圖片地址用v-bind縮寫":"來綁定,不讓的話你顯示的地址會是直接字符串item.image(此坑我也是掉過進去)
當然為了更好的在瀏覽器上看到效果,我們把一些樣式也加進去先
<style scoped>
.banner {
width: 100%;
height: 300px;
position: relative;
}
.banner-img img {
display: block;
width: 100%;
/*height: 100%; */
position: absolute;
left: 50%;
margin-left: -50%;
}
.banner-img span {
font-size: 22px;
display: block;
position: absolute;
bottom: 35px;
color: #fff;
padding: 0 20px;
}
</style>
當讓加上上面的樣式后你看看瀏覽器會發現
圖片地址是有了,而且正確了,但是每一張圖片都報錯403!!!
這其實是因為知乎服務器做了圖片防盜鏈的操作,那么我們要用到他的圖片就只能夠處理一下圖片地址了,具體方法就是轉接一下,如運用這個Images.weserv.nl的網站(感興趣的可以去看看,挺簡單的原理),我們要做的就是更改下圖片的前綴,加上images.weserv.nl/?url=p后面接上原圖片地址,就可以從他們的網站作為圖片源了。
所以我們需要多寫一個函數方法來改變一下圖片地址。
methods: {
fetchData() {
// 獲取數據
axios.get('https://zhihu-daily.leanapp.cn/api/v1/last-stories')
// 正確輸出
.then(response => {
// 在axios中,這里只有用箭頭函數this才指向vue
this.items = response.data.STORIES.top_stories;
})
// 錯誤輸出
.catch(function (error) {
console.log(error);
});
},
// 更改圖片地址
changeImageUrl(srcUrl) {
if (srcUrl !== undefined) {
return srcUrl.replace(/http\w{0,1}:\/\/p/g, 'https://images.weserv.nl/?url=p');
}
},
}
}
</script>
然后在使用到圖片地址的地方調用這個方法
<template>
<div class="banner clearfix swiper-container" ref="banner">
<mt-swipe :auto="4000">
<!-- 以items為數據源,循環 -->
<mt-swipe-item v-for="item in items" class="banner-img">
<!-- 更改圖片地址,否則知乎圖片防盜鏈無法顯示 -->
<img :src=“changeImageUrl(item.image)” alt="banner">
<span>{{item.title}}</span>
</mt-swipe-item>
</mt-swipe>
</div>
</template>
上面<img :src=“changeImageUrl(item.image)” alt="banner">
用了中文符號注意!
很好!大功告成!
結束
banner部分就此完成了,顯示的效果雖然達成了,但是當中不知道運用的技術是否得當,如有更好的實現方法請留言告訴我,最后把banner組件的完整代碼寫一下。
<template>
<div class="banner clearfix swiper-container" ref="banner">
<mt-swipe :auto="4000">
<!-- 以items為數據源,循環 -->
<mt-swipe-item v-for="item in items" class="banner-img">
<!-- 更改圖片地址,否則知乎圖片防盜鏈無法顯示 -->
<img :src=“changeImageUrl(item.image)” alt="banner">
<span>{{item.title}}</span>
</mt-swipe-item>
</mt-swipe>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'banner',
data() {
return {
items: [],
}
},
mounted() {
// 監聽方法
this.fetchData()
this.getHeight()
},
methods: {
fetchData() {
// 獲取數據
axios.get('https://zhihu-daily.leanapp.cn/api/v1/last-stories')
// 正確輸出
.then(response => {
// 在axios中,這里只有用箭頭函數this才指向vue
this.items = response.data.STORIES.top_stories;
})
// 錯誤輸出
.catch(function (error) {
console.log(error);
});
},
// 更改圖片地址
changeImageUrl(srcUrl) {
if (srcUrl !== undefined) {
return srcUrl.replace(/http\w{0,1}:\/\/p/g, 'https://images.weserv.nl/?url=p');
}
},
// 獲取banner塊的高度
getHeight() {
// 獲取屏幕高度
let h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
// 更改樣式,用到了vue中$refs方法
this.$refs.banner.style.height = h / 2 - 80 + 'px';
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.banner {
width: 100%;
position: relative;
}
.banner-img {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0 auto;
position: relative;
}
.banner-img img {
display: block;
width: 100%;
/*height: 100%; */
position: absolute;
left: 50%;
margin-left: -50%;
}
.banner-img span {
font-size: 22px;
display: block;
position: absolute;
bottom: 35px;
color: #fff;
padding: 0 20px;
}
</style>
和上面文章唯一不同的是,我把banner的高度改了一下,其他完全一樣。(上面<img :src=“changeImageUrl(item.image)” alt="banner">
用了中文符號注意!)