waterfall.vue 7.21 KB
<!--瀑布流组件-->
<template>
  <div ref="waterfall" class="water-fall-container" @scroll="scroll">
    <water-fall ref="waterfallComp"
      :col="col"
      :width="itemWidth"
      :gutter-width="gutterWidth"
      :data="articleList"
      :scrollTop="scrollTop"
      :page="listInfo.pageNo"
      @loadmore="loadMore">
      <template>
        <div class="cell-item" v-for="(item, index) in articleList" :key="index">
          <div class="item-image" :data-id="item.articleId" @click="gotoDetailPage">
            <div :class="['icon', item.sort === 4 ? 'icon-play' : '', item.sort === 1 ? 'icon-note' : '']"></div>
            <img :src="item.coverImage">
<!--            <img :src="item.resourceSrc" v-else-if="item.dataType === 2">-->
          </div>
          <div class="item-info">
            <p v-if="item.content" class="item-title">{{item.content}}</p>
            <div class="user-info">
              <div class="user-head">
                <img :src="item.authorHeadIco">
              </div>
              <p class="user-name">{{item.authorName}}</p>
              <div class="zan-container" :data-praised="item.hasPraised" :data-index="index" :data-id="item.articleId" @click="updatePraise">
                <i :class="[item.hasPraised === 'Y' ? 'iconzan-fill' : 'iconzan_n', 'iconfont', 'btn-zan']"></i>
                <p class="zan-count">{{item.praiseCount ? item.praiseCount : '赞'}}</p>
              </div>
            </div>
          </div>
        </div>
      </template>
    </water-fall>
    <div class="load-text">{{loadText}}</div>
  </div>
</template>

<script>
import WaterFall from '../../../components/waterfall/waterfall';
import {mapState, createNamespacedHelpers} from 'vuex';

const {mapActions} = createNamespacedHelpers('article/articleList');

export default {
  name: 'waterFallList',
  components: {WaterFall},
  props: {
    listData: { // 列表数据
      type: Array,
      default() {
        return [];
      }
    },
    listInfo: { // 列表基础信息
      type: Object,
      default() {
        return {};
      }
    },
    itemW: { // 每一个ariticleItem的宽度
      type: Number,
      default: 344
    },
    gutterW: { // item之间的间隔宽度
      type: Number,
      default: 18
    },
    isLoading: { // 是否正在调用列表接口
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      col: 2,
      scrollTop: 0, // 页面滚动高度
      isLogin: false, // 是否登录
      loadText: '', // 加载新列表提示文字
    };
  },
  computed: {
    ...mapState(['yoho']),
    articleList() {
      console.log('listData=', this.listData);
      return this.listData;
    },
    itemWidth() {
      let width = 0;

      if (document) {
        width = (this.itemW * 0.5 * (document.documentElement.clientWidth / 375));
      }

      return width;
    },
    gutterWidth() {
      let gutwidth = 0;

      if (document) {
        gutwidth = (this.gutterW * 0.5 * (document.documentElement.clientWidth / 375));
      }

      return gutwidth;
    },
  },
  watch: {
    'yoho.context.isLogin': function(val) {
      // this.isLogin = val;
    },
    isLoading(newVal) {
      if (newVal === true) {
        this.loadText = '加载中...';
      } else {
        this.loadText = '';
      }
    }
  },
  mounted() {
    console.log('mounted');
    this.checkLogin();
  },
  methods: {
    loadMore() {
      this.$emit('load-more');
    },
    scroll() {
      // console.log(this.$refs.waterfall.scrollTop);
      this.scrollTop = this.$refs.waterfall.scrollTop;
      this.$refs.waterfallComp.emitLoadMore();
    },
    async checkLogin() {
      const user = await this.$sdk.getUser(true);

      if (user.uid) {
        this.isLogin = true;
      }
    },
    gotoDetailPage(e) { // 跳转详情页
      let articleId = e.currentTarget.dataset.id;

      if (articleId) {
        this.$router.push({
          name: 'ArticleDetail',
          params: {
            articleId: articleId
          }
        });
      }
    },
    updatePraise(e) { // 点赞
      if (this.isLogin) {
        let articleId = e.currentTarget.dataset.id;
        let index = e.currentTarget.dataset.index;
        let status = e.currentTarget.dataset.praised === 'Y' ? 1 : 0;

        console.log(articleId, index, status);
        this.$emit('update-praise', {articleId, status, index});
      } else {
        this.$yoho.auth();
      }
    },
    scrollToOldPlace() { // 从详情页路由回来时,滚动到原来的位置
      console.log('scrollTop=', this.scrollTop);
      if (!this.isLogin) {
        this.checkLogin();
      }

      this.$refs.waterfall.scrollTo(0, this.scrollTop);
    }
  }
};
</script>

<style lang="scss">
  .water-fall-container {
    padding: 24px 20px 0 20px;
    background-color: #efefef;
    height: 100%;
    overflow-x: hidden;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
    z-index: 1;

    .load-text {
      text-align: center;
      color: #999;
      font-size: 30px;
      line-height: 30px;
    }

    img {
      width: 100%;
      float: left;
    }

    .item-image {
      position: relative;
      width: 100%;
      border-radius: 16px 16px 0 0;
      overflow: hidden;

      .icon {
        width: 40px;
        height: 40px;
        position: absolute;
        right: 12px;
        top: 12px;
        background-size: 100% 100%;
        z-index: 9;

        &.icon-play {
          background-image: url("../../../statics/image/article/icon_list_play.png");
        }

        &.icon-note {

        }
      }
    }

    .cell-item {
      margin-bottom: 16px;

      .item-info {
        background-color: #fff;
        border-radius: 0 0 16px 16px;

        .item-title {
          padding: 8px 20px 0 20px;
          max-height: 80px;
          line-height: 40px;
          font-weight: 600;
          font-size: 28px;
          display: -webkit-box;
          -webkit-line-clamp: 2;
          -webkit-box-orient: vertical;
          word-break: break-all;
          overflow: hidden;
        }

        .user-info {
          position: relative;
          padding: 0 20px;
          height: 70px;
          display: flex;
          align-items: center;

          .user-head {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            overflow: hidden;
          }

          .user-head img {
            height: 100%;
          }

          .user-name {
            display: inline-block;
            min-width: 20px;
            max-width: 150px;
            white-space: nowrap;
            overflow: hidden;
            font-size: 24px;
            font-weight: 300;
            padding-left: 8px;
            text-overflow: ellipsis;
          }

          .zan-container {
            position: absolute;
            display: flex;
            right: 0;
            width: 120px;
            height: 34px;
            align-items: center;
          }

          .btn-zan {
            font-size: 34px;
          }

          .btn-zan.iconzan-fill {
            color: #c30016;
          }

          .zan-count {
            display: inline-block;
            font-size: 26px;
            margin-left: 12px;
            max-width: 60px;
            white-space: nowrap;
            overflow: hidden;
          }
        }
      }
    }
  }
</style>