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')