頁面效果:

1.初始化默認布局
<template>
<div>
<!-- 內容占位組件 -->
<nuxt />
</div>
</template>
<script>
export default {
}
</script>
<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;
}
a:hover{
}
em,i{
font-style: normal;
}
</style>
2.新建公共組件
思路:
1.在components中新建需要復用的頭部組件和頁腳組件
2.在默認布局中layouts/default.vue中導入公共組件
組件約定:公共組件不需要放到子文件夾中
下拉組件文檔:https://element.eleme.cn/#/zh-CN/component/dropdown#ji-chu-yong-fa
實現步驟
頭部組件
<template>
<div class="container">
<el-row type="flex" class="main" justify="space-between">
<!-- 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>
<!-- 右側登錄注冊 -->
<div class="right-login">
<div v-if="false">
<nuxt-link to="/user/login">登錄/注冊</nuxt-link>
</div>
<div>
<el-dropdown>
<span class="el-dropdown-link">
<img src="http://157.122.54.189:9095/assets/images/avatar.jpg" alt="">
托馬斯
<i class="el-icon-arrow-down el-icon--right"></i> <!-- 小箭頭 -->
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>個人中心</el-dropdown-item>
<el-dropdown-item>退出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</el-row>
</div>
</template>
<script>
export default {};
</script>
<style lang="less" scoped>
.container {
box-shadow: 0 2px 2px #ddd;
}
.main {
width: 1000px;
margin: 0 auto;
height: 60px;
line-height: 60px;
}
.logo {
margin-right: 20px;
img {
width: 156px;
height: 42px;
margin-top: 9px;
}
}
.navs {
margin: 0 20px;
flex: 1;/* 讓所有彈性盒模型對象的子元素都有相同的長度,且忽略它們內部的內容: */
a {
display: block;
padding: 0 20px;
height: 60px;
box-sizing: border-box;
&:hover {
color: #409eff;
border-bottom: 5px #409eff solid;
}
}
/deep/ .nuxt-link-exact-active { /* /deep/ 是為了重置element-ui組件中的樣式*/
background: #409eff;
color: #fff;
&:hover {
color: #fff;
}
}
}
.el-dropdown-link{
img{
width: 36px;
height: 36px;
vertical-align: middle;
border-radius: 50%;
}
}
</style>
<template>
<div>
<Header></Header>
<!-- 內容的占位符,類似router-view -->
<nuxt />
</div>
</template>
<script>
import Header from '@/components/header'
export default {
// 注冊組件
components: {
Header
}
}
</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;
}
*{
margin:0;
padding:0;
}
ul, li, ol{
list-style: none;
}
a{
color:inherit;
text-decoration: none;
}
em,i{
font-style: normal;
}
</style>
<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>60,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 lang="less" scoped>
.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: skyblue;
font-weight: bold;
font-style: italic;
}
}
}
.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>
<template>
<div>
<Header></Header>
<!-- 內容的占位符,類似router-view -->
<nuxt />
<Footer></Footer>
</div>
</template>
<script>
import Header from '@/components/header'
import Footer from '@/components/footer'
export default {
// 注冊組件
components: {
Header,
Footer
}
}
</script>
總結:
-
-
在
layouts/default.vue中導入全局的頭部組件和頁腳組件
3.首頁輪播圖和TAB欄
<template>
<div class="container">
<!-- 輪播圖 -->
<el-carousel :interval="3000" arrow="hover">
<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 class="banner-content">
<div class="search-bar">
<!-- tab欄 -->
<el-row type="flex" class="search-tab">
<span
v-for="(item, index) in tabs"
:key="index"
:class="{active: currentTab === index}"
@click="handleChangeTab(index)"
>
<i>{{item.name}}</i>
</span>
</el-row>
<!-- 輸入框 -->
<el-row type="flex" align="middle" class="search-input">
<input :placeholder="tabs[currentTab].placeholder" />
<i class="el-icon-search"></i>
</el-row>
</div>
</div>
</div>
</template>
<script>
export default {
// data是一個函數,返回一個對象
data() {
return {
banners: [],
currentTab: 0,
// tab欄的數據
tabs: [
{ name: "攻略", placeholder: "搜索城市" },
{ name: "酒店", placeholder: "請輸入搜索酒店的城市" },
{ name: "機票", placeholder: "", pageUrl: "/air" }
]
};
},
methods: {
// tab欄切換
handleChangeTab(index) {
// 如果點擊的是機票,跳轉到機票頁面
if (index === 2) {
this.$router.push("/air");
}
// 修改當前高亮顯示
this.currentTab = index;
}
},
// 頁面加載時自動執行的生命周期函數
mounted() {
// 這里可以使用this.$axios是因為框架已經自動幫我們把axios綁定到原型上了
// 手動將axios綁定到原型上的方法:Vue.prototype.$axios = axios
this.$axios({
url: "/scenics/banners",
method: "GET"
}).then(res => {
const { data } = res.data;
this.banners = data;
});
}
};
</script>
<style lang="less" scoped>
.container {
min-width: 1000px;
margin: 0 auto;
position: relative; /* 相對定位 */
/deep/ .el-carousel__container {
height: 700px;
}
.banner-image {
width: 100%;
height: 100%;
}
.banner-content {
z-index: 9;
width: 1000px;
position: absolute;
left: 50%;
top: 45%;
margin-left: -500px;
border-top: 1px transparent solid;
.search-bar {
width: 552px;
margin: 0 auto;
}
.search-tab {
.active {
i {
color: #333;
}
&::after {
background: #eee;
}
}
span{
width: 82px;
height: 36px;
display: block;
position: relative;
margin-right: 8px;
cursor: pointer;
i{
position: absolute;
z-index: 2;
display: block;
width: 100%;
height: 100%;
line-height: 30px;
text-align: center;
color: #fff;
}
&::after{
position: absolute;
left: 0;
top: 0;
display: block;
content: "";
width: 100%;
height: 100%;
border: 1px rgba(255, 255, 255, .2) solid;
border-bottom: none;
transform: scale(1.1,1.3) perspective(.7em) rotateX(2.2deg);
transform-origin: bottom left;
background: rgba(0, 0, 0, .5);
border-radius: 1px 2px 0 0;
box-sizing: border-box;
}
}
}
.search-input{
width: 550px;
height: 46px;
background: #ffffff;
border-radius: 0 4px 4px 4px;
border: 1px rgba(255, 255, 255, .2) solid;
border-top: none;
box-sizing: unset;
input{
flex: 1;
height: 20px;
padding: 13px 15px;
outline: none;
border: 0;
font-size: 16px;
}
.el-icon-search{
cursor: pointer;
font-size: 22px;
padding: 0 10px;
font-weight: bold;
}
}
}
}
</style>
