vue项目实现商品懒加载和轮播效果

1.需要的文件

        注意先要在终端下载Element-ui框架,axios接口,stylus语言,

2.效果展示

 

 

 

3.视图页面:views

Home.vue

<template>
  <div class="home">
    <!-- 轮播 start -->
    <el-carousel :interval="1000" type="card" height="300px">
      <el-carousel-item v-for="item in banners" :key="item._id">
        <!--/detail?menuId=5d83bfba2f7cb93a4009cf98-->
        <router-link to="{name:'detail',query:{menuId.item._id}}">
          <img :src="item.product_pic_url" width="100%" alt="" />
        </router-link>
      </el-carousel-item>
    </el-carousel>
    <div>
      <h2>内容精选</h2>
      <waterfall ref="waterfall" @view="loadingMenuHanle">
        <menu-card :margin-left="13" :info="menuList"></menu-card>
      </waterfall>
    </div>
  </div>
</template>
<script>
import MenuCard from "@/components/menu-card.vue";
import Waterfall from "@/components/waterfall.vue";
import { getBanner, getMenus } from "@/service/api.js";
export default {
  name: "home",
  components: {
    MenuCard: MenuCard,
    Waterfall,
  },
  data() {
    return {
      banners: [],
      menuList: [],
      page: 1,
    };
  },
  mounted() {
    getBanner().then(({ data }) => {
      this.banners = data.list;
    }),
      getMenus({ page: this.page }).then(({data}) => {
        this.menuList = data.list;
        this.pages=Math.ceil(data.total/data.page_size);
      });
  },
  methods: {
    loadingMenuHanle() {
      this.page++;
      if(this.page>this.pages){
        this.$refs.waterfall.isloading = false;
        return;
      }
      this.$refs.waterfall.isloading = true;
      getMenus({ page: this.page }).then(({data}) => {
        this.menuList.push(...data.list);
         this.$refs.waterfall.isloading = false;
      });
    },
  },
};
</script>
<style lang="stylus">
.home {
  h2 {
    text-align: center;
    padding: 20px 0;
  }
  .el-carousel__item h3 {
    color: #475669;
    font-size: 14px;
    opacity: 0.75;
    line-height: 200px;
    margin: 0;
  }
  .el-carousel__item:nth-child(2n) {
    background-color: #99a9bf;
  }
  .el-carousel__item:nth-child(2n+1) {
    background-color: #d3dce6;
  }
}
</style>

 5.组件零部件components

header.vue

<template>
  <el-header style="height: auto;">
    <div class="header">
      <div class="header_c">
        <el-row type="flex" justify="start" align="middle">
          <el-col :span="6">
            <a href="" class="logo">
            </a>
          </el-col>
          <el-col :span="10" :offset="2"></el-col>
          <el-col :span="6" :offset="3" class="avatar-box">
            <router-link to="">
              <el-avatar style="vertical-align: middle;" shape="square" size="medium" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201604%2F03%2F20160403103054_uUzLm.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1634978424&t=e387c3862dab6ca1c8239263e91f0a38"></el-avatar>
            </router-link>
            <router-link to="" class="user-name">    {{userInfo.name}}</router-link>
            <router-link to="" class="collection">发布菜谱</router-link>
            <a href="javascript:;"  class="collection">退出</a>
          </el-col>
          <el-col :span="6" :offset="3" class="avatar-box" >
            <router-link to="" class="user-name">登录</router-link>
            <router-link to="" class="collection">注册</router-link>
          </el-col>
        </el-row>
      </div>
    </div>
    <div class="nav-box">
      <div class="nav_c">
        <Menus></Menus>
      </div>
    </div>
  </el-header>
