Vue全栈开发旅游网项目首页
0. 展示效果:
书接上回:
https://blog.csdn.net/Tttian622/article/details/143212387?spm=1001.2014.3001.5502
1.“热门推荐”模块的制作:
位置:src\components\home\Hot.vue
1.1 <script>
模块:
列举各个景点信息
<script setup>
import { ref } from 'vue';
const hotList = ref([
{ id: 1, img: '/static/home/hot/h1.jpg', name: '景点名称', price: 65 },
{ id: 2, img: '/static/home/hot/h2.jpg', name: '景点名称', price: 65 },
{ id: 3, img: '/static/home/hot/h3.jpg', name: '景点名称', price: 65 },
{ id: 4, img: '/static/home/hot/h4.jpg', name: '景点名称', price: 65 },
{ id: 5, img: '/static/home/hot/h5.jpg', name: '景点名称', price: 65 },
{ id: 6, img: '/static/home/hot/h6.jpg', name: '景点名称', price: 65 },
{ id: 7, img: '/static/home/hot/h7.jpg', name: '景点名称', price: 65 },
{ id: 8, img: '/static/home/hot/h8.jpg', name: '景点名称', price: 65 },
{ id: 9, img: '/static/home/hot/h9.jpg', name: '景点名称', price: 65 },
{ id: 10, img: '/static/home/hot/h10.jpg', name: '景点名称', price: 65 }
])
</script>
1.2 <template>
模块:
其中RouterLink相当于a超链接,通过该标记,可访问路由列表,
最后根据地址访问目标。
<template>
<!-- 热门经典 -->
<div class="home-hot-box">
<!-- 顶上导航 -->
<van-cell title="热门推荐" is-link value="全部榜单" icon="/static/home/hot/fire.png" title-style="text-align:left" />
<!-- 经典列表 -->
<div class="box-main">
<RouterLink class="hot-item" v-for="item in hotList" :key="item.id" :to="`#`">
<div class="img">
<span class="span"></span>
<img :src="item.img" alt="">
</div>
<h5 class="van-ellipsis">{{ item.name }}</h5>
<div class="line-price">
<span class="price">¥{{ item.price }}</span>起
</div>
</RouterLink>
</div>
</div>
</template>
1.3 <style>
模块:
padding: 0 10px; //内边距:上下0px 左右10px
margin-right: 10px; //外边距
display: flex; //弹性布局
overflow: scroll; //无论内容是否溢出,元素都会提供滚动条。
flex-direction: column;
//flex-direction:决定弹性布局的方向(主轴方向),默认横向
//column:主轴为垂直方向,起点在上沿
position: relative; //相对定位
position: absolute; //绝对定位
no-repeat; //不平铺
<style lang="less">
.home-hot-box {
padding: 0 10px;
//设置顶上导航样式
.van-cell {
padding: 10px 0px;
}
// 经典列表样式
.box-main {
width: 100%;
display: flex;
padding-top: 10px;
overflow: scroll;
}
//热门元素
.hot-item {
display: flex;
flex-direction: column;
width: 100px;
margin-right: 10px;
padding-bottom: 10px;
//图片样式
.img {
position: relative;
.span {
position: absolute;
left: 0;
top: 0;
display: inline-block;
width: 42px;
height: 20px;
z-index: 10;
}
img {
width: 100px;
height: 100px;
}
}
h5 {
color: #212121;
padding: 2px 0;
font-size: 12px;
margin: 0px;
}
.line-price {
color: #212121;
font-size: 12px;
.price {
color: orange;
font-size: 13px;
}
}
//当前所有元素节点
&:nth-child(1) .img span {
background: url(/static/home/hot/top1.png)no-repeat;
background-size: 100% auto;
}
&:nth-child(2) .img span {
background: url(/static/home/hot/top2.png)no-repeat;
background-size: 100% auto;
}
&:nth-child(3) .img span {
background: url(/static/home/hot/top3.png)no-repeat;
background-size: 100% auto;
}
}
}
</style>
1.4 主页面homeView.vue
<script setup>
import Hot from '@/components/home/Hot.vue';
</script>
<template>
<!-- 热门推荐 -->
<Hot />
</template>
2. “精选景点”模块的制作:
2.1 <script>
模块:
<script setup>
import { ref } from 'vue';
const fineList = ref([
{ id: 1, name: '景点名称', score: 5, price: 98 },
{ id: 2, name: '景点名称', score: 4.5, price: 98 },
{ id: 3, name: '景点名称', score: 4, price: 98 },
{ id: 4, name: '景点名称', score: 4.5, price: 98 },
{ id: 5, name: '景点名称', score: 4.5, price: 98 },
{ id: 6, name: '景点名称', score: 5, price: 98 }
])
</script>
2.2 <template>
模块:
<template>
<!-- 精选经典 -->
<div class="home-fine-box">
<!-- 顶上导航 -->
<van-cell title="精选景点" is-link value="更多" icon="location-o" title-style="text-align:left" />
<!-- 景点列表 -->
<div class="box-main">
<a href="#" class="sight-item" v-for="item in fineList" :key="item.id">
<img src="/static/home/hot/h1.jpg" alt="">
<div class="right">
<h5>{{ item.name }}</h5>
<van-rate v-model="item.score" readonly=""/>
<div class="tips">4人点评|100%满意</div>
<div class="tips" light>辽宁-沈阳</div>
<div class="line-price">¥{{ item.price }}</div>
</div>
</a>
</div>
</div>
</template>
2.3 <style>
模块:
border-bottom: 1px solid #f6f6f6;
//给下边框(border-bottom)一个粗细为1px的浅灰色(#f6f6f6)实线(solid)
text-align: left; //文本内容居左
flex-grow: 1; //布局填充,默认值为0:保留原大小,1:扩大填充
justify-content: left; //非文本(例如:⭐)居左
<style lang="less">
.home-fine-box {
padding: 0 10px;
.van-cell {
padding: 10px 0px;
}
//景点列表
.box-main {
.sight-item {
display: flex;
margin-top: 10px;
border-bottom: 1px solid #f6f6f6;
img {
width: 100px;
height: 100px;
}
.right {
text-align: left;
flex-grow: 1;
justify-content: left;
padding-left: 5px;
position: relative;
h5 {
color: #212121;
font-size: 14px;
padding: 5px 0;
margin: 0px;
}
.line-price {
color: orange;
font-size: 16px;
position: absolute;
right: 10px;
top: 20px;
display: inline-block;
font-weight: bold;
}
.tips {
font-size: 12px;
color: #666;
&.light {
color: #999;
}
}
}
}
}
}
</style>
2.4 主页面homeView.vue
<script setup>
import Fine from '@/components/home/Fine.vue';
</script>
<template>
<!-- 精选景点 -->
<Fine style="margin-bottom: 10px;"></Fine>
</template>
3. 设置全局组件
由于精选景点(为例)模块信息,会在其他位置用到,
所以将其中数据,如图片、地区、价格等设置成全局组件。
方便随时提用:
3.1 新建ListSight.vue
src/components/common/ListSight.vue
3.2 搬运(ListSight.vue)
从Fine.vue中搬运信息,到ListSight.vue中来:
<script>
export default{
props:['item']
}
</script>
<template>
<a href="#" class="sight-item">
<img src="/static/home/hot/h1.jpg" alt="">
<div class="right">
<h5>{{ item.name }}</h5>
<van-rate v-model="item.score" readonly="" />
<div class="tips">4人点评|100%满意</div>
<div class="tips" light>辽宁-沈阳</div>
<div class="line-price">¥{{ item.price }}</div>
</div>
</a>
</template>
<style lang="less">
.sight-item {
display: flex;
margin-top: 10px;
border-bottom: 1px solid #f6f6f6; //下边框
img {
width: 100px;
height: 100px;
}
.right {
text-align: left; //文本内容居左
flex-grow: 1; //布局填充,默认值为0:保留原大小,1:扩大填充
justify-content: left; //非文本(⭐)居左
padding-left: 5px;
position: relative;
h5 {
color: #212121;
font-size: 14px;
padding: 5px 0;
margin: 0px;
}
.line-price {
color: orange;
font-size: 16px;
position: absolute;
right: 10px;
top: 20px;
display: inline-block;
font-weight: bold;
}
.tips {
font-size: 12px;
color: #666;
&.light {
color: #999;
}
}
}
}
</style>
3.3 现·Fine.vue
<script setup>
import ListSight from '../common/ListSight.vue';
import { ref } from 'vue';
const fineList = ref([
{ id: 1, name: '景点名称', score: 5, price: 98 },
{ id: 2, name: '景点名称', score: 4.5, price: 98 },
{ id: 3, name: '景点名称', score: 4, price: 98 },
{ id: 4, name: '景点名称', score: 4.5, price: 98 },
{ id: 5, name: '景点名称', score: 4.5, price: 98 },
{ id: 6, name: '景点名称', score: 5, price: 98 }
])
</script>
<template>
<!-- 精选经典 -->
<div class="home-fine-box">
<!-- 顶上导航 -->
<van-cell title="精选景点" is-link value="更多" icon="location-o" title-style="text-align:left" />
<!-- 景点列表 -->
<div class="box-main">
<ListSight v-for="item in fineList" :key="item.id" :item="item"/>
</div>
</div>
</template>
<style lang="less">
.home-fine-box {
padding: 0 10px;
.van-cell {
padding: 10px 0px;
}
//景点列表
// .box-main {
// }
}
</style>
4.页脚·脚部分
4.1 Footer.vue:
<script setup>
import { ref } from 'vue';
const active =ref()
</script>
<template>
<div>
<van-tabbar v-model="active">
<van-tabbar-item icon="wap-home-o" name="home">首页</van-tabbar-item>
<van-tabbar-item icon="search" name="search">搜索</van-tabbar-item>
<van-tabbar-item icon="user-o" name="mine">我</van-tabbar-item>
</van-tabbar>
</div>
</template>
4.2 主页面homeView.vue
<script setup>
import TripFooter from '@/components/common/Footer.vue';
</script>
<template>
<!-- 底部导航 -->
<TripFooter />
</template>