• vuejs实现瀑布流布局(二)


    瀑布流布局已然完成,那么剩下的就是另一个比较大的工程了——无限加载。

    之前说了,这个活动项目是基于SUI-Mobile搭建的,所以可以直接使用sui内建组件“无限加载”来实现这个功能。

    没有真实的数据,所有数据都是自己创建的假数据

    以works.json为例:

    [
      {
        "id": 1,
        "src": "http://cued.xunlei.com/demos/publ/img/P_000.jpg",
        "numbering":"00001",
        "school":"双语小学",
        "student":"王伟",
        "praise":"23",
        "isDel": true,
        "delDesc": "图片不符合法律要求",
        "name": "美美的一天",
        "todayClk": false,
        "isPraise": false
      },
      ...     
    ]

    一个数组,里面是一个个的对象。

    最开始实现的时候,是在methods对象里面定义一个初始化请求函数,一个分页请求函数

          fetchData(fn){
            var _this = this;
            axios.get("./src/assets/data/worksRank.json").then(function (res) {
              _this.worksList=res.data
              if (typeof fn =="function") fn();
            })
          },
          loadingMore(){
            var _this = this;
            var loading = false;
    
            // 每次加载添加多少条目
            var itemsPerLoad = 10,
                page = 2;
            // 注册'infinite'事件处理函数
            $(document).on('infinite',  function() {
              
              // 如果正在加载,则退出
              if (loading) return;
    
              // 设置flag
              loading = true;
    
              // 模拟1s的加载过程,实际项需要调用ajax向后台取数据
           
                  // 重置加载flag
              axios.get('./src/assets/data/worksRank.json', {
                  page: page,
                  val: ""
                }).then(function (response) {
                  loading = false;
    
                  
                  //添加判断条件  如果返回的数组的数据小于每页应当加载的数据条数,则表示加载完毕
                  if (response.data.length < itemsPerLoad) {
                      // 加载完毕,则注销无限加载事件,以防不必要的加载
                      $.detachInfiniteScroll($('.infinite-scroll'));
                      // 删除加载提示符
                      $('.infinite-scroll-preloader').remove();
                      return;
                  }
    
                  // 添加新条目
                  // _this.addWorks(response.data);
                  _this.worksList = _this.worksList.concat(response.data);
                  page++;
                  //容器发生改变,如果是js滚动,需要刷新滚动
                  $.refreshScroller();
                });
            });
          }

    然后在mounted内调用这两个函数,发现很快实现该无限加载的功能了。再继续研究下去,也受到一片文章的启发,其实所谓无限加载,不就是我们常说的分页么?

    改变思路如下:

    当页面滑动到底部的时候,仅仅增加页码,然后监听页码的变化,然后调用初始化时候的ajax请求,去请求后台数据。

          loadingMore(){
            var _this = this;
            // 注册'infinite'事件处理函数
            $(document).on('infinite', function() {
              // 如果正在加载,则退出
              if (_this.loading) return;
              // 设置flag
              _this.loading = true;
              // 无限加载,其实就是类似于分页的效果,增加页码
              _this.page++;
            });
          },
    
        watch: {
          page: function () {
            this.ajaxData();
          }
        }
    

    向后台请求数据,需要带两个参数,一个是页码page,一个是值val,该值是为了搜索功能使用。

    其他的操作全部放在ajax请求内部操作:

          ajaxData(){
            axios.get('./src/assets/data/works.json',{
              page: this.page,
              val: this.val
            }).then(function (response) {
              this.loading = false;
              // 为了美观,这里对获取到的推按进行了随机数的处理,实际项目中,不需要额外处理
              response.data.forEach(function (item, index) {
                var num = Math.ceil(Math.random()*162);
                num = num < 10 ? "00"+num : num < 100 ? "0" + num : num;
                item.src = item.src.replace(/[d]+/, num);
                // 预加载
                var img = new Image();
                img.src = item.src;
              });
    
              //添加判断条件  如果返回的数组的数据小于每页应当加载的数据条数,则表示加载完毕
              if (response.data.length < this.items) {
                  // 加载完毕,则注销无限加载事件,以防不必要的加载
                  $.detachInfiniteScroll($('.infinite-scroll'));
                  // 删除加载提示符
                  $('.infinite-scroll-preloader').remove();
                  return;
              }
              if (this.page == 1) {
                this.works = response.data;
              } else {
                this.works = this.works.concat(response.data);
              }
    
              // 如果是下拉刷新的话
              $.pullToRefreshDone('.pull-to-refresh-content');
    
            }.bind(this));
          },

    对于返回数据循环操作这一步可以不予关注,我这里主要是为了获取不同的图片,进行的随机数,实际请求过程中,每次返回的都是不同数据,不存在这一过程。

    还有一个判断 :

              if (this.page == 1) {
                this.works = response.data;
              } else {
                this.works = this.works.concat(response.data);
              }
    

     这里需要判断当前页码是否为1,如果为1的话,返回的数据直接赋值给works,如果不是1,则在原有值的基础上追加,目的是方便下拉刷新和搜索。

     原以为到这里,已经彻底完成工作,但是在多次测试之后发现,还有一个更大的bug在那呢!

     路由跳转之后,必须刷新页面,才能实现新页面的无限加载,发现该问题之后,立即意识到了问题之所在:

       由于路由点击之后,并没有为document绑定infinite事件,导致跳转之后的页面无法触发infinite事件,就无法实现无限加载。

    解决问题的思路在于:在路由跳转页面的时候,关闭之前组件绑定的infinite事件,而在新组件中重新绑定infinite事件。

    查询vue-router官方文档,发现“导航钩子”这一说法,共有三个钩子函数:

    • beforeRouteEnter
    • beforeRouteUpdate (2.2 新增)
    • beforeRouteLeave

    这里需要用到的是beforeRouteLeave,在路由跳转离开的时候,关闭当前页面注册的“无限滚动事件”,在新组件mounted的时候重新绑定无限滚动事件”,代码修改为:

       beforeRouteLeave (to, from, next) {
          this.page =1;
          $.detachInfiniteScroll($(".infinite-scroll"));
          next(true);
        },
    

      

        mounted(){
          $.init()
          this.refresh();
          this.ajaxData();
          this.loadingMore();
          $.attachInfiniteScroll($(".infinite-scroll"));
        },
    

    至此,使用vuejs搭配SUI-Mobile的瀑布流布局真正实现了,其中也遇到了各种槽点,初学vuejs,总得付出点填坑的代价的。  

  • 相关阅读:
    JS定义一个立即执行的可重用函数
    Git常用命令速记与入门
    设计的一些kubernetes面试题
    运维知识各种链接
    php7.2安装smbclient扩展
    logrotate自定义切割时间的一些坑
    【转】日志收集工具scribe
    ELK日志报警插件ElastAlert并配置钉钉报警
    consul-server集群搭建
    加油,骚年
  • 原文地址:https://www.cnblogs.com/zhuhuoxingguang/p/6742596.html
Copyright © 2020-2023  润新知