用vue.js寫的一個瀑布流的組件

不多寫文章,很亂,,見諒。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,
            }
        },
    }
}

放一張渣渣效果圖吧。。。

clipboard.png

代碼裏是一次性生成的20個元素,頁面渲染的時候,很明顯的能看出來是在一個img觸發了load事件以後才渲染下一個元素。
若是花點心思加一些動畫效果應該很酷吧。函數

若是你要渲染的item不包含圖片,純文字的話,能夠經過這種寫法調用next。保證了計算列高度的準確性。測試

renderItem(h, item, next){
    this.$nextTick(function(){
        next();
    });
    return h('p', item.title);
},

瀑布流的流程說明

  1. 先根據參數生成對應數量的列,動畫

  2. 判斷data是否有元素,沒有就結束。ui

  3. 從data裏面shift()拿到一個元素item,this

  4. 找出當前高度最小的一列,將item放入該列。spa

  5. 渲染item,而後調用next()方法進入2

TODO

  • 瀑布流還有個常見的功能就是滾動加載了,目前還沒有加入此功能,會盡快加上。

  • 元素加載的過渡動畫

相關文章
相關標籤/搜索