waterfall.vue 5.49 KB
<!--
 * @description:
 * @fileName: waterfall.vue
 * @author: huzhiming
 * @date: 2019-12-18 15:23:55
 * @后台人员:
 * @version: v1.0.0
 * @path: 页面访问路径及参数说明
!-->
<template>
  <div class="article-waterfall-wrap">
    <horizontalSlide v-model="items" :style="{'margin': '20px 0 0 12px'}"></horizontalSlide>
    <!-- <div class="water">
      <div class="piping" ref="piping0"></div>
      <div class="piping" ref="piping1"></div>
      <div class="piping" ref="piping2"></div>
      <div class="piping" ref="piping3"></div>
    </div> -->
  </div>
</template>

<script>
import axios from 'axios';

import horizontalSlide from './components/horizontalSlide'

export default {
  name: 'Article',
  mixins: [],
  props: {},
  // 服务端渲染函数
  async asyncData ({ isDev, route, store, env, params, query, req, res, redirect, error }) {
    return {}
  },
  data() {
    return {
      items: [...Array(20).keys()].map(item => item),

      moments: [],
      available: 1,
      height1: 0,
      height2: 0,
      height3: 0,
      page: 1
    }
  },
  created() {
    // 获取第一页数据
    // this.fetchMoments();
  },
  mounted() {
    // 用来监听滚轮
    window.addEventListener("scroll", this.handleScroll);
  },
  activated() {},
  deactivated() {},
  // beforeRouteEnter (to, from, next) {},
  // beforeRouteUpdate(to, from, next) {},
  // beforeRouteLeave(to, from, next) {},
  destroyed() {},
  methods: {
    fetchMoments() {
      // 请求接口方法
      // const result = await this.$api.post('https://m.yohobuy.com/grass/api/grass/topicRelatedArticles', {
      //   page,
      //   limit: limit || 10,
      //   type: 6,
      //   topicId: 2713
      // });

      axios.get('https://m.yohobuy.com/grass/api/grass/topicRelatedArticles')
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });


      // https://m.yohobuy.com/grass/api/grass/topicRelatedArticles
    },
    // sort()函数是递归的,因为要确保每个卡片的图片加载完成后再获取管道的高度,但是图片加载完成的函数是个异步函数,
    // 如果放在for循环中会打乱顺序,因此要使异步函数同步执行,for循环改为递归。
    sort(j) {
      if (j < this.moments.length) {
        let that = this;
        // 创建Image类
        var newImg = new Image();
        // 获取要加载的图片地址
        newImg.src =
          "http://lanyue.ink:8123/images/" +
          (Math.floor(Math.random() * 15) + 1) +
          ".png";
        // 图片加载完成后(异步)
        newImg.onload = () => {
          // 四个管道的高度
          var arr = [
            that.$refs.piping0.offsetHeight,
            that.$refs.piping1.offsetHeight,
            that.$refs.piping2.offsetHeight,
            that.$refs.piping3.offsetHeight
          ];
          //获取管道最小高度
          var min = arr.indexOf(Math.min.apply(Math, arr));
          // 添加卡片的模板
          var html =
            `<div class="card">
                <img src=` + newImg.src + `>
                <div>
                  <img src="http://lanyue.ink:8123/images/avatar.jpg" alt="">
                  <div>` + this.moments[j].id + "  " + this.moments[j].content + `</div>
                </div>
            </div>`;
          //给最小的管道添加卡片
          if (min == 0) {
            that.$refs.piping0.innerHTML += html;
          } else if (min == 1) {
            that.$refs.piping1.innerHTML += html;
          } else if (min == 2) {
            that.$refs.piping2.innerHTML += html;
          } else if (min == 3) {
            that.$refs.piping3.innerHTML += html;
          }
          that.sort(j + 1);
        };
      }
    },
    handleScroll() {
      // 获取滚轮位置
      var scrollTop =
        window.pageYOffset ||
        document.documentElement.scrollTop ||
        document.body.scrollTop;
      this.height1 = scrollTop;
      // 文档高度
      this.height2 = document.body.scrollHeight;
      // 可视区域
      this.height3 =
        document.compatMode == "CSS1Compat"
          ? document.documentElement.clientHeight
          : document.body.clientHeight;
      // 如果滚动到最低(这里设置离最底还有100距离才触发函数)
      // available条件是为了防止触底时一直不断地请求。因此,请求一次后available设为0,直到滚动到离底部超过100距离(即数据加载玩后)才设为1
      if (this.height3 + this.height1 >= this.height2 - 100 && this.available) {
        //请求下一页
        this.page++;
        this.available = 0;
        let that = this;
        fetch("api/moments?page=" + this.page)
          .then(res => res.json())
          .then(res => {
            that.moments = res.data;
            if (that.moments[0]) {
              that.sort(0);
            } else {
              that.page--;
            }
          });
      } else if (this.height3 + this.height1 < this.height2 - 100) {
        this.available = 1;
      }
    }
  },
  computed: {},
  watch: {},
  components: {
    horizontalSlide
  }
};
</script>

/* 定义局部样式,添加外围容器,scss嵌套尽量不要超过三层,会影响查找器性能 */
<style rel='stylesheet/scss' lang='scss' scoped>
.waterfall-wrap {}
//@import "./style.scss";
</style>

/* 定义全局样式,添加外围容器,避免覆盖全局样式, 若不需要,请删除 */
<style rel='stylesheet/scss' lang='scss'>
.waterfall-wrap {}
</style>