vue的內容分發很是適合「固定部分+動態部分」的組件的場景,固定部分能夠是結構固定,也能夠是邏輯固定,好比下拉loading,下拉loading只是中間內容是動態的,而拉到底部都會觸發拉取更多內容的操做,所以咱們能夠把下拉loading作成一個有slot的插件。vue
「下拉加載更多」的場景在移動端相對來講出現得比較多。咱們知道下拉觸底都要監聽觸底事件,觸底的操做也相同(去後臺拉取數據),分頁算法也相同,所以咱們會想到把它作成一個組件,重用這些相同的地方,讓其餘地方能夠共用這個組件,從而減小代碼量。
然而,下拉loading並非一個能夠徹底重用的組件,由於列表裏面的內容不一樣,空白頁(沒有內容時)的內容也可能不一樣,若是要作成組件,那麼就要考慮到這方面的「不一樣」,所以咱們想到利用vue的內容分發slot來作。下面是本人在開發的時候作的一個下拉loading,你們能夠參考下。算法
組件代碼:bash
<template>
<div>
<slot name="list" v-if="total > 0"></slot>
<slot name="empty" v-else></slot>
</div>
</template>
<script>
import Toast from 'lib/xl-toast'
import Tool from 'tool/tool'
export default {
data() {
return {
page: 1,
isLoading: false,
busy: false,
isFirstLoad: false
}
},
props: {
pageSize: {
default: 10 // 每頁展現多少條數據
},
total: {
default: 0 // 總共多少條記錄
}
},
computed: {
totalPage() {
return Math.ceil(this.total / this.pageSize)
}
},
created() {
this.getList()
},
mounted() {
this.addScrollListener()
},
methods: {
addScrollListener() {
// 添加監聽滾動操做,用到函數防抖
this.scrollFn = Tool.throttle(this.onScroll, 30, 30)
document.addEventListener('scroll', this.scrollFn, false)
},
getList() {
// 正在拉取數據或者沒有數據了,則取消滾動監聽
if(this.isLoading || this.isFirstLoad && (this.page > this.totalPage)) {
document.removeEventListener('scroll', this.scrollFn, false)
return
}
this.busy = true
this.isLoading = true
// 通知父組件去拉取更多數據
this.$emit("getList", this.page, () => {
this.isFirstLoad = true
this.isLoading = false
this.page++
}, () => {
Toast.show('網絡錯誤,請稍後重試')
this.total = 0
this.isLoading = false
})
},
reset() {
// 從新拉取數據
this.page = 1
this.total = 0
this.isLoading = false
this.isFirstLoad = false
this.addScrollListener()
this.getList()
},
onScroll() {
// 到底拉取更多數據
if(Tool.touchBottom()) {
this.getList()
}
}
}
}
</script>
複製代碼
總之,遇到一些有想對比較固定的部分,包括js操做或者結構固定,又有一些動態的部分,咱們應該就應該考慮到使用:組件+slot。網絡
我在作需求的時候,作了一個組件,該組件分爲上下兩個部分,這兩個部分耦合度很高(否則我怎麼把它當成一個組件呢哈哈哈),以下圖所示: 函數
原本C區域是一個組件,而後產品忽然說,須要把這兩個部分分開,把A移到C1的位置,C1移到A的位置(內心感受到憋屈)。<A></A>
<B></B>
<C></C>
複製代碼
改成slot之後是這樣的ui
<C>
<A slot="c1"></A>
<B slot="c2"></B>
</C>
複製代碼
這樣就能作到不把C模塊拆分,又能調整位置了,以最小的代價完成需求~~。this
vue的slot不只能夠用來內容分發,還能夠用來作位置調整。若是在須要拆分組件來作位置調整,又不想由於拆分耦合度很高的組件,能夠考慮使用slot來進行位置調整。一點愚見,但願對你們有所幫助。spa