channel.vue 5.72 KB
<template>
  <LayoutApp class="yohoufo-channel-page" :show-back="true" :hide-header="hideHeader">
      <div class="fixed-nav scroll-nav-wrap" v-if="isShow && navList.length">
        <ScrollNav :list="navList" :current="active" @transfer="getIndex"></ScrollNav>
      </div>
      <Scroll
        ref="scroll"
        :scroll-events="scrollEvents"
        @scroll="scrollHandler"
        :options="options"
        @pulling-up="onPullingUp"
        @pulling-down="onPullingDown"
        :data="productList.list">
        <div class="channel-body" ref="body">
          <div ref="topSource" class="channel-html">
            <template v-for="(item, index) in channelList.list">
              <Swiper :list="item.data" :key="index" v-if="item.template_name == 'threePicture'"/>
              <Hot :list="item.data" :key="index" v-if="item.template_name == 'image_list'"/>
              <Banner :list="item.data" :key="index" v-if="item.template_name == 'single_image'"/>
              <TwoBanner :list="item.data" :key="index" v-if="item.template_name == 'twoPicture'"/>
            </template>
          </div>
          <div ref="scrollNav" class="scroll-nav-wrap" v-if="navList.length">
            <ScrollNav :list="navList" :current="active" @transfer="getIndex"></ScrollNav>
          </div>
          <div class="list-wrap" :style="{minHeight: total + 'px'}">
            <ProductList :list="productList.list" v-if="productList.list.length > 0"></ProductList>
            <UfoNoItem :tip="`暂无数据`" v-else></UfoNoItem>
          </div>
        </div>
      </Scroll>
  </LayoutApp>
</template>

<script>
import { get, find } from 'lodash';
import { Style, Scroll, Sticky } from 'cube-ui';
import { createNamespacedHelpers } from 'vuex';
import queryString from 'query-string';
import Swiper from './components/swiper';
import Banner from './components/banner';
import TwoBanner from './components/twoBanner';
import Hot from './components/hot';
import ScrollNav from './components/scrollNav';
import ProductList from '../../list/components/productList';
import { setTimeout } from 'timers';
import UfoNoItem from '../../../components/ufo-no-item';

const { mapState, mapActions } = createNamespacedHelpers('home/channel');
const { mapState: mapStateList, mapActions: mapActionsList } = createNamespacedHelpers('list');

export default {
  props: ['hideHeader'],
  data() {
    return {
      options: {
        // bounce: {
        //   top: false
        // },
        scrollbar: true,
        pullUpLoad: true,
        pullDownRefresh: true,
        pullDownRefresh: {
          txt: '刷新成功',
        }
      },
      scrollEvents: ['scroll'],
      scrollY: 0,
      navTop: 0,
      navHeight: 0,
      isShow: false,
      total: 0,
      active: 0,
      listBaseParams: {
        isHome: true,
      }
    };
  },
  computed: {
    ...mapState(['channelList']),
    ...mapStateList(['productList']),
    navList() {
      return get(find(this.channelList.list, ['template_name', 'guessLike']), 'data') || [];
    }
  },
  watch: {
    'channelList.list': function() {
      this.init();
    }
  },
  activated() {
    if (!this.channelList.list || !this.channelList.list.length) {
      this.fetchChannelList();
    }
  },
  async serverPrefetch() {
    return this.fetchChannelList();
  },
  mounted() {
    this.init();
  },
  methods: {
    ...mapActions(['fetchChannelList']),
    ...mapActionsList(['fetchProductList']),
    init() {
      this.$nextTick(() => {
        this.navTop = this.$refs.topSource.offsetHeight;
        this.navHeight = get(this.$refs, 'scrollNav.offsetHeight') || 0;
        this.total = this.$refs.scroll.$el.offsetHeight - this.navHeight;
        this.refreshProductList(this.active);
      });
    },
    getIndex(index) {
      this.active = Number(index);
    },
    scrollHandler({ y }) {
      if (this.navTop) {
        let scrollY = -y;

        if (scrollY >= this.navTop) {
          this.isShow = true;
        } else {
          this.isShow = false;
        }
      }
    },
    refreshProductList(index) {
      let str = get(get(this.navList, `[${index}].url`, '').split('?'), '[1]', '');

      this.params = Object.assign({}, queryString.parse(str), this.listBaseParams);
      this.fetchProductList(this.params);
    },
    async onPullingUp() {
      if (this.params) {
        this.params.isReset = false
        await this.fetchProductList(this.params);
      }
    },
    onPullingDown() {
      this.params.isReset = true
      this.fetchProductList(this.params);
    },
  },
  components: {
    Swiper,
    Banner,
    TwoBanner,
    Hot,
    ScrollNav,
    Style,
    Scroll,
    Sticky,
    cubeSticky: Sticky,
    cubeStickyEle: Sticky.Ele,
    ProductList,
    UfoNoItem
  }
};
</script>

<style lang="scss" scoped>
.yohoufo-channel-page {
  background-color: #fefefe;
}

.scroll-nav-wrap {
  position: relative;

  &:after {
    content: "";
    position: absolute;
    width: 100%;
    height: 0;
    box-shadow: 0 0 120px 100px #f2f2f2;
  }

  &.fixed-nav {
    width: 100%;
    position: absolute;
    z-index: 10;
    background-color: #fefefe;
    overflow: hidden;
  }
}

.channel-body {
  height: 100%;
  position: relative;

  &:before {
    content: "";
    width: 100%;
    height: 330px;
    background: #08304B;
    position: absolute;
    top: 0;
    z-index: -1;
  }
}

.channel-html {
  padding: 20px 24px 0;

  &:before {
    content: "";
    width: 520px;
    height: 28px;
    background-image: url("~statics/image/channel/server.png");
    background-size: 100% 100%;
    margin: 0 auto 20px;
    display: block;
  }

  &:after {
    content: "";
    width: 100%;
    height: 1px;
    display: block;
  }

  > * {
    margin-top: 20px;
  }
}

.list-wrap {
  background: #f2f2f2;

  /deep/ .item {
    position: relative;
    z-index: 1;
  }
}
</style>