</template>
<script>
import Menus from '@/components/menus'
import {login_out} from '@/service/api'
export default {
  name: 'headers',
  components: {Menus},
  computed:{
    
  },
  methods:{
    
  }
}
</script>
<style lang="stylus">
.header 
  height 129px
  background-color #c90000
  .logo 
    display: block;
    height: 129px;
    width: 184px;
    background url(https://s1.c.meishij.net/n/images/logo2.png) -15px 9px no-repeat;
.header_c, .nav_c
  width 990px
  margin 0 auto 
.nav-box 
  height 60px
  background-color #fff;
  box-shadow 10px 0px 10px rgba(0,0,0,0.3)
.user-name
  margin-left 5px
  color #fff
.collection 
  margin-left 5px  
  color #fff
</style>

        waterfall.vue        

<template>
  <div class="waterfall" ref="waterfall">
    <slot></slot>
    <!-- 实现图片加载 -->
    <div class="waterfall-loading" ref="loading" v-show="isloading">
      <i class="el-icon-loading"></i>
    </div>
  </div>
</template>
<script>
import {throttle} from "throttle-debounce"
export default {
  name: "Waterfall",
  data() {
    return {
      isloading: false,
    };
  },
  mounted() {
    this.scrollHanle = throttle(300,this.scroll.bind(this));
    window.addEventListener("scroll", this.scrollHanle);
  },
  destroyed() {
    window.addEventListener("scroll", this.scrollHanle);
  },
  methods: {
    scroll() {
      if(this.isloading) return;
      if (this.$refs.waterfall.getBoundingClientRect().bottom <document.documentElement.clientHeught)
        this.isloading = true;
        this.$emit("view");
      },
    },
};
</script>
<style lang="stylus">
.waterfall-loading {
  width: 100%;
  height: 20px;
  text-align: center;
}
</style>

 menu-card.vue

<template>
  <el-row class="menu-card" type="flex" justify="start">
    <el-colstyle="flex:none;" :style="{'margin-left':marginLeft+'px'}"v-for="item in info" :key="item._id">
    <el-card :body-style="{ padding: '0px' }">
       <router-link :to="{name:'detail',query:{menuId:item._id}}">
       <img :src="item.product_pic_url" class="image" style="width: 232px;height:232px;">
          <div style="padding: 14px;" class="menu-card-detail">
            <strong>{{item.title}}</strong>
            <span>{{item.comments_len}} 评论</span>
            <router-link :to="{name:'space',query:{userId:item.userId}}" tag="em">
              {{item.name}}
            </router-link>
          </div>
        </router-link> 
      </el-card>
    </el-col>
  </el-row>
</template>
<script>
export default {
  name: 'menu-card',
  props:{
    marginLeft: {
      type: Number,
      default: 22
    },
    info:{
      type: Array,
      default:() => []
    }
  }
}
</script>
<style lang="stylus">
.menu-card 
  flex-wrap wrap
  .el-col-24
    width auto
    margin-bottom 20px
    margin-left: 22px
  .menu-card-detail
    > *
      display block
    strong 
      height 24px
      line-height 24px
      font-size 14px
      font-weight bold
      color #333
    span 
      height 26px
      line-height 26px
      font-size 12px
      color #999
    em 
      height 23px
      line-height 23px
      font-size 12px
      color #ff3232
</style>

6.App.vue(父组件)

<template>
  <div id="app">
    <el-container>
      <Header></Header>
      <el-main>
        <div class="main">
          <router-view></router-view>
        </div>
      </el-main>
      <el-footer>
        <div class="footer">
          Copyright © 2019 - 2019 
        </div>
      </el-footer>
    </el-container>
  </div>
</template>
<script>
import Header from '@/components/header'
export default {
  components: {
    Header
  }
}
</script>
<style lang="stylus">
body 
  background: #fae8c8
  font-size 12px
.main
  width 990px
  margin 0 auto
.footer
  text-align center
  height 42px
  line-height 42px
</style>

7.main.js 入口文件

import Vue from 'vue'
import App from './App.vue'
import store from './store/'
import router from './router/index.js'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
Vue.config.productionTip = false
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值