您好,登錄后才能下訂單哦!
小編給大家分享一下vue中slot內容分發的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
vue的內容分發非常適合“固定部分+動態部分”的組件的場景,固定部分可以是結構固定,也可以是邏輯固定,比如下拉loading,下拉loading只是中間內容是動態的,而拉到底部都會觸發拉取更多內容的操作,因此我們可以把下拉loading做成一個有slot的插件。
單個Slot
在children這個標簽里面放Dom,Vue不會理你,也就是不會顯示,類似React:this.props.children。
//父 <children> <span>12345</span>//這邊不會顯示 </children> //子 components: { children: { template: "<button>為了明確作用范圍,所以使用button標簽</button>" } }
你需要寫成這樣
children: { template: "<button><slot></slot>為了明確作用范圍,所以使用button標簽</button>" }
注意這邊 slot 相當于一個坑,等著父組件給填上,這邊 slot 代表的就是上面的 span
多個Slot
這邊需要加name屬性,說白了,多個Slot就不像上面單個,需要有個對應關系。
父-> slot="name1"
子-> <slot name="name1"
//父 <children> <span slot="name1">12345</span> </children> //子 components: { children: { template: "<button> <slot name="name1"></slot> button標簽 </button>" } }
這邊寫了一個name1,如果有多個,就插多個,比較簡單。
使用場景
“下拉加載更多”的場景在移動端相對來說出現得比較多。我們知道下拉觸底都要監聽觸底事件,觸底的操作也相同(去后臺拉取數據),分頁算法也相同,因此我們會想到把它做成一個組件,重用這些相同的地方,讓其他地方可以共用這個組件,從而減少代碼量。
然而,下拉loading并不是一個可以完全重用的組件,因為列表里面的內容不同,空白頁(沒有內容時)的內容也可能不同,如果要做成組件,那么就要考慮到這方面的“不同”,因此我們想到利用vue的內容分發slot來做。下面是本人在開發的時候做的一個下拉loading,大家可以參考下。
組件代碼:
<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。
意向不到的slot另類用法
我在做需求的時候,做了一個組件,該組件分為上下兩個部分,這兩個部分耦合度很高(不然我怎么把它當成一個組件呢哈哈哈),如下圖所示:
本來C區域是一個組件,然后產品突然說,需要把這兩個部分分開,把A移到C1的位置,C1移到A的位置(心里感覺到憋屈)。
這里我的第一個想法就是拆開來做成兩個組件,但是問題來了,之前這兩部分的耦合度很高,如果強制把它拆開成兩個組件,那么這兩個組件之間的交互必然會多很多。比如,C1改變了某個東西會影響到C2,那么C1需要觸發事件通知父組件,父組件再調用C2的某個方法來更新狀態。這種跨組件之間的通訊在組件之間頻繁交互的情況下,將會是噩夢,而我這邊卻需要頻繁的交互,所以如果把它拆分為兩個組件,那么工作量和復雜度將會大大的增加。當然,你可以想到通過Event Hub的方式來實現兩個組件之間的交互,但是根本問題還是沒有實質性得得到解決。
那么,有什么方法可以做到不拆分成兩個組件又能移動位置的方法呢,答案就是slot。以我的例子為例,把A和B作為C的內容分發,原來是這樣的:
<A></A> <B></B> <C></C>
改為slot以后是這樣的
<C> <A slot="c1"></A> <B slot="c2"></B> </C>
這樣就能做到不把C模塊拆分,又能調整位置了,以最小的代價完成需求~~。
以上是“vue中slot內容分發的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。