美文网首页让前端飞web前端开发
Vue瀑布流插件的使用示例

Vue瀑布流插件的使用示例

作者: 88b61f4ab233 | 来源:发表于2018-11-16 15:07 被阅读4次

    我自己写的一个的Vue瀑布流插件,列数自适应,不用设置每个卡片的高度。

    测试页面:Page.vue
    模板页面:WaterFollow.vue 和 WFColumn.vue

    在Page.vue中,修改itemW的值,设置每列的最小宽度。例如:itemW="200"(意为200px)。list为数组。高度不用设置,:style="{height:item+'px'}"是我为了创造卡片高度加上去的,不加就显示卡片的原来大小。

    经测试,created加载数据正常,mounted加载、更新数据正常。

    Page.vue

    <template>
     <div class="container">
      <w-f-column itemW="200">
       <template slot-scope="{columnNum,columnIndex}">
        <water-follow :list="list" :columnNum="columnNum" :columnIndex="columnIndex">
         <template slot-scope="{item,index}">
          <div class="my-box" :style="{height:item+'px'}">{{item}}-{{index}}</div>
         </template>//前端全栈学习交流圈:866109386
        </water-follow>//面向1-3年前端人员
       </template>//帮助突破技术瓶颈,提升思维能力。
      </w-f-column>
     </div>
    </template>
     
    <script>
    import WFColumn from '../waterFollow/WFColumn'
    import WaterFollow from '../waterFollow/WaterFollow'
    export default {
     name: 'page',
     components: {WaterFollow, WFColumn},
     data () {
      return {
       list: []
      }
     },
     created () {
      // 有初始数据
      for (let i = 0; i < 50; i++) {
       this.list.push(Math.floor(Math.random() * 301 + 200))
      }
     },
     mounted () {
      // 模拟网络请求
      // window.setTimeout(() => {
      //  this.list = []
      //  for (let i = 0; i < 50; i++) {
      //   this.list.push(Math.floor(Math.random() * 301 + 200))
      //  }
      // }, 1000)
      // -- 分割 --
      // 模拟数据不断变化
      // window.setInterval(() => {
      //  this.list = []
      //  for (let i = 0; i < 50; i++) {
      //   this.list.push(Math.floor(Math.random() * 301 + 200))
      //  }
      // }, 1000)
     }
    }
    </script>
     
    <style scoped lang="scss">
     .container{
      width: 100%;
      background: gray;
      .my-box{
       width: 200px;
       background: #000;
       margin-bottom: 20px;
       color: #fff;
      }
     }
    </style>
    

    WFColumn.vue

    <template>
     <div class="wf-container">
      <div class="wf-column" v-for="(item,index) in columnNum" :key="'column-'+index" :name="index">
       <slot :columnNum="columnNum" :columnIndex="index"></slot>
      </div>
     </div>
    </template>
     
    <script>
    export default {
     name: 'WFColumn',
     props: ['itemW'],
     data () {
      return {
       columnNum: 0
      }
     },
     created () {
      this.columnNum = Math.floor(document.body.clientWidth / this.itemW)
      window.onresize = () => {
       this.columnNum = Math.floor(document.body.clientWidth / this.itemW)
      }
     }
    }
    </script>
     
    <style scoped lang="scss">
    .wf-container{
     width: 100%;
     display: flex;
     .wf-column{
      flex: 1;
     }
    }
    </style>
    

    WaterFollow.vue

    <template>
     <div>
      <div v-for="(item,index) in list" :key="'item-'+index" class="item" :id="'card-'+columnIndex+'-'+index" v-if="load?(record[index].index===columnIndex):true">
       <slot :item="item" :index="index"></slot>
      </div>
     </div>
    </template>
     
    <script>
    export default {
     name: 'WaterFollow',
     props: ['list', 'columnNum', 'columnIndex'],
     data () {
      return {
       column: 0,
       record: [],
       load: false,
       update: false
      }
     },
     methods: {
      calculateColumn () {
       let cList = []
       for (let i = 0; i < this.columnNum; i++) {
        cList.push(0)
       }
       for (let i = 0; i < this.record.length; i++) {
        let index = 0
        for (let j = 0; j < cList.length; j++) {
         if (cList[index] > cList[j]) {
          index = j
         }
        }
        cList[index] += this.record[i].height
        this.record[i].index = index
       }
      },
      recordInit () {
       for (let i = 0; i < this.list.length; i++) {
        this.record.push({index: -1, height: -1})
       }
      },
      initHeightData () {
       for (let i = 0; i < this.list.length; i++) {
        if (document.getElementById('card-' + this.columnIndex + '-' + i)) {
         let h = document.getElementById('card-' + this.columnIndex + '-' + i).offsetHeight
         this.record[i].height = h
        }
       }
      }
     },
     beforeCreate () {},
     created () {
      this.load = false
      this.recordInit()
     },
     beforeMount () {},
     mounted () {
      this.initHeightData()
      this.calculateColumn()
      this.load = true
     },
     beforeUpdate () {},
     updated () {
      if (this.update) {
       this.initHeightData()
       this.calculateColumn()
       this.update = false
       this.load = true
      }
     },
     beforeDestroy () {},
     destroyed () {},
     watch: {
      columnNum (curr, old) {
       this.calculateColumn()
      },
      list (curr, old) {
       console.log('list change')
       this.recordInit()
       this.load = false
       this.update = true
      }
     }
    }
    </script>
     
    <style scoped>
    </style>
    

    相关文章

      网友评论

        本文标题:Vue瀑布流插件的使用示例

        本文链接:https://www.haomeiwen.com/subject/lfemfqtx.html