Table des matières
1. Source de l'exigence " > 1. Source de l'exigence
2. Hypothèse logique
3. Image de l'effet final" >3. Image de l'effet final
4. " >4.
5.
position : positionnement absolu, qui n'ouvrira pas le p extérieur, ce qui entraînera une mauvaise pose du modèle de boîte extérieure. et la page sera déroulée et chargée paresseusement. Alors, que devons-nous faire ? " >Lors de l'utilisation de ce plug-in, il y a deux problèmes, à cause de la couche intérieure. C'est position : positionnement absolu, qui n'ouvrira pas le p extérieur, ce qui entraînera une mauvaise pose du modèle de boîte extérieure. et la page sera déroulée et chargée paresseusement. Alors, que devons-nous faire ?
Maison interface Web Voir.js Vous guidez étape par étape dans l'utilisation de Vue pour implémenter un plug-in de flux de cascade horizontal d'images

Vous guidez étape par étape dans l'utilisation de Vue pour implémenter un plug-in de flux de cascade horizontal d'images

Oct 11, 2022 pm 07:21 PM
vue vue.js vue3

Comment utiliser Vue pour implémenter un plug-in de flux en cascade horizontal pour les images ? Ici, je voudrais partager avec vous quelques connaissances que j'ai résumées sur Internet, j'espère qu'elles vous seront utiles.

Vous guidez étape par étape dans l'utilisation de Vue pour implémenter un plug-in de flux de cascade horizontal d'images

1. Source de l'exigence

Aujourd'hui, j'ai rencontré une exigence, qui nécessite de charger quelques images sur la page à l'aide d'un flux en cascade horizontal. Cela m'a soudain rappelé une histoire que j'ai écrite il y a longtemps. Cet article "JS Deux façons d'implémenter une disposition de flux en cascade horizontale"

Mais il y a un problème pour le projet Vue, donc il n'y a aucun moyen de partager ici mon processus de développement. du projet utilise le précédent framework back-end Learn the CRMEB pour se développer, l'interface utilisateur utilise iView-UI et le reste des scénarios est cohérent avec d'autres projets Vue. [Recommandations associées : Tutoriel vidéo Vuejs]

2. Hypothèse logique

Si ce n'est pas un environnement Vue, notre logique est

1.获取所有的p元素
2.获取盒子的宽度,宽度都是相同,高度不同
3.在浮动布局中每一行的盒子个数不固定,是根据屏幕宽度和盒子宽度决定
4.获取屏幕宽度
5.求出列数,屏幕宽度 / 盒子宽度 取整
6.瀑布流最关键的是第二行的盒子的排布方式,通过获取第一行盒子中最矮的一个的下标,绝对定位,top是最矮盒子的高度,left是最矮盒子的下标 * 盒子的宽度
7.循环遍历所有的盒子,通过列数找到第一行所有的盒子,将第一行盒子的高度放入数组,再取出数组中最小的一个的下标,就是第6步思路的第一行盒子中最矮盒子的下标。
8.循环继续,第二行第一个盒子,通过绝对定位,放进页面。
9.关键,需要将数组中最小的值加上放进的盒子的高度
10.继续循环,遍历所有
11.如果想要加载更多,需要判断最后一个盒子的高度和页面滚动的距离,再将数据通过创建元素,追加进页面,再通过瀑布流布局展示
Copier après la connexion

Mais s'il s'agit d'un projet Vue, nous pouvons résumez la logique aux étapes suivantes

1.获取屏幕宽度
2..获取盒子的宽度,宽度都是相同,高度不同
3.在浮动布局中每一行的盒子个数不固定,是根据屏幕宽度和盒子宽度决定
4.求出列数,屏幕宽度 / 盒子宽度 取整
5.瀑布流最关键的是第二行的盒子的排布方式,通过获取第一行盒子中最矮的一个的下标,绝对定位,top是最矮盒子的高度,left是最矮盒子的下标 * 盒子的宽度
6.继续循环,遍历所有
7.如果想要加载更多,需要判断最后一个盒子的高度和页面滚动的距离,再将数据通过创建元素,追加进页面,再通过瀑布流布局展示
Copier après la connexion

3. Image de l'effet final

4.

