Vue瀑布流插件的使用示例

news/2024/7/10 2:30:16 标签: vue

我自己写的一个的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>

http://www.niftyadmin.cn/n/1301165.html

相关文章

BeyondCompare去掉时间戳的匹配

BeyondCompare是一个非常好用的对比工具。 其中在对比文件的时候&#xff0c;我们可能需要在不进入文件的情况下&#xff0c;一眼就看出两个文件是否一样。 在没有去掉时间戳的匹配的情况下&#xff0c;是看不出来的&#xff0c;因为可能文件的内容是一样的&#xff0c;而文件…

vue-router的HTML5 History 模式设置

VUE是当下最火爆的前端框架之一&#xff0c;vue-router是vue项目中几乎都会用到的组件&#xff0c;然而体验一时爽&#xff0c;其实坑不少。本篇经验将详细介绍vue-router的两种mode效果和开发测试环境下的问题&#xff0c;并给出解决方案。 vue-router的HTML5 History 模式&a…

C语言鱼类管理系统

#include <stdio.h>#include <stdlib.h>//内存分配#include <string.h>//字符串处理#include <conio.h>//用于getch() typedef struct fish{char name[20];//鱼名float price;//价格int num;//总数量int sell;//卖出的数量struct fish *next…

C语言图书管理系统

typedef struct p1{ char pname[30];//人的姓名 char pnum[30];//人的学号 char bname[4][30];//借的书名,最多四本 int bnum;//借书的数目}p; typedef struct b1{ char bname[30]; //书名 char author[30];//书的作者 char pname[30];//人的姓名 int jm;/…

vue router+vuex实现首页登录验证判断逻辑

首页登录逻辑要求在页面上判断是否获取到登录token &#xff0c;没有获取到则跳转到登录页。登录成功后&#xff0c;跳转到前一个页面。 1.vue router 路由判断首先我们想到的是router.beforeEach 前置导航守卫 &#xff0c;这个方法接受三个参数 to from next 。 to参数为即…

C语言小区居民查询系统

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<conio.h> typedef struct member//成员结构体 { char name[30];//姓名 char born[10];//出生日 int relation;//与户主关系 int sex;//姓别 struct member *next; }mem; typedef str…

详解vue-router 初始化时做了什么

vue router 的初始化使用步骤 我们首先来看 vue-router 的使用步骤&#xff0c;然后再分别去看各个步骤都发生了什么。 使用 vue-router 需要经过一下几个步骤&#xff1a; 引入 vue-router&#xff1a; import VueRouter from vue-router;利用 vue 的插件机制&#xff0c;…

C语言学籍管理系统

#include <stdio.h>#include <stdlib.h>//内存分配#include <string.h>//字符串处理#include <conio.h>//用于getch() typedef struct mark{char num[20];//学号int ch;//语int ma;//数int en;//外struct mark *next ;} m; typedef struct stud…