目录
- 前言:
- 具体实现思路:
- 步骤:
- 1. 展示美食杰项目首页效果
- 2. 引入 element-ui
- 3. 头部代码
- 4. 首页内容总代码
- 5. 轮播图代码
- 6. 已发布菜品内容代码
- 7. 加载图片页面代码
- 总结:
前言:
本文给大家讲解,美食杰项目中首页实现的效果,和具体代码。
具体实现思路:
- 向后端请求数据,获取数据,渲染数据
- 引入 element-ui
- 刷新后加载新图片
步骤:
头部代码中包含了一部分登录功能,这个功能在本文没有实现,想要知道的,可以看我发布的实现登录注册功能的文章。
在 加载图片页面代码中,使用了节流 throttle-debounce,节流的具体使用可以看官方文档。
点击跳转至节流的官方文档:https://www.npmjs.com/package/throttle-debounce
点击跳转至 element-ui 官方文档:https://element.eleme.cn/#/zh-CN/component/installation
1. 展示美食杰项目首页效果
美食杰首页
2. 引入 element-ui
- 下载 element-ui
npm i element-ui -S
- 在 main.js 中引入 element-ui
import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
3. 头部代码
<template>
<div class="box">
<div class="top">
<div class="center">
<a href="" class="left">
<img src="@/assets/logos.png" alt="" />
</a>
<!-- 判断是否登录,不登录则显示 -->
<div class="right" v-if="!islogin">
<router-link :to="{ name: 'login' }">登录</router-link>
<router-link :to="{ name: 'login' }">注册</router-link>
</div>
<!-- 判断是否登录,登录则显示 -->
<div class="right rights" v-if="islogin">
<router-link :to="{ name: 'MyHomepage' }">
<img :src="userInfo.avatar" alt="" />
</router-link>
<router-link :to="{ name: 'MyHomepage' }">{{
userInfo.name
}}</router-link>
<router-link to="PublishRecipes">发布菜谱</router-link>
<button @click="quit">退出</button>
</div>
</div>
</div>
<div class="bottom">
<el-menu
:default-active="activeIndex"
class="el-menu-demo center"
mode="horizontal"
>
<el-menu-item index="1" class="el-menu-item">
<router-link :to="{ name: 'page' }">首页</router-link>
</el-menu-item>
<el-menu-item index="2">
<router-link :to="{ name: 'recipes' }">菜谱大全</router-link>
</el-menu-item>
</el-menu>
</div>
</div>
</template>
<script>
import { mapGetters, mapState } from "vuex";
import { login_out } from "@/connector/api";
export default {
data() {
return {
activeIndex: "1",
activeIndex2: "1",
};
},
computed: {
// 获取 vuex 里的内容
...mapGetters(["islogin"]),
...mapState(["userInfo"]),
},
methods: {
// 点击退出登录
quit() {
login_out().then((data) => {
if (data.code === 0) {
// 删除本地存储的 token
localStorage.removeItem("token");
// 跳转至首页
window.location.href = "/";
}
});
},
},
};
</script>
<style lang="scss" scoped>
.box {
width: 100%;
.top {
width: 100%;
height: 129px;
background-color: #c90000;
.center {
width: 990px;
height: 100%;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
.left {
width: 213.75px;
}
.right {
width: 213.75px;
a {
font-size: 12px;
text-decoration: none;
color: #fff;
margin-left: 5px;
}
}
.rights {
display: flex;
align-items: center;
a {
img {
width: 36px;
height: 36px;
}
}
button {
font-size: 12px;
color: #fff;
margin-left: 5px;
border: none;
background-color: #c90000;
}
}
}
}
.bottom {
width: 100%;
height: 60px;
background-color: #ffffff;
.center {
width: 990px;
height: 100%;
margin: 0 auto;
line-height: 60px;
.el-menu-item {
a {
display: inline-block;
width: 100%;
height: 100%;
text-decoration: none;
}
}
}
}
}
</style>
4. 首页内容总代码
<template>
<div class="box">
<!-- :banner="banner" 是父传子事件,和它类似的也是 -->
<!-- @Scroll="Scroll" 是子传父事件 -->
<!-- ref="Loading" 可以获取子组件的内容 -->
<!-- Banner:轮播图,Roll:内容,Loading:加载图片 -->
<Banner :banner="banner"></Banner>
<Roll :menus="menus"></Roll>
<Loading @Scroll="Scroll" ref="Loading"></Loading>
<div class="bottom">Copyright © 2019 - 2019</div>
</div>
</template>
<script>
import Banner from "./banner.vue";
import Roll from "./roll.vue";
import Loading from "./loading.vue";
import { getMenus, getBanner } from "@/connector/api";
export default {
components: {
Banner,
Roll,
Loading,
},
data() {
return {
// 轮播图
banner: [],
// 已发布菜品
menus: [],
// 页数
pages: 1,
// 总数
total: "",
// 一页显示多少个
page_size: "",
};
},
// 进入时触发
mounted() {
// 获取轮播图的内容
getBanner().then(({ data }) => {
// console.log(data);
// 赋值给 banner
this.banner = data.list;
});
// 根据页数获取已发布菜品的内容
getMenus({ page: this.pages }).then(({ data }) => {
// console.log(data);
// 内容
this.menus = data.list;
// 总数
this.total = data.total;
// 一页几条
this.page_size = data.page_size;
});
},
// 点击时触发
methods: {
Scroll() {
// 页数 + 1
this.pages++;
// 判断当前页数是否等于最后的页数
if (this.pages == Math.ceil(this.total / this.page_size)) {
// 等于则关闭 加载图片
this.$refs.Loading.loading = false;
// 下面的代码不在执行
return;
}
// 显示 加载图片
this.$refs.Loading.loading = true;
// 根据页数获取已发布菜品的内容
getMenus({ page: this.pages }).then(({ data }) => {
// console.log(loading);
// 追加到 menus 里面
this.menus.push(...data.list);
// 关闭 加载图片
this.$refs.Loading.loading = false;
});
},
},
};
</script>
<style lang="scss" scoped>
.box {
width: 990px;
margin: 20px auto 0;
.bottom {
text-align: center;
margin-top: 20px;
}
}
</style>
5. 轮播图代码
点击跳转至 element-ui 中轮播图使用方法:https://element.eleme.cn/#/zh-CN/component/carousel
<template>
<div class="box">
<!-- element-ui 里的轮播图 -->
<el-carousel :interval="4000" type="card" height="300px">
<el-carousel-item v-for="item in banner" :key="item._id">
<router-link
:to="{ name: 'DishesInformation', query: { menuId: item.menuId } }"
>
<img :src="item.product_pic_url" alt="" />
</router-link>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
export default {
// props 接收父组件传递过来的值
props: {
banner: {
// type 元素类型
type: Array,
// default 默认值
default: () => [],
},
},
};
</script>
<style>
.el-carousel__item a img {
color: #475669;
font-size: 14px;
opacity: 0.75;
line-height: 300px;
margin: 0;
width: 100%;
height: 300px;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n + 1) {
background-color: #d3dce6;
}
</style>
6. 已发布菜品内容代码
<template>
<div class="box">
<!-- :class="{ h2: id === 234 }" 判断 id 是否为 234 不是的话使用前面的 class 标签 -->
<h2 :class="{ h2: id !== 234 }">内容精选</h2>
<ul class="banner">
<li
v-for="item in menus"
:key="item._id"
ref="list"
:class="{ 'banner-li': id === 170 }"
>
<!-- 和上文大致意思相同 -->
<router-link
:to="{ name: 'DishesInformation', query: { menuId: item.menuId } }"
>
<img :src="item.product_pic_url" alt="" />
</router-link>
<div>
<router-link
:to="{ name: 'DishesInformation', query: { menuId: item.menuId } }"
>
<b>{{ item.title }}</b>
</router-link>
<p>{{ item.comments_len }} 评论</p>
<router-link
:to="{ name: 'MyHomepage', query: { userId: item.userId } }"
>
<p>{{ item.name }}</p>
</router-link>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
// props 接收父组件传递过来的值
// type 元素类型
// default 默认值
props: {
menus: {
type: Array,
default: () => [],
},
// 因为要在好几个地方使用所以传递过来一个值,用来判断在哪里使用
id: {
type: Number,
default: 234,
},
},
};
</script>
<style lang="scss" scoped>
.box {
width: 990px;
padding: 0;
h2 {
text-align: center;
font-weight: 400;
padding: 20px 0;
}
.banner {
display: flex;
flex-wrap: wrap;
padding: 0;
width: 100%;
li {
display: inline-block;
width: 234px;
// width: 23.4%;
height: 338px;
list-style: none;
background-color: #fff;
margin: 0 0 20px 13px;
border: 1px solid #ebeef5;
a {
text-decoration: none;
img {
width: 99.8%;
height: 63%;
}
b {
height: 24px;
line-height: 24px;
font-size: 12px;
color: #333;
}
p {
width: 95%;
margin: 0 auto;
font-size: 12px;
height: 23px;
line-height: 23px;
color: #ff3232 !important;
}
}
div {
padding: 20px;
}
p {
width: 204px;
margin: 0 auto;
font-size: 12px;
height: 26px;
line-height: 26px;
color: #999;
}
}
.banner-li {
width: 160px !important;
height: 264px;
}
}
.h2 {
display: none;
padding: none;
}
}
</style>
7. 加载图片页面代码
点击跳转至 element-ui 中加载使用方法:https://element.eleme.cn/#/zh-CN/component/loading
<template>
<div class="box">
<!-- element-ui 中加载的图片 -->
<i
v-loading="loading"
element-loading-spinner="el-icon-loading"
ref="loadings"
>
</i>
</div>
</template>
<script>
// 引入节流
import { throttle } from "throttle-debounce";
export default {
data() {
return {
// 是否显示
loading: false,
};
},
// 进入当前页面时触发
mounted() {
// 使用节流
this.handleScroll = throttle(300, this.handleScroll.bind(this));
// 给当前页面全局绑定 滚动条 事件
window.addEventListener("scroll", this.handleScroll);
},
// 离开当前页面时触发
destroyed() {
// 删除 滚动条 事件
window.removeEventListener("scroll", this.handleScroll);
},
methods: {
handleScroll() {
// 为 true 则停止向下执行
if (this.loading) return;
// 判断 加载图片距离顶部的高 是否小于 可视窗口
if (
this.$refs.loadings.getBoundingClientRect().bottom <
document.documentElement.clientHeight
) {
// console.log("滚动到指定位置");
// 小于则显示 加载图片
this.loading = true;
// 子传父事件
this.$emit("Scroll");
}
},
},
};
</script>
<style lang="scss" scoped>
.box {
text-align: center;
height: 20px;
}
</style>
总结:
总结:
以上就是 美食杰项目 中 首页的具体实现方法,不懂得也可以在评论区里问我,以后会持续发布一些新的功能,敬请关注。
我的其他文章:https://blog.csdn.net/weixin_62897746?type=blog