<template>
  <div class="tab-container" id="tabContainer">
    <div class="tab-item" v-for="(item, index) in pbList" :key="index">
      <img :src="item.url" />
    </div>
  </div>
</template>
 
<style scoped>
* {
  margin: 0;
  padding: 0;
}
/* 最外层大盒子 */
.tab-container {
  padding-top: 20px;
  position: relative;
}
/* 每个小盒子 */
.tab-container .tab-item {
  position: absolute;
  height: auto;
  border: 1px solid #ccc;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
  background: white;
  /* 元素不能中断显示 */
  break-inside: avoid;
  text-align: center;
}
.tab-container .tab-item img {
  width: 100%;
  height: auto;
  display: block;
}
</style>
Copier après la connexion

La partie principale de js

<script>
export default {
  name:&#39;compList&#39;,
  props:{
    pbList:{
      type:Array,
      default:()=>{return []}
    }
  },
  data() {
    return {
    };
  },
  mounted() {
    this.$nextTick(()=>{
      this.waterFall("#tabContainer", ".tab-item"); //实现瀑布流
    })
  },
  methods: {
    waterFall(
        wrapIdName,
        contentIdName,
        columns = 5,
        columnGap = 20,
        rowGap = 20
    ) {
      // 获得内容可用宽度(去除滚动条宽度)
      const wrapContentWidth =
          document.querySelector(wrapIdName).offsetWidth;
 
      // 间隔空白区域
      const whiteArea = (columns - 1) * columnGap;
 
      // 得到每列宽度(也即每项内容宽度)
      const contentWidth = parseInt((wrapContentWidth - whiteArea) / columns);
 
      // 得到内容项集合
      const contentList = document.querySelectorAll(contentIdName);
 
      // 成行内容项高度集合
      const lineConentHeightList = [];
 
      for (let i = 0; i < contentList.length; i++) {
        // 动态设置内容项宽度
        contentList[i].style.width = contentWidth + "px";
 
        // 获取内容项高度
        const height = contentList[i].clientHeight;
 
        if (i < columns) {
          // 第一行按序布局
          contentList[i].style.top = "0px";
          contentList[i].style.left = contentWidth * i + columnGap * i + "px";
 
          // 将行高push到数组
          lineConentHeightList.push(height);
        } else {
          // 其他行
          // 获取数组最小的高度 和 对应索引
          let minHeight = Math.min(...lineConentHeightList);
          let index = lineConentHeightList.findIndex(
              (listH) => listH === minHeight
          );
 
          contentList[i].style.top = minHeight + rowGap +"px";
          contentList[i].style.left = (contentWidth + columnGap) * index + "px";
 
          // 修改最小列的高度 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 行间距
          lineConentHeightList[index] += height + rowGap;
        }
      }
    },
  },
};
</script>
Copier après la connexion

Voici un rappel pour tout le monde Lors de l'utilisation du plug-in, nous devons utiliser this.$nextTick() pour initialiser la page, car c'est le principe de la méthode. pour réussir, il faut attendre que la page soit initialisée et chargée. L'acquisition et le calcul ne peuvent être effectués qu'une fois terminés

Le code global du plug-in est :


 
<script>
export default {
  name:&#39;compList&#39;,
  props:{
    pbList:{
      type:Array,
      default:()=>{return []}
    }
  },
  data() {
    return {
    };
  },
  mounted() {
    this.$nextTick(()=>{
      this.waterFall("#tabContainer", ".tab-item"); //实现瀑布流
    })
  },
  methods: {
    waterFall(
        wrapIdName,
        contentIdName,
        columns = 5,
        columnGap = 20,
        rowGap = 20
    ) {
      // 获得内容可用宽度(去除滚动条宽度)
      const wrapContentWidth =
          document.querySelector(wrapIdName).offsetWidth;
 
      // 间隔空白区域
      const whiteArea = (columns - 1) * columnGap;
 
      // 得到每列宽度(也即每项内容宽度)
      const contentWidth = parseInt((wrapContentWidth - whiteArea) / columns);
 
      // 得到内容项集合
      const contentList = document.querySelectorAll(contentIdName);
 
      // 成行内容项高度集合
      const lineConentHeightList = [];
 
      for (let i = 0; i < contentList.length; i++) {
        // 动态设置内容项宽度
        contentList[i].style.width = contentWidth + "px";
 
        // 获取内容项高度
        const height = contentList[i].clientHeight;
 
        if (i < columns) {
          // 第一行按序布局
          contentList[i].style.top = "0px";
          contentList[i].style.left = contentWidth * i + columnGap * i + "px";
 
          // 将行高push到数组
          lineConentHeightList.push(height);
        } else {
          // 其他行
          // 获取数组最小的高度 和 对应索引
          let minHeight = Math.min(...lineConentHeightList);
          let index = lineConentHeightList.findIndex(
              (listH) => listH === minHeight
          );
 
          contentList[i].style.top = minHeight + rowGap +"px";
          contentList[i].style.left = (contentWidth + columnGap) * index + "px";
 
          // 修改最小列的高度 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 行间距
          lineConentHeightList[index] += height + rowGap;
        }
      }
    },
  },
};
</script>
 
