前期准备:
预计使用到的技术栈:
- Nuxtjs
- Vue
- element
- vue-router
- Axios
- Token
- Vuex
- 高德地图
一、修改配置文件
配置文件
nuxt.config.js对项目进行了全局配置,对每个页面都生效
import pkg from './package'
export default {
mode: 'universal',
/*
** Headers of the page
*/
head: {
title: "闲云旅游网", // 修改title
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: pkg.description }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', type: 'text/css', href: '//at.alicdn.com/t/font_1168872_ehvuah8v57g.css' } // 新增全局字体样式
]
},
/*
** Customize the progress-bar color
*/
loading: { color: '#fff' },
/*
** Global CSS
*/
css: [
'element-ui/lib/theme-chalk/index.css',
'assets/main.css' // 新增自定义的页面过渡样式(文件来自3.4.1)
],
/*
** Plugins to load before mounting the App
*/
plugins: [
'@/plugins/element-ui'
],
/*
** Nuxt.js modules
*/
modules: [
// https://axios.nuxtjs.org/setup
'@nuxtjs/axios'
],
/*
** Axios module configuration
*/
axios: {
// See https://github.com/nuxt-community/axios-module#options
// baseURL: "http://157.122.54.189:9095" // 新增备用地址
baseURL: "http://127.0.0.1:1337" // 新增axios默认请求路径
},
/*
** Build configuration
*/
build: {
transpile: [/^element-ui/],
/*
** You can extend webpack config here
*/
extend(config, ctx) {
}
},
}
配置
assets/main.css文件,实现页面切换时样式过渡,非必须
/* 页面切换时候过渡样式 */
.page-enter-active,
.page-leave-active {
transition: opacity .5s;
}
/* 打开时候过渡样式 */
.page-enter,
.page-leave-active {
opacity: 0;
}
/* 页面顶部页面加载进度条 */
.nuxt-progress {
background: #409eff;
height: 1px;
}
二、初始化默认全局布局
- 普通
vue的根实例放在App.vue,里面有<router-view/>是路由映射出口.还有一些全局的css样式等.现在nuxt里面没有App.vue,而是提供了一个layouts/default.vue公共布局组件,该布局组件默认作用于所有页面,相当于App.vue.- 里面的
<Nuxt/>也是相当于<router-view/>,只不过封装成这个模式.
根据项目需要初始化样式
<style lang="less">
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;
}
*{
margin:0;
padding:0;
}
ul, li, ol{
list-style:none;
}
a{
text-decoration:none;
color:inherit;
}
em,i{
font-style: normal;
}
</style>
二、创建公共组建
- 在
components文件夹中新建应用统一的头部组件和页脚组件- 在默认布局中
layouts/default.vue中导入公共组件- 公共样式可以不引入子文件夹
1.头部组件
components/PageHeader.vue<nuxt-link to="/">等同于<router link>- 使用
element组件的Dropdown下拉菜单,在右上登录成功时鼠标上移出现下拉效果
<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">
<!-- 如果用户存在则展示用户信息,用户数据来自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>
</template>
<script>
export default {
methods: {
// 用户退出
handleLogout() {},
},
};
</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.尾部组件
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引入
<template>
<div>
<!-- 步骤三:使用 -->
<!-- 页头 -->
<PageHeader />
<!-- 内容占位组件 -->
<nuxt />
<!-- 页尾 -->
<PageFooter />
</div>
</template>
<script>
// 步骤一:引入
import PageHeader from "@/components/PageHeader";
import PageFooter from "@/components/PageFooter";
export default {
components: {
// 步骤二:注册
PageHeader,
PageFooter,
},
};
</script>
4.轮播图
思路:
- 使用
Element-ui的幻灯片组件Carousel走马灯,新增首页轮播图布局。- 请求后端接口渲染图片数据
- 把
pages/index.vue内容替换成以下代码
<template>
<div class="container">
<!-- 幻灯片 -->
<!-- interval:自动切换图片的时间 -->
<!-- v-for:循环数据 -->
<!-- el-carousel-item:一个item就是一个图片 -->
<el-carousel :interval="3000" 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;
`"
></div>
</el-carousel-item>
</el-carousel>
<!-- 下面是搜索框 -->
</div>
</template>
<script>
export default {
data() {
return {
// 轮播图数据
banners: [],
};
},
//页面创建时需要获取轮播图数据,created时虽然dow不在,但是拿数据没问题
// mounted()也可以
created() {
this.$axios({
url: "/scenics/banners",
}).then((res) => {
console.log(res.data.data);
this.banners = res.data.data; //获取数据时赋值给banners数组,用来遍历
// 解构写法
// const { data } = res.data;
// this.banners = data;
});
},
};
</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>