业务需求:
- 初始化布局
- 页头页脚公共组件
- 首页轮播图
一 初始化默认全局布局
nuxtjs 提供了一个公共组件 layouts/default.vue,相当于以前的 app.vue 。该布局组件默认作用于所有的页面,所以我们可以再这里加上一些公共的样式
layouts/default.vue
代码如下:
<template>
<div>
<!-- 这里相当于我们以前的app.vue -->
<pageHeader></pageHeader>
<!-- <Nuxt /> 相当于 <router-view></router-view> -->
<Nuxt />
<pageFooter></pageFooter>
</div>
</template>
<script>
import pageHeader from "@/components/pageHeader.vue";
import pageFooter from "@/components/pageFooter.vue";
export default {
components: {
pageHeader,
pageFooter
}
};
</script>
<style>
html {
font-family: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 16px;
word-spacing: 1px;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
}
.button--green {
display: inline-block;
border-radius: 4px;
border: 1px solid #3b8070;
color: #3b8070;
text-decoration: none;
padding: 10px 30px;
}
.button--green:hover {
color: #fff;
background-color: #3b8070;
}
.button--grey {
display: inline-block;
border-radius: 4px;
border: 1px solid #35495e;
color: #35495e;
text-decoration: none;
padding: 10px 30px;
margin-left: 15px;
}
.button--grey:hover {
color: #fff;
background-color: #35495e;
}
</style>
二 新建公共组件
1.思路
1.在components 文件夹中新建所有页面统一的头部组件和页脚组件
2.在默认布局中 layouts/default.vue中 导入公共组件并使用
组件约定:公共组件不需要放到子文件夹中:如下图
头部下拉菜单组件文档:https://element.eleme.cn/#/zh-CN/component/dropdown#ji-chu-yong-fa
2.实现步骤
2.1 头部组件
components/pageFooter.vue 文件代码如下:
<template>
<header class="header">
<el-row type="flex" justify="space-between" class="main">
<!-- 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">
<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>退出</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>
</template>
<script>
export default {
computed: {
};
</script>
<style scoped lang="less">
.header {
height: 60px;
line-height: 60px;
background: #fff;
border-bottom: 1px #ddd solid;
box-shadow: 0 3px 0 #f5f5f5;
box-sizing: border-box;
.main {
width: 1000px;
margin: 0 auto;
}
.logo {
width: 156px;
padding-top: 8px;
img {
display: block;
width: 100%;
}
}
.navs {
margin: 0 20px;
flex: 1;
a {
display: block;
padding: 0 20px;
height: 60px;
box-sizing: border-box;
&:hover,
&:focus,
&:active {
border-bottom: 5px #409eff solid;
color: #409eff;
}
}
// 菜单高亮时的颜色
/deep/ .nuxt-link-exact-active {
background: #409eff;
color: #fff !important;
}
}
.message {
height: 36px;
line-height: 1;
cursor: pointer;
.el-icon-bell {
margin-right: 2px;
font-size: 18px;
}
}
.el-dropdown-link {
margin-left: 20px;
&:hover {
img {
border-color: #409eff;
}
}
a {
display: block;
}
img {
width: 32px;
height: 32px;
vertical-align: middle;
border: 2px #fff solid;
border-radius: 50px;
}
}
.account-link {
font-size: 14px;
margin-left: 10px;
color: #666;
&:hover {
color: #409eff;
text-decoration: underline;
}
}
}
</style>
2.2 页脚组件
在components/pageFooter.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>
3 总结:
- layouts.default.vue 是默认的布局组件,会作用于任何页面
- 在layouts/default.vue 中导入全局的头部组件和页脚组件,就可以查看到基本的页面效果了
三 首页轮播图
1. 思路
- 使用 Element-ui 的幻灯片组件 el-carousel,新增首页的轮播图布局
- 请求后端接口替换静态图片数据
2.实现步骤
2.1 新增轮播图布局
- 首页的轮播图布局,pages/index.vue 是在 layouts/default.vue 中的 </nuxt>中渲染
- banners 是我们自己构建的一个死数据数组, 用来遍历之后生成多张图片进行轮播
<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>
2.2 请求后端接口数据
<script>
export default {
data(){
return {
banners: [] //轮播图数据存放
}
},
mounted(){
this.$axios({
url:"/scenics/banners"
}).then(res=>{
const {data} = res.data;
})
}
}
</script>
this.$axios能使用 是因为 nuxt 已经帮我们绑定了
2.3 修改 template 的图片地址,添加 $axios.defaults.baseURL,因为接口返回的图片链接时相对链接
<!-- 首页轮播图 -->
<template>
<el-carousel :interval="5000" arrow="always">
<el-carousel-item v-for="(item,index) in banners" :key="index">
<div
class="banner-image"
:style="`
background:url(${$axios.defaults.baseURL}${item.url}) center center no-repeat;
background-size:contain contain;
`"
>{{$axios.defaults.baseURL}}{{item.url}}</div>
</el-carousel-item>
</el-carousel>
</template>
3.总结
- 使用Element-ui的幻灯片组件 el-carousel 实现轮播图,开始显示固定数据,固定的图片
- 使用this.$axios 请求后台轮播图接口 获取数据
- 在模板中使用$axios.defaults.baseURL 补全图片地址进行显示