Copier après la connexion

5.

Lors de l'utilisation de ce plug-in, il y a deux problèmes, à cause de la couche intérieure. C'est position : positionnement absolu, qui n'ouvrira pas le p extérieur, ce qui entraînera une mauvaise pose du modèle de boîte extérieure. et la page sera déroulée et chargée paresseusement. Alors, que devons-nous faire ?

Je donne ici ma méthode de traitement

Le code global est le suivant :

<template>
  <div>
    <div class="list-box" @scroll="scrollFun">
      <compList :pbList="pbList" ref="compList"></compList>
    </div>
  </div>
</template>
 
<script>
import compList from "@/pages/test/components/compList";
export default {
  name:&#39;testList&#39;,
  components:{
    compList
  },
  data() {
    return {
      //瀑布流数据
      pbList: [
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        }
      ],
      addList:[
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        },
        {
          url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
        }
      ],
      bottomMain:true
    };
  },
  methods:{
    scrollFun(e) {
      const  offsetHeight= e.target.offsetHeight
      const  scrollHeight= e.target.scrollHeight
      const  scrollTop= e.target.scrollTop
      if((scrollHeight - (offsetHeight+scrollTop)) < 10){
        if(this.bottomMain){
          this.bottomMain = false
          this.addListDataFun()
        }
      }
    },
    addListDataFun(){
      this.$Spin.show({
        render: (h) => {
          return h(&#39;div&#39;, [
            h(&#39;Icon&#39;, {
              &#39;class&#39;: &#39;demo-spin-icon-load&#39;,
              props: {
                type: &#39;ios-loading&#39;,
                size: 18
              }
            }),
            h(&#39;div&#39;, &#39;数据更新中...&#39;)
          ])
        }
      });
      setTimeout(() => {
        this.pbList = this.pbList.concat(this.addList)
        this.bottomMain = true
        this.$nextTick(()=>{
          this.$refs.compList.waterFall("#tabContainer", ".tab-item")
          this.$Spin.hide()
        })
      },1000)
    }
  }
};
</script>
 
<style scoped>
.list-box{
  position: relative;
  width: 100%;
  height: calc(100vh - 240px);
  background: white;
  padding: 20px 30px 20px 20px;
  margin-top: 20px;
  box-sizing: border-box;
  overflow: auto;
}
</style>
Copier après la connexion

Le code principal de la liste déroulante est :

scrollFun(e) {
  const  offsetHeight= e.target.offsetHeight
  const  scrollHeight= e.target.scrollHeight
  const  scrollTop= e.target.scrollTop
  if((scrollHeight - (offsetHeight+scrollTop)) < 10){
    if(this.bottomMain){
      this.bottomMain = false
      this.addListDataFun()
    }
  }
},
addListDataFun(){
  this.$Spin.show({
    render: (h) => {
      return h(&#39;div&#39;, [
        h(&#39;Icon&#39;, {
          &#39;class&#39;: &#39;demo-spin-icon-load&#39;,
          props: {
            type: &#39;ios-loading&#39;,
            size: 18
          }
        }),
        h(&#39;div&#39;, &#39;数据更新中...&#39;)
      ])
    }
  });
  setTimeout(() => {
    this.pbList = this.pbList.concat(this.addList)
    this.bottomMain = true
    this.$nextTick(()=>{
      this.$refs.compList.waterFall("#tabContainer", ".tab-item")
      this.$Spin.hide()
    })
  },1000)
}
Copier après la connexion

