首页开发
项目GitHub地址:https://github.com/q2419068625/xianyun
新建公共组件
- 在
components
中新建应用统一的头部组件和页脚组件。 - 在默认布局中
layouts/default.vue
中导入公共组件。 - 实现步骤
头部组件
在components
文件夹中新建头部组件components/header.vue
。
<!-- logo -->
<div class="logo">
<nuxt-link to="/">
<img src="http://157.122.54.189:9093/images/logo.jpg" alt="">
</nuxt-link>
</div>
<!-- 菜单栏 -->
<el-row type="flex" class="navs">
<nuxt-link to="/">首页</nuxt-link>
<nuxt-link to="/post">旅游攻略</nuxt-link>
<nuxt-link to="/hotel">酒店</nuxt-link>
<nuxt-link to="/air">国内机票</nuxt-link>
</el-row>
<!-- 登录/用户信息 -->
<el-row type="flex" align="middle">
<!-- 如果用户存在则展示用户信息,用户数据来自store -->
<el-dropdown v-if="false">
<el-row type="flex" align="middle" class="el-dropdown-link">
<nuxt-link to="#">
<img src="http://157.122.54.189:9093/images/pic_sea.jpeg"/>
用户名
</nuxt-link>
<i class="el-icon-caret-bottom el-icon--right"></i>
</el-row>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<nuxt-link to="#">个人中心</nuxt-link>
</el-dropdown-item>
<el-dropdown-item>
<div @click="handleLogout">退出</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<!-- 不存在用户信息展示登录注册链接 -->
<nuxt-link to="/user/login" class="account-link" v-else>
登录 / 注册
</nuxt-link>
</el-row>
</el-row>
</header>
页脚组件
在components
文件夹中新建头部组件components/footer.vue
。
<template>
<div class="footer-wrapper">
<div class="footer">
<el-row class="info-list">
<el-col :span="6" :offset="1">
<h5>闲云旅游旅游网</h5>
<p>上亿旅行者共同打造的"旅行神器"</p>
<p><span>60,000</span> 多个全球旅游目的地</p>
<p><span>600,000</span> 个细分目的地新玩法</p>
<p><span>760,000,000</span> 次攻略下载</p>
<p><span>38,000</span> 家旅游产品供应商</p>
</el-col>
<el-col :span="5">
<h5>关于我们</h5>
<p>隐私政策 商标声明</p>
<p>服务协议 游记协议</p>
<p>商城平台服务协议</p>
<p>网络信息侵权通知指引</p>
<p>闲云旅游旅游网服务监督员</p>
<p>网站地图加入闲云旅游</p>
</el-col>
<el-col :span="5">
<h5>旅行服务</h5>
<p>旅游攻略 酒店预订</p>
<p>旅游特价 国际租车</p>
<p>旅游问答 旅游保险</p>
<p>旅游指南 订火车票</p>
<p>旅游资讯 APP下载</p>
</el-col>
<el-col :span="6" class="scan">
<p>
<img src="http://157.122.54.189:9093/images/1556522965.png" alt="">
</p>
关注我们
</el-col>
</el-row>
<div class="licence">
京ICP备08001421号 京公网安备110108007702 Copyright © 2016-2019 博学谷 All Rights Reserved
</div>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped lang="less">
.footer-wrapper{
background:#333;
color:#ccc;
min-width:1000px;
}
.footer{
padding-top:30px;
margin:0 auto;
width:1000px;
}
.info-list{
h5{
font-weight: normal;
font-size:16px;
margin-bottom:10px;
}
p{
font-size:12px;
line-height: 1.8;
span{
color:orange;
}
}
}
.scan{
text-align: center;
img{
width:140px;
height:140px;;
}
font-size:12px;
}
.licence{
border-top:1px #666 solid;
margin-top:20px;
padding:50px 0;
text-align: center;
font-size:12px;
}
</style>
首页轮播图
实现步骤
新增轮播图布局
把pages/index.vue
内容替换成以下代码:
<template>
<div class="container">
<!-- 幻灯片 -->
<el-carousel
:interval="5000"
arrow="always">
<el-carousel-item
v-for="(item, index) in banners"
:key="index">
<div class="banner-image"
:style="`
background:url(${item.url}) center center no-repeat;
background-size:contain contain;
`">
</div>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
export default {
data(){
return {
// 轮播图数据
banners: [
{
url: "http://157.122.54.189:9095/assets/images/th03.jfif",
},
{
url: "http://157.122.54.189:9095/assets/images/th04.jfif",
}
]
}
}
}
</script>
<style scoped lang="less">
.container{
min-width:1000px;
margin:0 auto;
position:relative;
/deep/ .el-carousel__container{
height:700px;
}
.banner-image{
width:100%;
height:100%;
}
}
</style>
请求后端接口数据
接下来使用接口数据来替换本地的静态数据
接口地址:http://157.122.54.189:9095/scenics/banners
mounted() {
this.$axios({
url:'http://157.122.54.189:9095/scenics/banners'
}).then(res=>{
// console.log(res.data);
this.banners = res.data.data
})
},
替换template
的图片地址为$axios.defaults.baseURL
,因为接口返回的图片链接是相对链接
<!--省略代码-->
<div class="banner-image"
:style="`
background:url(${$axios.defaults.baseURL}${item.url}) center center no-repeat;
background-size:contain contain;
`">
</div>
<!--省略代码-->
搜索跳转
思路
-
添加搜索框布局
-
搜索框
tab
切换执行不同的操作 -
搜索跳转
实现步骤
搜索框布局
把搜索框定位在轮播图上,在pages/index.vue
的template
新增以下代码
<template>
<div class="container">
<!-- 幻灯片 -->
<!-- 省略代码 -->
<!-- 搜索框 -->
<div class="banner-content">
<div class="search-bar">
<!-- tab栏 -->
<el-row
type="flex"
class="search-tab">
<span
v-for="(item, index) in options"
:key="index"
:class="{active: index === currentOption}"
@click="handleOption(index)">
<i>{{item.name}}</i>
</span>
</el-row>
<!-- 输入框 -->
<el-row
type="flex"
align="middle"
class="search-input">
<input
:placeholder="options[currentOption].placeholder"
v-model="searchValue"
@keyup.enter="handleSearch"/>
<i class="el-icon-search" @click="handleSearch"></i>
</el-row>
</div>
</div>
</div>
</template>
在pages/index.vue
的script
替换如下:
<script>
export default {
data(){
return {
banners: [], // 轮播图数据
options: [ // 搜索框tab选项
{
name: "攻略",
placeholder: "搜索城市",
pageUrl: "/post?city="
},
{
name: "酒店",
placeholder: "请输入城市搜索酒店",
pageUrl: "/hotel?city="},
{
name: "机票",
placeholder: "请输入出发地",
pageUrl: "/air"
}
],
searchValue: "", // 搜索框的值
currentOption: 0, // 当前选中的选项
}
},
mounted(){
this.$axios({
url: "/scenics/banners"
}).then(res => {
const {data} = res.data;
this.banners = data;
})
},
methods: {
handleOption(index){},
handleSearch(){}
},
}
</script>
tab栏操作
实现切换效果,并且判断如果切换的机票tab
,那么直接跳转到机票首页
编辑methods
下的handleOption
方法
// 切换tab栏时候触发
handleOption(index){
// 设置当前tab
this.currentOption = index;
// 如果切换的机票tab,那么直接跳转到机票首页
const item = this.options[index];
if(item.name === "机票"){
return this.$router.push(item.pageUrl);
}
},
搜索跳转
确定搜索时候会跳转到当前tab
的pageUrl
页面路径,并且在url
上携带上输入框的值
// 搜索时候触发
handleSearch(){
const item = this.options[this.currentOption];
// 跳转时候给对应的页面url加上搜索内容参数
this.$router.push(item.pageUrl + this.searchValue);
}
总结
- 先把搜索框定位在轮播图上。
- 给
tab
添加切换效果,并且判断如果是机票tab
,直接跳转到机票首页。 - 实现搜索跳转,注意跳转的链接来自当前选中的
tab
的pageUrl
属性,并且附带上参数