H5移动端vue-masonry + van-list实现瀑布流懒加载效果

H5移动端vue-masonry + van-list实现瀑布流懒加载效果

1. 安装两个库

npm install vue-masonry --save
npm i vant@latest-v2 --save

2. 全局注册
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Vant from 'vant'
import 'vant/lib/index.css'
import {VueMasonryPlugin} from 'vue-masonry';
import '@/assets/global.css'
 
Vue.config.productionTip = false
 
Vue.use(Vant)
Vue.use(VueMasonryPlugin)
 
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
3. 使用

vue-masonry 的一些属性

  1. item-selector=".item" 列表元素 DOM 项目选择器;
  2. transition-duration="0.3s" 过渡的持续时间;
  3. column-width="#test" 列宽的元素选择器。可以是选择器字符串或数字;
  4. origin-left=“false” 设置为默认将元素分组到右侧而不是左侧;
  5. origin-top="false" 默认情况下将元素分组到底部而不是顶部;
  6. stamp=".stamp" 指定在布局中标记哪些元素;
  7. gutter=".gutter-block-selector" 指定[项目元素之间的水平空间]。可以是选择器字符串或数字。将 gutter 设置为 Element 或 Selector String 以使用元素的外部宽度;
  8. fit-width="true" 设置容器的宽度以适合可用的列数;
  9. horizontal-order="true" 布置项目以(主要)保持水平从左到右的顺序;
  10. stagger="0.03s" 错开项目过渡,因此项目一个接一个地逐步过渡。设置为 CSS,时间格式,“0.03s”,或以毫秒为单位的数字,30。
  11. destroy-delay="0" masonry.destroy() 当容器被销毁时,在卸载砖石之前等待的时间(以毫秒为单位) 。这在页面/路由转换期间很有用,以确保在转换发生时布局是一致的。
<template>
  <div :style="{ padding: `10px` }">
    <van-list v-model="loading" :finished="finished" finished-text="我是有底线的" @load="onLoad" :immediate-check="false"
      :style="{ width: `${screenWidth - 20}px` }">
      <van-cell :style="{ padding: `10px` }">
        <div v-masonry transition-duration="0s" item-selector=".item" gutter="10">
          <div v-masonry-tile class="item" v-for="(item, index) in  styleList " :key="item.id"
            :style="{ width: `${imgWidth}px`, marginBottom: '4px' }" @click="goto(item)">
            <img :src="item.src" alt="">
            <div :style="{ position: 'absolute', bottom: '10px', right: '10px', background: '#fff' }">{{ index }}</div>
          </div>
        </div>
      </van-cell>
    </van-list>
  </div>
</template>
<script>
export default {
  data() {
    return {
      screenWidth: null,
      screenHeight: null,
      imgWidth: null,
      styleList: [
        { id: null, type: '商务1', src: "https://www.freeimg.cn/i/2024/01/08/659b50c926020.png" },
        { id: null, type: '商务2', src: "https://www.freeimg.cn/i/2024/01/08/659b50ca0646d.jpg" },
        { id: null, type: '商务3', src: "https://www.freeimg.cn/i/2024/01/08/659b50c9e9d0f.png" },
        { id: null, type: '商务4', src: "https://www.freeimg.cn/i/2024/01/08/659b50c926020.png" },
        { id: null, type: '商务5', src: "https://www.freeimg.cn/i/2024/01/08/659b50ca0646d.jpg" },
        { id: null, type: '商务6', src: "https://www.freeimg.cn/i/2024/01/08/659b50c9e9d0f.png" },
        { id: null, type: '商务7', src: "https://www.freeimg.cn/i/2024/01/08/659b50c926020.png" },
        { id: null, type: '商务8', src: "https://www.freeimg.cn/i/2024/01/08/659b50ca0646d.jpg" },
        { id: null, type: '商务9', src: "https://www.freeimg.cn/i/2024/01/08/659b50c9e9d0f.png" },
        { id: null, type: '商务10', src: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F8080ba2d-d5e8-4f98-96d0-95c69d5862b8%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1706774872&t=b1900e9188c67df586f8e3abacb0290a" },
      ], // 图片列表
      // 状态
      loading: false,
      finished: false,
      curPage: 1,
      total: 0
    };
  },
  created() {
    this.screenWidth = document.body.clientWidth;     // 屏幕宽
    this.screeHeight = document.body.clientHeight;    // 屏幕高
    console.log('screenWidth:' + this.screenWidth);
    console.log('screeHeight:' + this.screeHeight);
    this.imgWidth = (this.screenWidth - 50) / 2
    this.getList();
  },
  methods: {
    getList() {
      this.styleList.map(r => { r.id = Math.floor(Math.random() * 999999999) + 1 })
    },
    onLoad() {
      console.log('到底了,需要继续加载');

      // 特判,当总数据小于10条时
      if (this.total <= 10 && this.total !== 0) {
        this.finished = true;
        return;
      }

      // 判断当前页数是否等于总页数,并且初始长度不等于0,防止从详情页返回出现bug,造成误判
      if (this.curPage === Math.ceil(this.total / 10) && this.total !== 0) {
        this.finished = true;
        return;
      }

      this.curPage++;
      // http({
      //   url: `/gateway?cityId=310100&pageNum=${this.curPage}&pageSize=10&type=1&k=908466`,
      //   headers: {
      //     'X-Host': 'mall.film-ticket.film.list'
      //   }
      // }).then((res) => {
      //   this.filmList = this.addNewFilmItems(res.data.data.films);
      //   this.total = res.data.data.total
      //   console.log(this.filmList);
      // })
      this.getList();
      let list = [
        { id: null, type: '商务1', src: "https://www.freeimg.cn/i/2024/01/08/659b50c926020.png" },
        { id: null, type: '商务2', src: "https://www.freeimg.cn/i/2024/01/08/659b50ca0646d.jpg" },
        { id: null, type: '商务3', src: "https://www.freeimg.cn/i/2024/01/08/659b50c9e9d0f.png" },
        { id: null, type: '商务4', src: "https://www.freeimg.cn/i/2024/01/08/659b50c926020.png" },
        { id: null, type: '商务5', src: "https://www.freeimg.cn/i/2024/01/08/659b50ca0646d.jpg" },
        { id: null, type: '商务6', src: "https://www.freeimg.cn/i/2024/01/08/659b50c9e9d0f.png" },
        { id: null, type: '商务7', src: "https://www.freeimg.cn/i/2024/01/08/659b50c926020.png" },
        { id: null, type: '商务8', src: "https://www.freeimg.cn/i/2024/01/08/659b50ca0646d.jpg" },
        { id: null, type: '商务9', src: "https://www.freeimg.cn/i/2024/01/08/659b50c9e9d0f.png" },
        { id: null, type: '商务10', src: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F8080ba2d-d5e8-4f98-96d0-95c69d5862b8%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1706774872&t=b1900e9188c67df586f8e3abacb0290a" },
      ]
      list.map(r => { r.id = Math.floor(Math.random() * 999999999) + 1 })
      this.styleList.push(...list);
      this.loading = false;
    },

    addNewFilmItems(newFilmList) {
      return this.filmList.concat(newFilmList);
    },

    filteredActors(actors) {
      const actorsName = actors.map((item) => {
        return item = item.name;
      });

      return actorsName.join(' ');
    },
  },
};
</script>

注:使用中遇到class被覆盖的情况,原因暂时没有排查,先使用行内样式解决此问题。

  • 23
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值