L'événement de chargement global d'iView- L'interface utilisateur est utilisée ici. Si vous souhaitez utiliser d'autres frameworks d'interface utilisateur, vous pouvez également les modifier vous-même

Ici, toutes les idées sont terminées

(Partage de vidéos d'apprentissage :

développement web front-end

, Programmation de base vidéo)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Vue.js vs react: Considérations spécifiques au projet Vue.js vs react: Considérations spécifiques au projet Apr 09, 2025 am 12:01 AM

Vue.js convient aux projets de petite et moyenne taille et aux itérations rapides, tandis que React convient aux applications grandes et complexes. 1) Vue.js est facile à utiliser et convient aux situations où l'équipe est insuffisante ou l'échelle du projet est petite. 2) React a un écosystème plus riche et convient aux projets avec des performances élevées et des besoins fonctionnels complexes.

Comment ajouter des fonctions aux boutons pour Vue Comment ajouter des fonctions aux boutons pour Vue Apr 08, 2025 am 08:51 AM

Vous pouvez ajouter une fonction au bouton VUE en liant le bouton dans le modèle HTML à une méthode. Définissez la logique de la fonction de méthode et d'écriture dans l'instance Vue.

Comment utiliser Bootstrap en Vue Comment utiliser Bootstrap en Vue Apr 07, 2025 pm 11:33 PM

L'utilisation de bootstrap dans vue.js est divisée en cinq étapes: installer bootstrap. Importer un bootstrap dans main.js. Utilisez le composant bootstrap directement dans le modèle. Facultatif: style personnalisé. Facultatif: utilisez des plug-ins.

Comment référencer le fichier JS avec Vue.js Comment référencer le fichier JS avec Vue.js Apr 07, 2025 pm 11:27 PM

Il existe trois façons de se référer aux fichiers JS dans Vue.js: spécifiez directement le chemin à l'aide du & lt; script & gt; étiqueter;; importation dynamique à l'aide du crochet de cycle de vie monté (); et l'importation via la bibliothèque de gestion de l'État Vuex.

Comment utiliser Watch in Vue Comment utiliser Watch in Vue Apr 07, 2025 pm 11:36 PM

L'option Watch dans Vue.js permet aux développeurs d'écouter des modifications de données spécifiques. Lorsque les données changent, regardez déclenche une fonction de rappel pour effectuer des vues de mise à jour ou d'autres tâches. Ses options de configuration incluent immédiatement, qui spécifie s'il faut exécuter un rappel immédiatement, et profond, ce qui spécifie s'il faut écouter récursivement les modifications des objets ou des tableaux.

Que signifie le développement de plusieurs pages Vue? Que signifie le développement de plusieurs pages Vue? Apr 07, 2025 pm 11:57 PM

Le développement multi-pages VUE est un moyen de créer des applications à l'aide du cadre Vue.js, où l'application est divisée en pages distinctes: Maintenance du code: La division de l'application en plusieurs pages peut rendre le code plus facile à gérer et à maintenir. Modularité: chaque page peut être utilisée comme module séparé pour une réutilisation et un remplacement faciles. Routage simple: la navigation entre les pages peut être gérée par une configuration de routage simple. Optimisation du référencement: chaque page a sa propre URL, ce qui aide le référencement.

Comment revenir à la page précédente par Vue Comment revenir à la page précédente par Vue Apr 07, 2025 pm 11:30 PM

Vue.js dispose de quatre méthodes pour revenir à la page précédente: $ router.go (-1) $ router.back () utilise & lt; router-link to = & quot; / & quot; Composant Window.History.back (), et la sélection de la méthode dépend de la scène.

Comment interroger la version de Vue Comment interroger la version de Vue Apr 07, 2025 pm 11:24 PM

Vous pouvez interroger la version Vue en utilisant Vue Devtools pour afficher l'onglet Vue dans la console du navigateur. Utilisez NPM pour exécuter la commande "NPM List -g Vue". Recherchez l'élément VUE dans l'objet "dépendances" du fichier package.json. Pour les projets Vue CLI, exécutez la commande "Vue --version". Vérifiez les informations de la version dans le & lt; script & gt; Tag dans le fichier html qui fait référence au fichier VUE.

See all articles