不多寫文章,很亂,,見諒。vue
我所見過的瀑布流都是固定的幾列,而後每一列包含若干個元素(圖文元素),每一列的總高度都差很少。
因此我這個組件的功能就很簡單,能夠設置列數量,而後只要再寫一個渲染元素的方法,便可使用。git
組件名:<tag-autoflow />github
參數名 | 類型 | 說明 |
---|---|---|
data | Array | 數據源 |
column_size | Number | 列的數量 |
renderItem | Function | 目前只能經過render函數渲染子元素,還不支持模板。 有三個參數 h, item,將被渲染的元素 next,是一個function,在渲染子元素的合適時機(例如img的onload事件裏),調用next()便可。 如不調用next將只能渲染一個元素,沒法繼續渲染。 |
源代碼在此dom
export default { data() { // 隨機生成20個測試數據 const num = 20; var list = new Array(num).fill(0).map((v, i) => { return this.createItem(i); }) return { list, } }, // 直接用render函數來寫,由於我以爲這樣寫props更直觀一點 render(h){ return h('tag-autoflow', { props:{ // 設置列數量 column_size:3, // 數據源 data: this.list, // 渲染item的方法,參數目前提供三個 // h 瀑布流組件的createElement方法,非父組件的 // item 要渲染的元素對象 // next 必須主動調用next,插件纔會自動去渲染下一個元素,詳細說明見下文 renderItem(h, item, next){ // 簡單的渲染一個img跟一個p標籤 // 由於img標籤的圖片加載須要時間,而圖片影響了計算所在列的高度 // 因此須要在img觸發了load事件後,再去調用next渲染下一個item。 return h('div', [ h('img', { attrs: { src: item.img }, on: { load: e => { next(); } } }), h('p', item.title) ]) }, }, }); }, methods:{ createItem(i) { var title = i + ',' + new Array(_.random(10, 150)).fill('哈').join(''); var img = `http://via.placeholder.com/${_.random(100, 400)}x${_.random(100, 400)}`; return { img, title, } }, } }
代碼裏是一次性生成的20個元素,頁面渲染的時候,很明顯的能看出來是在一個img觸發了load事件以後才渲染下一個元素。
若是花點心思加一些動畫效果應該很酷吧。函數
若是你要渲染的item不包含圖片,純文字的話,能夠經過這種寫法調用next。保證了計算列高度的準確性。測試
renderItem(h, item, next){ this.$nextTick(function(){ next(); }); return h('p', item.title); },
先根據參數生成對應數量的列,動畫
判斷data是否有元素,沒有就結束。ui
從data裏面shift()拿到一個元素item,this
找出當前高度最小的一列,將item放入該列。spa
渲染item,而後調用next()方法進入2
瀑布流還有個常見的功能就是滾動加載了,目前還沒有加入此功能,會盡快加上。
元素加載的過渡動畫