一. 首页 - 静态结构准备 & 动态渲染
目标:实现首页静态结构,封装接口,完成首页动态渲染
1. 首页静态结构和样式
layout / home.vue
<template>
<div class="home">
<!-- 导航条 -->
<van-nav-bar title="智慧商城" fixed />
<!-- 搜索框 -->
<van-search readonly shape="round" background="#f1f1f2" placeholder="请输入搜索关键词" @click="$router.push('/search')" />
<!-- 轮播图 -->
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item>
<img src="@/assets/1.png" alt="">
</van-swipe-item>
<van-swipe-item>
<img src="@/assets/2.jpg" alt="">
</van-swipe-item>
<van-swipe-item>
<img src="@/assets/3.png" alt="">
</van-swipe-item>
</van-swipe>
<!-- 导航-->
<van-grid column-num="5" icon-size="40">
<van-grid-item
v-for="item in 10" :key="item"
icon="photo"
text="新品首发" @click="$router.push('/category')" />
</van-grid>
<!-- 主会场 -->
<div class="main">
<img src="@/assets/3.png" alt="">
</div>
<!-- 猜你喜欢 -->
<div class="guess">
<p class="guess-title">-- 猜你喜欢 --</p>
<div class="goods-list">
<GoodsItem v-for="item in 10" :key="item"></GoodsItem>
</div>
</div>
</div>
</template>
<script>
import GoodsItem from '@/components/GoodsItem.vue'
export default {
name: 'HomeIndex',
components: {
GoodsItem
}
}
</script>
<style lang="less" scoped>
//主题 padding
.home{
// padding-top: 100px;
padding-top: 50px;
padding-bottom: 50px;
}
// 导航条样式定制
.van-nav-bar{
z-index: 999;
background-color: #c21401;
::v-deep .van-nav-bar__title{
color:#fff;
}
}
// 搜索框样式定制
.var-search{
position: fixed;
width: 100%;
top:46px;
z-index:999;
}
// 分类导航部分
.my-swipe .van-swipe-item{
height: 185px;
color:#fff;
font-size:20px;
text-align: center;
background-color: #39a9ed;
}
.my-swipe .van-swipe-item img{
widows: 100%;
height: 185px;
}
// 主会场
.main img{
display: block;
width: 100%;
}
// 猜你喜欢
.guess .guess-title{
height: 40px;
line-height: 40px;
text-align: center;
}
// 商品样式
.goods-list{
background-color: #f6f6f6;
}
</style>
2. 新建商品组件
components / GoodsItem.vue
<template>
<div class="goods-item" @click="$router.push('/prodetail')">
<div class="left">
<img src="" alt="">
</div>
<div class="right">
<p class="tit text-ellipsis-2">
XXXXXXXXXXXXXXXX
</p>
<p class="count">已售104件</p>
<p class="price">
<span class="new">¥3999.00</span>
<span class="old">¥6699.00</span>
</p>
</div>
</div>
</template>
<script>
export default {
name: 'GoodsItem'
}
</script>
<style lang="less" scoped>
.goods-item{
height: 148px;
margin-bottom: 6px;
padding: 10px;
background-color: #fff;
display: flex;
.left{
width: 127px;
img{
display: block;
width: 100%;
}
}
.right{
flex:1;
font-size: 14px;
line-height: 1.3;
padding: 10px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
.count{
color:#999;
font-size: 12px;
}
.price{
color:#999;
font-size: 16px;
.new{
color: #f03c3c;
margin-right: 10px;
}
.old{
text-decoration: line-through;
font-size:12px
}
}
}
}
</style>
3. 组件按需导入
utils / vant-ui.js
// 按需导入
import Vue from 'vue'
import {Search, Swipe, SwipeItem, Grid, GridItem} from 'vant'
Vue.use(Search)
Vue.use(Swipe)
Vue.use(SwipeItem)
Vue.use(Grid)
Vue.use(GridItem)
二. 首页 - 动态渲染
1. 封装首页请求接口
api / home.js
import request from '@/utils/request'
// 获取首页数据
export const getHomeDate = () => {
return request.get('/page/detail', {
params: {
pageId: 0
}
})
}
2. 首页请求数据并渲染
layout / home.vue
<template>
<div class="home">
<!-- 导航条 -->
<van-nav-bar title="智慧商城" fixed />
<!-- 搜索框 -->
<van-search readonly shape="round" background="#f1f1f2" placeholder="请输入搜索关键词" @click="$router.push('/search')" />
<!-- 轮播图 -->
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item v-for="item in bannerList" :key="item.imgUrl">
<img :src="item.imgUrl" alt="">
</van-swipe-item>
</van-swipe>
<!-- 导航-->
<van-grid column-num="5" icon-size="40">
<van-grid-item
v-for="item in navList" :key="item.imgUrl"
:icon="item.imgUrl"
text="新品首发"
@click="$router.push('/category')" />
</van-grid>
<!-- 主会场 -->
<div class="main">
<img src="@/assets/3.png" alt="">
</div>
<!-- 猜你喜欢 -->
<div class="guess">
<p class="guess-title">-- 猜你喜欢 --</p>
<div class="goods-list">
<GoodsItem v-for="item in proList" :key="item.goods_id" :item="item"></GoodsItem>
</div>
</div>
</div>
</template>
<script>
import { getHomeDate } from '@/api/home'
import GoodsItem from '@/components/GoodsItem.vue'
export default {
name: 'HomeIndex',
components: {
GoodsItem
},
data () {
return {
bannerList: [], // 轮播
navList: [], // 导航
proList: [] // 商品
}
},
async created () {
const { data: { pageData } } = await getHomeDate()
this.bannerList = pageData.items[1].data
this.navList = pageData.items[3].data
this.proList = pageData.items[6].data
console.log(this.proList)
}
}
</script>
<style lang="less" scoped>
...
</style>
3. 父传子渲染商品列表
components / GoodsItem.vue
<template>
<div v-if="item.goods_id" class="goods-item" @click="$router.push(`/prodetail/${item.goods_id}`)">
<div class="left">
<img :src="item.goods_image" alt="">
</div>
<div class="right">
<p class="tit text-ellipsis-2">
{{ item.goods_name }}
</p>
<p class="count">已售 {{ item.goods_sales }} 件</p>
<p class="price">
<span class="new">¥{{ item.goods_price_min }}</span>
<span class="old">¥{{ item.goods_price_max }}</span>
</p>
</div>
</div>
</template>
<script>
export default {
name: 'GoodsItem',
props: {
item: {
type: Object,
default: () => {
return {}
}
}
}
}
</script>
<style lang="less" scoped>
...
</style>