旅游网站
1. 创建项目
- 在你要创建项目的路径下打开vscode,新建终端,然后输入vue ui,进入Vue项目管理器。
- 选择"创建",确定项目路径,并点击"在此创建新项目"。
- 在项目文件夹中输入项目名称,点击下一步;
- 选择"手动配置项目",然后点击下一步;
- 增加选择"router"和"css"两个配置项,然后点击下一步;
- 选择 CSS 预处理器。node-sass 是自动编译实时的,dart-sass 需要保存后才会生效,此处建议选择
Sass/SCSS(with dart-sass);pick a linter / formatter config
可以选择第一个,只检查错误。选择完成后就可以创建项目。 - 提示创建成功后可以用vscode打开新建的项目。
2. 新建首页
注意:App.vue是整个项目的入口文件,这个文件保持干净,后续内容多了,结构才不出错,所以新建一个首页index.vue
-
为避免系统提示要组合词命名文件的错误,在package.json文件中修改"rules"的值:
json"rules": { "vue/multi-word-component-names": "off" }
-
在src文件夹下的views文件夹中新建index.vue。在index.vue文件中,先设置一个简单页面,输入如下代码:(安装了插件就可以输入vue,然后选择默认vue结构,会自动补全vue结构)
html<template> <h1>首页</h1> </template> <script> export default { } </script> <style> </style>
-
按照路由的配置方法,在router文件下设置index.js文件,把不需要的路由删除或者注释。两步走,1引入子页面,2设置路由。
代码如下
jsimport { createRouter, createWebHashHistory } from 'vue-router' // 1.引入 import Index from '../views/index.vue' const routes = [ // 2.设置路由 { path: '/', name: 'home', component: Index } ] const router = createRouter({ history: createWebHashHistory(), routes }) export default router
如果显示index出错
error Component name "index" should always be multi-word
解决方式:
在vue.config.js中添加代码
lintOnSave:false
后重启项目即可
-
修改App.vue文件为如下代码,在这个页面中引入需要的页
html<template> <router-view/> </template>
效果图:
3. 引入ElementPlus组件
-
用vscode打开项目,然后在终端中,项目路径下运行命令:npm install element-plus --save
-
在main.js文件中配置elementplus和ico图标库,导入方法见element官网,
https://element-plus.org/zh-CN/,修改main.js为如下代码:
jsimport { createApp } from 'vue' import App from './App.vue' import router from './router' // ElementPlus 相关库的导入 import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import zhCn from 'element-plus/es/locale/lang/zh-cn' // 导入icon图标库 import * as ElementPlusIconsVue from '@element-plus/icons-vue' // 导入暗黑模式主题,在index.html文件中:需在 html 上添加一个名为 dark 的类 import 'element-plus/theme-chalk/dark/css-vars.css' // 创建一个应用 const app = createApp(App) // 注册elementplus app.use(ElementPlus, { locale: zhCn, }) // 注册elementplus图标 for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component) } // 注册路由后挂载 app.use(router).mount('#app')
4. 高仿携程旅游页面,制作index.vue
-
首页布局。进入element官网,https://element-plus.org/zh-CN/,选择组件,然后选择Basic 基础组件中的Container 布局容器。根据上面的图,选择左上下结构,复制代码。
-
粘贴到index.vue中里面并进行修改。此时也可以启动服务器查看布局结果
代码如下:
html<template> <!-- <h1>首页</h1> --> <div class="common-layout"> <el-container> <el-aside width="200px" class="test1">Aside</el-aside> <el-container> <el-header class="test2">Header</el-header> <el-main class="test3">Main</el-main> </el-container> </el-container> </div> </template> <script> export default { } </script> <style lang="scss"> .test1{ background-color: rgb(177, 208, 255); height: 100vh; } .test2{ background-color: rgb(110, 160, 235); } .test3{ background-color: rgb(187, 239, 255); } </style>
效果图:
-
将index.vue页面中的三个组成部分拆分成menu.vue、logo.vue和main.vue三个页
(1)在views文件夹中新建menu.vue、logo.vue和main.vue三个页面,然后将这三个组成部分的代码分别输入到对应的页面中。具体如下:
html
menu.vue代码:
<template>
<el-aside width="200px">Aside</el-aside>
</template>
<script>
export default {
}
</script>
<style lang="scss">
.el-aside{
background-color: rgb(177, 208, 255);
height: 100vw;
}
</style>
logo.vue代码:
<template>
<el-header>Header</el-header>
</template>
<script>
export default {
}
</script>
<style lang="scss">
.el-header{
background-color: rgb(110, 160, 235);
}
</style>
main.vue代码:
<template>
<el-main>Main</el-main>
</template>
<script>
export default {
}
</script>
<style lang="scss">
.el-main{
background-color: rgb(187, 239, 255);
}
</style>
(2)修改index.vue,将三个组件页面引入到index.vue中,然后设置组件标签,代码如下:
html
<template>
<!-- <h1>首页</h1> -->
<div class="common-layout">
<el-container>
<MenuView></MenuView>
<el-container>
<el-header><LogoView></LogoView></el-header>
<el-main><MainView></MainView></el-main>
</el-container>
</el-container>
</div>
</template>
<script setup>
// 1.script 里加setup,引入要加载的子页面
import MenuView from './menu.vue'
import MainView from './main.vue'
import LogoView from './logo.vue'
</script>
<style lang="scss">
</style>
效果图:
5. 制作左边菜单栏
功能是可以展开和隐藏菜单栏,所以要在elementplus中找到相对应的组件,想要的效果是munu菜单中的Collapse 折叠面板。
-
打开Collapse 折叠面板的代码,分析其哪些功能代码是我们需要的,不要直接全部复制。leftmenu.vue的代码如下:
html<template> <el-aside width="200px"> <!-- 1.隐藏展开按钮 --> <el-radio-group v-model="isCollapse" style="margin-bottom: 20px"> <el-radio-button :value="false">expand</el-radio-button> <el-radio-button :value="true">collapse</el-radio-button> </el-radio-group> <!-- 2菜单标签 --> <el-menu default-active="2" class="el-menu-vertical-demo" :collapse="isCollapse" @open="handleOpen" @close="handleClose" > <!-- 3根据页面的布局需要第二组菜单项 --> <el-menu-item index="2"> <el-icon><icon-menu /></el-icon> <template #title>酒店</template> </el-menu-item> </el-menu> </el-aside> </template> <script setup> import { ref } from 'vue' // 设置isCollapse的值为true,用于控制展开或隐藏 const isCollapse = ref(true) // 导入icon图标,没用到的组件导入会报错,可以在package.json文件中 // 增加一条rules:"no-unused-vars": "off" import { Document, Menu as IconMenu, Location, Setting, } from '@element-plus/icons-vue' </script> <style> .el-menu-vertical-demo:not(.el-menu--collapse) { width: 200px; min-height: 400px; } </style>
-
启动服务器,查看此时网页效果
效果图:
-
修改上面的代码,实现与网站几乎相同的效果。
(1)将展开隐藏按钮标签放入到菜单标签,并将展开隐藏的文字提示改为"|||",并且将两个标签设置v-show属性,展开的时候显示,隐藏的时候隐藏标识符号。
(2)在script里面定义左侧菜单数组
(3)在菜单项中通过v-for去实现显示菜单组
(4)更改icon图标,可以在icon图标库中复制图标名字加到已导入的图标项中
(5)修改菜单项中设置icon图标的代码,实现动态加载图标
leftmenu.vue的代码改动为如下所示:
vue
<template>
<el-aside width="200px">
<!-- 1.隐藏展开按钮 -->
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
<!-- <el-radio-button :value="false">expand</el-radio-button>
<el-radio-button :value="true">collapse</el-radio-button> -->
<!-- 6.修改为:将展开隐藏按钮标签放入到菜单标签,
并将展开隐藏的文字提示改为"|||",
并且将两个标签设置v-show属性,展开的时候显示,隐藏的时候隐藏标识符号 -->
<el-radio-button :value="false" v-show="isCollapse">|||</el-radio-button>
<el-radio-button :value="true" v-show="!isCollapse">|||</el-radio-button>
</el-radio-group>
<!-- 2菜单标签 -->
<el-menu default-active="2" class="el-menu-vertical-demo"
:collapse="isCollapse" @open="handleOpen" @close="handleClose">
<!-- 3根据页面的布局需要第二组菜单项 -->
<!-- <el-menu-item index="2">
<el-icon><icon-menu /></el-icon>
<template #title>酒店</template>
</el-menu-item> -->
<!-- 8.需要多个这个菜单项就用v-for实现-->
<el-menu-item index="v.id" v-for="v in asidelist" :key="v.id">
<!-- 11.实现动态icon图标 -->
<el-icon><component :is="v.icon"></component></el-icon>
<template #title>{{v.title}}</template>
</el-menu-item>
</el-menu>
</el-aside>
</template>
<script setup>
import { ref } from "vue";
// 设置isCollapse的值为true,用于控制展开或隐藏
const isCollapse = ref(true)
// 导入icon图标,没用到的组件导入会报错,可以在package.json文件中
// 增加一条rules:"no-unused-vars": "off"
import {
Document,
Menu as IconMenu,
Location,
Setting,
// 9.增加新的图标
OfficeBuilding,
Bowl
} from '@element-plus/icons-vue'
// 7.定义左侧菜单数组,10.增加icon
let asidelist=ref([
{id:1,title:'酒店',icon:OfficeBuilding},
{id:2,title:'机票',icon:Document},
{id:3,title:'火车票',icon:Setting},
{id:4,title:'旅游',icon:Bowl},
{id:5,title:'景点',icon:Location},
{id:6,title:'汽车票',icon:Document},
{id:7,title:'船票',icon:IconMenu},
{id:8,title:'门票',icon:OfficeBuilding},
])
</script>
<style lang="scss">
.el-aside{
background-color: rgb(177, 208, 255);
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
</style>
-
启动服务器,查看此时的显示效果
-
调整按钮位置
vue<template> <el-aside width="200px"> <!-- 菜单标签 --> <el-menu default-active="2" class="el-menu-vertical-demo" :collapse="isCollapse" @open="handleOpen" @close="handleClose" > <!-- 隐藏展开按钮 --> <el-radio-group v-model="isCollapse" style="margin-bottom: 20px"> <el-radio-button :value="false" v-show="isCollapse">|||</el-radio-button> <el-radio-button :value="true" v-show="!isCollapse">|||</el-radio-button> </el-radio-group> <!-- 需要多个这个菜单项就用v-for实现--> <el-menu-item index="v.id" v-for="v in asidelist" :key="v.id"> <!-- 实现动态icon图标 --> <el-icon><component :is="v.icon"></component></el-icon> <template #title>{{v.title}}</template> </el-menu-item> </el-menu> </el-aside> </template> <script setup> import { ref } from "vue"; // 设置isCollapse的值为true,用于控制展开或隐藏 const isCollapse = ref(true) // 导入icon图标,没用到的组件导入会报错,可以在package.json文件中 // 增加一条rules:"no-unused-vars": "off" import { Document, Menu as IconMenu, Location, Setting, // 9.增加新的图标 OfficeBuilding, Bowl } from '@element-plus/icons-vue' // 定义左侧菜单数组,10.增加icon let asidelist=ref([ {id:1,title:'酒店',icon:OfficeBuilding}, {id:2,title:'机票',icon:Document}, {id:3,title:'火车票',icon:Setting}, {id:4,title:'旅游',icon:Bowl}, {id:5,title:'景点',icon:Location}, {id:6,title:'汽车票',icon:Document}, {id:7,title:'船票',icon:IconMenu}, {id:8,title:'门票',icon:OfficeBuilding}, ]) </script> <style lang="scss"> .el-aside{ background-color: rgb(177, 208, 255); } .el-menu-vertical-demo:not(.el-menu--collapse) { width: 200px; min-height: 400px; } </style>
效果:
6. 字体图标的引入
-
下载第三方图标,进入阿里巴巴矢量图库https://www.iconfont.cn/?spm=a313x.manage_type_myprojects.i3.2.74bc3a812ze26a,并保存在src中
-
全局引入
在main.js中加上代码
import '@/assets/font/iconfont.css'
-
修改menu中代码
vue<template> <el-aside width="200px"> <!-- 菜单标签 --> <el-menu default-active="2" class="el-menu-vertical-demo" :collapse="isCollapse" @open="handleOpen" @close="handleClose" > <!-- 隐藏展开按钮 --> <el-radio-group v-model="isCollapse" style="margin-bottom: 20px"> <el-radio-button :value="false" v-show="isCollapse">|||</el-radio-button> <el-radio-button :value="true" v-show="!isCollapse">|||</el-radio-button> </el-radio-group> <!-- 需要多个这个菜单项就用v-for实现--> <el-menu-item index="v.id" v-for="v in asidelist" :key="v.id"> <!-- 实现动态icon图标 --> <!-- <el-icon><component :is="v.icon"></component></el-icon> --> <i class="iconfont" :class="v.icon"></i> <template #title>{{v.title}}</template> </el-menu-item> </el-menu> </el-aside> </template> <script setup> import { ref } from "vue"; // 设置isCollapse的值为true,用于控制展开或隐藏 const isCollapse = ref(true) // 导入icon图标,没用到的组件导入会报错,可以在package.json文件中 // 增加一条rules:"no-unused-vars": "off" import { Document, Menu as IconMenu, Location, Setting, // 9.增加新的图标 OfficeBuilding, Bowl } from '@element-plus/icons-vue' // 定义左侧菜单数组,10.增加icon // let asidelist=ref([ // {id:1,title:'酒店',icon:OfficeBuilding}, // {id:2,title:'机票',icon:Document}, // {id:3,title:'火车票',icon:Setting}, // {id:4,title:'旅游',icon:Bowl}, // {id:5,title:'景点',icon:Location}, // {id:6,title:'汽车票',icon:Document}, // {id:7,title:'船票',icon:IconMenu}, // {id:8,title:'门票',icon:OfficeBuilding}, // ]) // 引入第三方图标 let asidelist = ref([ {id:1,title:'酒店',icon:'icon-jiudian'}, {id:2,title:'机票',icon:'icon-lvxing'}, {id:3,title:'火车票',icon:'icon-huoche'}, {id:4,title:'旅游',icon:'icon-lvyou1'}, {id:5,title:'景点',icon:'icon-jingdian'}, {id:6,title:'汽车票',icon:'icon-tuijianqiche'}, {id:7,title:'船票',icon:'icon-lunchuan'}, {id:8,title:'门票',icon:'icon-menpiao'}, ]) </script> <style lang="scss"> .el-aside{ background-color: rgb(177, 208, 255); } .el-menu-vertical-demo:not(.el-menu--collapse) { width: 200px; min-height: 400px; } </style>
-
图标效果
7. 左侧导航栏样式
-
新建样式index.css
-
代码
index.css
css/* 左侧导航栏 */ .aside { width: 200px; } .aside-list { /* 固定定位 */ position: fixed; left: 0; width: 200px; } .aside .el-menu { height:100vh; } /* 字体图标的样式 */ .aside i { font-size: 24px; font-weight: 500; margin-right: 5px; } .aside .el-radio-button__inner { border:none; font-size: 20px; }
menu.vue
vue
<template>
<el-aside width="200px" class="aside">
<div class="aside-list">
<!-- 菜单标签 -->
<el-menu
default-active="2"
class="el-menu-vertical-demo"
:collapse="isCollapse"
@open="handleOpen"
@close="handleClose"
>
<!-- 隐藏展开按钮 -->
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
<el-radio-button :value="false" v-show="isCollapse">|||</el-radio-button>
<el-radio-button :value="true" v-show="!isCollapse">|||</el-radio-button>
</el-radio-group>
<!-- 需要多个这个菜单项就用v-for实现-->
<el-menu-item index="v.id" v-for="v in asidelist" :key="v.id">
<!-- 实现动态icon图标 -->
<!-- <el-icon><component :is="v.icon"></component></el-icon> -->
<i class="iconfont" :class="v.icon"></i>
<template #title>{{v.title}}</template>
</el-menu-item>
</el-menu>
</div>
</el-aside>
</template>
<script setup>
import { ref } from "vue";
// 设置isCollapse的值为true,用于控制展开或隐藏
const isCollapse = ref(true)
// 导入icon图标,没用到的组件导入会报错,可以在package.json文件中
// 增加一条rules:"no-unused-vars": "off"
import {
Document,
Menu as IconMenu,
Location,
Setting,
// 9.增加新的图标
OfficeBuilding,
Bowl
} from '@element-plus/icons-vue'
// 定义左侧菜单数组,10.增加icon
// let asidelist=ref([
// {id:1,title:'酒店',icon:OfficeBuilding},
// {id:2,title:'机票',icon:Document},
// {id:3,title:'火车票',icon:Setting},
// {id:4,title:'旅游',icon:Bowl},
// {id:5,title:'景点',icon:Location},
// {id:6,title:'汽车票',icon:Document},
// {id:7,title:'船票',icon:IconMenu},
// {id:8,title:'门票',icon:OfficeBuilding},
// ])
// 引入第三方图标
let asidelist = ref([
{id:1,title:'酒店',icon:'icon-jiudian'},
{id:2,title:'机票',icon:'icon-lvxing'},
{id:3,title:'火车票',icon:'icon-huoche'},
{id:4,title:'旅游',icon:'icon-lvyou1'},
{id:5,title:'景点',icon:'icon-jingdian'},
{id:6,title:'汽车票',icon:'icon-tuijianqiche'},
{id:7,title:'船票',icon:'icon-lunchuan'},
{id:8,title:'门票',icon:'icon-menpiao'},
])
</script>
<style lang="scss">
</style>
```
-
引入样式
在main.js中
import '@/assets/css/index.css'
-
效果图
遇到问题:
- 隐藏张开按钮会跟随移动
解决方式:
修改#appde 样式
删除
text-align: center
如不清楚,请看12.位置区域中的解决方式
8. 头部导航栏
-
修改logo.vue中的代码
vue<template> <div> <div class="headerNav"> <!-- logo --> <div class="header-logo">logo</div> <!-- 搜索框 --> <div class="header-search">搜索框</div> <!-- 导航菜单 --> <div class="header-right">导航菜单</div> </div> </div> </template> <script> export default { } </script> <style lang="scss"> .el-header{ background-color: rgb(110, 160, 235); } </style>
效果图:
-
横向排列、固定定位
修改index.css文件
css/* 页面头部 */ /* 宽度响应 */ .el-header { min-width: 1280px; } .headerNav { display: flex; justify-content: space-between; align-items: center; /* 水平垂直对齐 */ height: 70px; width:1620px; /* 固定定位 */ position:fixed; top:0; background-color: #fff; z-index: 999; padding: 10px 0; }
删除logo.vue中定义的css样式
-
效果图
-
logo图
-
修改代码
vue<template> <div> <div class="headerNav"> <!-- logo --> <div class="header-logo"> <img src="@/assets/images/logo.png" alt=""> </div> <!-- 搜索框 --> <div class="header-search">搜索框</div> <!-- 导航菜单 --> <div class="header-right">导航菜单</div> </div> </div> </template> <script> export default { } </script> <style lang="scss"> </style>
-
修改样式
css.headerNav { display: flex; justify-content: space-between; align-items: center; /* 水平垂直对齐 */ height: 70px; width:1400px; /* 固定定位 */ position:fixed; top:0; background-color: #fff; z-index: 999; padding: 10px 0; } .headerNav img { width: 100%; height: 50px; }
效果图:
9. 搜索框
-
修改代码
logo.vue
vue<template> <div> <div class="headerNav"> <!-- logo --> <div class="header-logo"> <img src="@/assets/images/logo.png" alt=""> </div> <!-- 搜索框 --> <div class="header-search"> <el-input v-model="input3" placeholder="请输入内容" class="input-with-select" > <template #append> <el-button :icon="Search" /> </template> </el-input> </div> <!-- 导航菜单 --> <div class="header-right">导航菜单</div> </div> </div> </template> <script setup> //引入搜索图标 import { Search } from '@element-plus/icons-vue' </script> <style lang="scss"> </style>
index.css
css.header-search { flex: 1; margin: 0 2rem; } /* 按钮的颜色 */ .headerNav .el-input-group__append { background-color: var(--el-color-primary); color: #fff; } .heaer-right .el-link { margin: 0 20px; }
效果图:
10. 头部下拉菜单
-
修改代码
logo.vue
vue<template> <div> <div class="headerNav"> <!-- logo --> <div class="header-logo"> <img src="@/assets/images/logo.png" alt=""> </div> <!-- 搜索框 --> <div class="header-search"> <el-input v-model="input3" placeholder="请输入内容" class="input-with-select" > <template #append> <el-button :icon="Search" /> </template> </el-input> </div> <!-- 导航菜单 --> <div class="header-right"> <el-link :icon="Avatar">请登录</el-link> <el-link target="_blank">注册</el-link> <el-link> <el-dropdown> <span class="el-dropdown-link"> 我的订单 <el-icon class="el-icon--right"> <arrow-down /> </el-icon> </span> <template #dropdown> <el-dropdown-menu> <el-dropdown-item v-for="v in Myorder" :key="v.id">{{v.title}}</el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </el-link> </div> </div> </div> </template> <script setup> //引入搜索图标 import { Search,Avatar,ArrowDown } from '@element-plus/icons-vue' import { ref } from 'vue' //下拉列表 let Myorder = ref([ {id:1,title:'酒店订单'}, {id:2,title:'火车票订单'}, {id:3,title:'飞机票订单'}, {id:4,title:'旅游订单'}, {id:5,title:'全部订单'} ]) </script> <style lang="scss"> </style>
index.css
css.header-right .el-link { margin: 0 20px; } /* 伪类选择器:可以用来选取获得焦点的元素 当鼠标移入上去后取消黑色边框 */ .el-dropdown-link:focus{ outline: none; }
效果图:
11. 区域模块
-
修改代码
main.vue
vue<template> <div class="searchlist"> <div class="searchlist-item">1</div> <div class="searchlist-item">2</div> <div class="searchlist-item">3</div> <div class="searchlist-item">4</div> <div class="searchlist-item">5</div> </div> </template> <script> export default { } </script> <style lang="scss"> </style>
index.css
css/* 区域展示部分 */ .searchlist { width: 1400px; display: grid; grid-template-columns: repeat(5,auto); margin-top: 15px; } .searchlist-item { border: 1px solid #dadada; margin-left: -1px; }
效果图:
-
内部搜索框、时间选择器
遇到问题
输入框一直有黑边
解决方式
css中增加input样式
main.vue
vue<template> <div class="searchlist"> <div class="searchlist-item"> <div class="search-box"> <!-- 使用for和id进行表单绑定 --> <label for="hotels-destination">目的地/酒店名称</label> <input class="input" type="text" id="hotels-destination" placeholder="北京"> </div> </div> <div class="searchlist-item"> <div class="search-box"> <label>入住时间/退房时间</label> <el-date-picker v-model="value1" type="datetimerange" start-placeholder="Start Date" end-placeholder="End Date" :default-time="defaultTime1" /> </div> </div> <div class="searchlist-item"> <div class="search-box"> <label for="room-guest">房间及住客</label> <input class="input" type="text" id="room-guest" placeholder="1间/1位"> </div> </div> <div class="searchlist-item"> <div class="search-box"> <label for="keyword">关健词(选填)</label> <input class="input" type="text" id="keyword" placeholder="火车/酒店名称或区域"> </div> </div> <div class="searchlist-item"> <el-button type="primary" :icon="Search"></el-button> </div> </div> </template> <script setup> import {ref} from 'vue' import {Search} from '@element-plus/icons-vue' </script> <style lang="scss"> </style>
index.css
css/* 右侧下面展示 */ .el-main { min-width: 1280px; overflow: hidden; } /* 目的地/酒店名称 */ .search-box { padding: 8px 12px; } .search-box label { color: #999; display: block; } .search-box input { border:none; font-size: 16px; font-weight: 700; padding-top: 15px; } .input{ outline: none; } /* 伪类选择器,当元素获得焦点的时候,能够控制父元素的样式 */ .searchlist-item:focus-within { border-bottom: 2px solid var(--el-color-primary); } /* 入住时间/退房时间 取消边框的颜色 */ .search-box .el-date-editor.el-input__wrapper { box-shadow:none; } .search-box .el-date-editor.el-input__wrapper:hover { box-shadow:none; } /* 搜索按钮的样式 */ .searchlist-item .el-button { width: 100%; height:100%; border-radius: 0; } .searchlist-item .el-button .el-icon { font-size: 30px; }
效果图:
12. 位置区域
使用网格布局
-
新建页面,并在index.vue中加入页面
vue<template> <!-- <h1>首页</h1> --> <div class="common-layout"> <el-container> <MenuView></MenuView> <el-container> <el-header><LogoView></LogoView></el-header> <el-main><MainView></MainView></el-main> <el-top><Toplist></Toplist></el-top> </el-container> </el-container> </div> </template> <script setup> // 1.script 里加setup,引入要加载的子页面 import MenuView from './menu.vue' import MainView from './main.vue' import LogoView from './logo.vue' import Toplist from './toplist.vue'; </script> <style lang="scss"> </style>
-
修改代码
toplist.vue
vue<template> <div class="topfilter"> <div> <h4>位置区域</h4> </div> <!-- tabs切换 --> <div class="topfilter-tab"> <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick"> <!-- 数据绑定 --> <el-tab-pane :label="v.label" :name="v.name" v-for="v in topfilterlist" :key="v.id"> <el-button v-for="(k,i) in v.list" :key="i" size="small" type="info" plain>{{k}}</el-button> </el-tab-pane> </el-tabs> </div> <div> <h4>星级价格</h4> </div> <div class="topfilter-price"> <el-button size="small" type="info" plain v-for="(v,i) in pricelist" :key="i">{{v}}</el-button> </div> <div> <h4>高级筛选</h4> </div> <div class="topfilter-filter"> <el-dropdown v-for="(v,i) in filterlist" :key="i"> <span class="el-dropdown-link"> {{v.title}} <el-icon class="el-icon--right"> <!-- 箭头按钮 --> <arrow-down /> </el-icon> </span> <template #dropdown> <el-dropdown-menu> <el-dropdown-item v-for="(k,i) in v.list" :key="i">{{k}}</el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> </div> </template> <script setup> import {ref} from 'vue' //箭头图标 import { ArrowDown } from '@element-plus/icons-vue' const activeName = ref('first') let topfilterlist = ref([ {id:1,name:'first',label:'热门筛选',list:['天安门广场','王府井','北京大家','天安门广场','王府井','北京大家','天安门广场','王府井','北京大家','天安门广场','王府井','北京大家','天安门广场','王府井','北京大家','天安门广场','王府井','北京大家']}, {id:2,name:'second',label:'机场车站',list:['北京南站','北京西站','北京火车站','北京南站','北京西站','北京火车站','北京南站','北京西站','北京火车站']}, {id:3,name:'third',label:'商业区',list:['三里屯','国贸地区','西直门','三里屯','国贸地区','西直门','三里屯','国贸地区','西直门']}, {id:4,name:'fourth',label:'景点',list:['什刹海','前门大街','五道口','什刹海','前门大街','五道口','什刹海','前门大街','五道口']} ]) let pricelist = ref(['五星(钻级)','四星(钻级)','三星(钻级)','两星(钻级)','一星(钻级)']) let filterlist = ref([ {title:'早餐',list:['含早餐','单份早餐','多份早餐']}, {title:'支付方式',list:['在线付款','到店付款','闪住']}, {title:'房型',list:['双床房','三床房','单人床房','大床房','特大床房']}, {title:'酒店设施',list:['免费停车','室内游泳','单人床房','大床房','特大床房']}, {title:'住宿类型',list:['免费停车','室内游泳','单人床房','大床房','特大床房']}, {title:'酒特色主题',list:['免费停车','室内游泳','单人床房','大床房','特大床房']}, ]) </script> <style> </style>
遇到问题:
按钮居中对齐,不靠左
解决方式:
修改#app中的样式(如果在之前隐藏展开框中改过则不会出现问题)
在App.vue中,注释掉
text-align: center;
vue<template> <router-view/> </template> <style lang="scss"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; // text-align: center; color: #2c3e50; } nav { padding: 30px; a { font-weight: bold; color: #2c3e50; &.router-link-exact-active { color: #42b983; } } } </style>
为防止应样式继承产生的问题,将App.vue中的样式都注销
遇到问题:星级价格中的按钮以及高级筛选的下拉菜单不垂直居中
解决方式:
在index.css中增加样式
css.topfilter-price{ display: flex; align-items: center; } .topfilter-filter{ display: flex; align-items: center; }
-
indext.css(根据页面大小,修改了其他样式)
css/* 左侧导航栏 */ .aside { width: 200px; } .aside-list { /* 固定定位 */ position: fixed; left: 0; width: 200px; } .aside .el-menu { height:100vh; } /* 字体图标的样式 */ .aside i { font-size: 24px; font-weight: 500; margin-right: 5px; } .aside .el-radio-button__inner { border:none; font-size: 20px; } /* 页面头部 */ /* 宽度响应 */ .el-header { min-width: 1280px; } .headerNav { display: flex; justify-content: space-between; align-items: center; /* 水平垂直对齐 */ height: 70px; width:1300px; /* 固定定位 */ position:fixed; top:0; background-color: #fff; z-index: 999; padding: 10px 0; } .headerNav img { width: 100%; height: 50px; } .header-search { flex: 1; margin: 0 2rem; } /* 按钮的颜色 */ .headerNav .el-input-group__append { background-color: var(--el-color-primary); color: #fff; } .header-right .el-link { margin: 0 20px; } /* 伪类选择器:可以用来选取获得焦点的元素 当鼠标移入上去后取消黑色边框 */ .el-dropdown-link:focus{ outline: none; } /* 右侧下面展示 */ .el-main { min-width: 1280px; overflow: hidden; } /* 区域展示部分 */ .searchlist { width: 1300px; display: grid; grid-template-columns: repeat(5,auto); margin-top: 15px; } .searchlist-item { border: 1px solid #dadada; margin-left: -1px; } /* 目的地/酒店名称 */ .search-box { padding: 8px 12px; } .search-box label { color: #999; display: block; } .search-box input { border:none; font-size: 16px; font-weight: 700; padding-top: 15px; } .input{ outline: none; } /* 伪类选择器,当元素获得焦点的时候,能够控制父元素的样式 */ .searchlist-item:focus-within { border-bottom: 2px solid var(--el-color-primary); } /* 入住时间/退房时间 取消边框的颜色 */ .search-box .el-date-editor.el-input__wrapper { box-shadow:none; } .search-box .el-date-editor.el-input__wrapper:hover { box-shadow:none; } /* 搜索按钮的样式 */ .searchlist-item .el-button { width: 100%; height:100%; border-radius: 0; } .searchlist-item .el-button .el-icon { font-size: 30px; } /* topfilter开始 */ .topfilter { width: 1300px; display:grid; grid-template-columns: 130px 1fr; /* 列 */ grid-template-rows:repeat(3,auto); /* 3行 */ } .topfilter>div { border-bottom:1px solid #ddd; padding: 0.2rem 1rem; } .topfilter h4 { line-height: 17px; text-align: center; } .topfilter .el-button:hover { background-color: var(--el-color-primary); border: 1px solid var(--el-color-primary); } .topfilter-price{ display: flex; align-items: center; } .topfilter-filter{ display: flex; align-items: center; } /* 按钮的间距: */ .topfilter .el-button { margin: 7px; } /* 高级筛选 */ .topfilter-filter .el-dropdown { margin: 10px 15px; /* 下拉菜单间距 */ }
-
效果图
13. 走马灯和列表
-
新建文件,并引入
recommend.vue
vue<template> <div class="recommend"> <div class="recommend-left">推荐酒店</div> <div class="recommend-left">轮播图</div> </div> </template> <script setup> import { ref } from "vue"; </script> <style> </style>
index.vue
vue<template> <!-- <h1>首页</h1> --> <div class="common-layout"> <el-container> <MenuView></MenuView> <el-container> <el-header><LogoView></LogoView></el-header> <el-main> <MainView></MainView> <Toplist></Toplist> <Recommend></Recommend> </el-main> </el-container> </el-container> </div> </template> <script setup> // 1.script 里加setup,引入要加载的子页面 import MenuView from './menu.vue' import MainView from './main.vue' import LogoView from './logo.vue' import Toplist from './toplist.vue' import Recommend from './recommend.vue' </script> <style lang="scss"> </style>
-
效果图
-
修改代码,增加视图Recommend-left和Banner
recommend.vue
vue
<template>
<div class="recommend">
<div class="recommend-left">
<h2>推荐酒店</h2>
<Recommendlist></Recommendlist>
</div>
<div class="recommend-right">
<Banner></Banner>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
</script>
<style>
</style>
index.css
css
/* 推荐酒店 */
.recommend {
width:1300px;
display:flex;
gap: 0 20px;
padding: 10px 0;
}
.recommend-left {
width: 900px;
}
.recommend-right {
width: 400px;
}
- 修改代码
banner.vue
vue
<template>
<div class="banner">
<el-carousel height="620px">
<el-carousel-item v-for="item in bannerlist" :key="item.id">
<img :src="`/src/assets/images/${item.img_url}`" alt="">
</el-carousel-item>
</el-carousel>
</div>
</template>
<script setup>
import {ref} from 'vue'
let bannerlist = ref([
{id:1,img_url:'banner1.jpg'},
{id:2,img_url:'banner2.jpg'},
{id:3,img_url:'banner3.jpg'},
{id:4,img_url:'banner4.jpg'},
{id:5,img_url:'banner5.jpg'},
])
</script>
<style>
</style>
index.css
css
.banner {
width: 400px;
height: 620px;
}
/* 轮播图 */
.banner img {
width: 100%;
height: 100%;
object-fit: cover;
}
遇到问题:
banner.vue中图片不显示
找不到路径
解决方式:
vue<!--相对路径引用 webpack 帮我们解析时需要使用 require() 把图片路径包裹起来 --> <!-- 在public文件夹下是绝对路径,不需要经过webpack --> <img :src="require(`/src/assets/images/${item.img_url}`)" alt="">
5.完善代码
recommend.vue
vue
<template>
<div class="recommend">
<div class="recommend-left">
<h2>推荐酒店</h2>
<Recommendlist></Recommendlist>
</div>
<div class="recommend-right">
<Banner></Banner>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import Banner from './banner.vue'
import Recommendlist from './recommend-list.vue'
</script>
<style>
</style>
recommend-list.vue
vue
<template>
<div class="recommend-list">
<ul>
<li v-for="v in recommendlist" :key="v.id">
<div class="list-left">
<div class="list-left-img">
<img :src="require(`/src/assets/images/${v.img_url}`)" alt="">
</div>
<div class="list-left-title">
<div class="list-left-tagandtitle">
<h4>{{v.name}}</h4>
<img :src="require(`/src/assets/images/${v.starimg_url}`)" alt="">
<span class="badge-thumb"></span>
</div>
<div class="list-left-transport">
<p>{{v.transport}}</p>
</div>
<div class="list-left-tag">
<el-tag class="ml-2" type="danger" effect="plain" v-for="(k,i) in v.tag" :key="i">{{k}}</el-tag>
</div>
</div>
</div>
<!-- 右侧 -->
<div class="list-right">
<div class="list-right-comment">
<div class="list-right-describe">
<div class="p1">好</div>
<a href="#">3333条点评</a>
</div>
<div class="list-right-score">
<p>4.5</p>
</div>
</div>
<div class="list-right-price">
<p>¥3333</p>
<el-button type="primary">查看详情</el-button>
</div>
</div>
</li>
</ul>
</div>
</template>
<script setup>
import {ref} from 'vue'
let recommendlist = ref([
{id:1,name:'北京首都宾馆',img_url:'1.jpg',transport:'天安门/王府井 | 距市中心直线310米',starimg_url:'star5.png',tag:['网球场','商务中心','会议厅']},
{id:2,name:'北京京伦饭店',img_url:'2.jpg',transport:'国贸CBD | 距市中心直线4.1公里',starimg_url:'star4.png',tag:['停车场','健身室','SPA']},
{id:3,name:'北京新世界中心同派酒店',img_url:'3.jpg',transport:'前门/天坛公园/崇文门 | 距市中心直线1公里',starimg_url:'star4.png',tag:['桌球室','闪住','酒吧','行李寄存']},
{id:4,name:'北京新世界中心同派酒店',img_url:'4.jpg',transport:'前门/天坛公园/崇文门 | 距市中心直线1公里',starimg_url:'star4.png',tag:['桌球室','闪住','酒吧','行李寄存']},
])
</script>
<style>
</style>
banner.vue
vue
<template>
<div class="banner">
<el-carousel height="620px">
<el-carousel-item v-for="item in bannerlist" :key="item.id">
<!--相对路径引用 webpack 帮我们解析时需要使用 require() 把图片路径包裹起来 -->
<!-- 在public文件夹下是绝对路径,不需要经过webpack -->
<!-- <img :src="require(`../assets/${item.img_url}`)" alt=""> -->
<img :src="require(`/src/assets/images/${item.img_url}`)" alt="">
</el-carousel-item>
</el-carousel>
</div>
</template>
<script setup>
import {ref} from 'vue'
let bannerlist = ref([
{id:1,img_url:'banner1.jpg'},
{id:2,img_url:'banner2.jpg'},
{id:3,img_url:'banner3.jpg'},
{id:4,img_url:'banner4.jpg'},
{id:5,img_url:'banner5.jpg'},
])
</script>
<style>
</style>
index.css
vue
/* 左侧导航栏 */
.aside {
width: 200px;
}
.aside-list {
/* 固定定位 */
position: fixed;
left: 0;
width: 200px;
}
.aside .el-menu {
height:100vh;
}
/* 字体图标的样式 */
.aside i {
font-size: 24px;
font-weight: 500;
margin-right: 5px;
}
.aside .el-radio-button__inner {
border:none;
font-size: 20px;
}
/* 页面头部 */
/* 宽度响应 */
.el-header {
min-width: 1280px;
}
.headerNav {
display: flex;
justify-content: space-between;
align-items: center;
/* 水平垂直对齐 */
height: 70px;
width:1300px;
/* 固定定位 */
position:fixed;
top:0;
background-color: #fff;
z-index: 999;
padding: 10px 0;
}
.headerNav img {
width: 100%;
height: 50px;
}
.header-search {
flex: 1;
margin: 0 2rem;
}
/* 按钮的颜色 */
.headerNav .el-input-group__append {
background-color: var(--el-color-primary);
color: #fff;
}
.header-right .el-link {
margin: 0 20px;
}
/* 伪类选择器:可以用来选取获得焦点的元素
当鼠标移入上去后取消黑色边框 */
.el-dropdown-link:focus{
outline: none;
}
/* 右侧下面展示 */
.el-main {
min-width: 1280px;
overflow: hidden;
}
/* 区域展示部分 */
.searchlist {
width: 1300px;
display: grid;
grid-template-columns: repeat(5,auto);
margin-top: 15px;
}
.searchlist-item {
border: 1px solid #dadada;
margin-left: -1px;
}
/* 目的地/酒店名称 */
.search-box {
padding: 8px 12px;
}
.search-box label {
color: #999;
display: block;
}
.search-box input {
border:none;
font-size: 16px;
font-weight: 700;
padding-top: 15px;
}
.input{
outline: none;
}
/* 伪类选择器,当元素获得焦点的时候,能够控制父元素的样式 */
.searchlist-item:focus-within {
border-bottom: 2px solid var(--el-color-primary);
}
/* 入住时间/退房时间 取消边框的颜色 */
.search-box .el-date-editor.el-input__wrapper {
box-shadow:none;
}
.search-box .el-date-editor.el-input__wrapper:hover {
box-shadow:none;
}
/* 搜索按钮的样式 */
.searchlist-item .el-button {
width: 100%;
height:100%;
border-radius: 0;
}
.searchlist-item .el-button .el-icon {
font-size: 30px;
}
/* topfilter开始 */
.topfilter {
width: 1300px;
display:grid;
grid-template-columns: 130px 1fr;
/* 列 */
grid-template-rows:repeat(3,auto);
/* 3行 */
}
.topfilter>div {
border-bottom:1px solid #ddd;
padding: 0.2rem 1rem;
}
.topfilter h4 {
line-height: 17px;
text-align: center;
}
.topfilter .el-button:hover {
background-color: var(--el-color-primary);
border: 1px solid var(--el-color-primary);
}
.topfilter-price{
display: flex;
align-items: center;
}
.topfilter-filter{
display: flex;
align-items: center;
}
/* 按钮的间距: */
.topfilter .el-button {
margin: 7px;
}
/* 高级筛选 */
.topfilter-filter .el-dropdown {
margin: 10px 15px;
/* 下拉菜单间距 */
}
/* 推荐酒店 */
.recommend {
width:1300px;
display:flex;
gap: 0 20px;
padding: 10px 0;
}
.recommend-left {
width: 880px;
}
.recommend-right {
width: 420px;
}
.banner {
width: 420px;
height: 650px;
margin-top: 57px;
}
h2{
font-size: 1.2em;
margin-left: 30px;
}
/* 轮播图 */
.banner img {
width: 100%;
height: 100%;
object-fit: cover;
}
.recommend-list ul li {
display: flex;
background-color: #F4F6F9;
padding: 10px;
margin-bottom: 10px;
height: 127px;
}
.list-left {
/* 设置了弹性项目如何增大或缩小以适应其弹性容器中可用的空间 */
flex: 2;
display: flex;
}
.list-right {
flex: 1;
border-left: 1px solid #ddd;
text-align: right;
display: flex;
flex-direction: column;
justify-content: space-between;
}
/* 图片的大小 */
.list-left-img {
flex: 0.7;
}
.list-left-img img {
width: 100%;
}
.list-left-title {
flex: 3;
margin-left: 30px;
}
/* 标题 */
.list-left-tagandtitle {
font-size: 16px;
line-height: 3px;
display: flex;
margin-bottom: 8px;
align-items: center;
}
.list-left-tagandtitle img {
height: 20px;
width: auto;
margin: 0 10px;
}
.badge-thumb {
background:url(@/assets/images/help.png) no-repeat;
width: 16px;
height: 16px;
}
.list-left-transport {
margin-bottom: 8px;
}
.list-left-tag .el-tag {
margin: 3px;
}
.list-right-comment {
display:flex;
justify-content: flex-end;
margin-bottom: 10px;
height: 40px;
}
.list-right-describe{
height: 60px;
}
.p1 {
color: var(--el-color-primary);
font-size:16px;
font-weight: 700;
align-items: center;
margin-top: 0px;
}
.list-right-describe a {
color: #999;
font-size: 11px;
margin-top: 0px;
}
.list-right-score {
background-color: var(--el-color-primary);
color: #fff;
border-radius: 4px;
padding: 3px;
font-size: 18px;
font-weight: 800;
margin-left: 9px;
display: flex;
align-items: center;
}
.list-right-price p {
color: var(--el-color-primary);
font-size:20px;
font-weight: 700;
margin-top: 0px;
margin-bottom: 9px;
}
样式根据电脑屏幕进行了修改
-
效果图
代码整合
1. index.vue
vue
<template>
<!-- <h1>首页</h1> -->
<div class="common-layout">
<el-container>
<MenuView></MenuView>
<el-container>
<el-header><LogoView></LogoView></el-header>
<el-main>
<MainView></MainView>
<Toplist></Toplist>
<Recommend></Recommend>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script setup>
// 1.script 里加setup,引入要加载的子页面
import MenuView from './menu.vue'
import MainView from './main.vue'
import LogoView from './logo.vue'
import Toplist from './toplist.vue'
import Recommend from './recommend.vue'
</script>
<style lang="scss">
</style>
2. banner.vue
vue
<template>
<div class="banner">
<el-carousel height="620px">
<el-carousel-item v-for="item in bannerlist" :key="item.id">
<!--相对路径引用 webpack 帮我们解析时需要使用 require() 把图片路径包裹起来 -->
<!-- 在public文件夹下是绝对路径,不需要经过webpack -->
<!-- <img :src="require(`../assets/${item.img_url}`)" alt=""> -->
<img :src="require(`/src/assets/images/${item.img_url}`)" alt="">
</el-carousel-item>
</el-carousel>
</div>
</template>
<script setup>
import {ref} from 'vue'
let bannerlist = ref([
{id:1,img_url:'banner1.jpg'},
{id:2,img_url:'banner2.jpg'},
{id:3,img_url:'banner3.jpg'},
{id:4,img_url:'banner4.jpg'},
{id:5,img_url:'banner5.jpg'},
])
</script>
<style>
</style>
3. logo.vue
vue
<template>
<div>
<div class="headerNav">
<!-- logo -->
<div class="header-logo">
<img src="@/assets/images/logo.png" alt="">
</div>
<!-- 搜索框 -->
<div class="header-search">
<el-input
v-model="input3"
placeholder="请输入内容"
class="input-with-select"
>
<template #append>
<el-button :icon="Search" />
</template>
</el-input>
</div>
<!-- 导航菜单 -->
<div class="header-right">
<el-link :icon="Avatar">请登录</el-link>
<el-link target="_blank">注册</el-link>
<el-link>
<el-dropdown>
<span class="el-dropdown-link">
我的订单
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-for="v in Myorder" :key="v.id">{{v.title}}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-link>
</div>
</div>
</div>
</template>
<script setup>
//引入搜索图标
import { Search,Avatar,ArrowDown } from '@element-plus/icons-vue'
import { ref } from 'vue'
//下拉列表
let Myorder = ref([
{id:1,title:'酒店订单'},
{id:2,title:'火车票订单'},
{id:3,title:'飞机票订单'},
{id:4,title:'旅游订单'},
{id:5,title:'全部订单'}
])
</script>
<style lang="scss">
</style>
3. main.vue
vue
<template>
<div class="searchlist">
<div class="searchlist-item">
<div class="search-box">
<!-- 使用for和id进行表单绑定 -->
<label for="hotels-destination">目的地/酒店名称</label>
<input class="input" type="text" id="hotels-destination" placeholder="北京">
</div>
</div>
<div class="searchlist-item">
<div class="search-box">
<label>入住时间/退房时间</label>
<el-date-picker
v-model="value1"
type="datetimerange"
start-placeholder="Start Date"
end-placeholder="End Date"
:default-time="defaultTime1"
/>
</div>
</div>
<div class="searchlist-item">
<div class="search-box">
<label for="room-guest">房间及住客</label>
<input class="input" type="text" id="room-guest" placeholder="1间/1位">
</div>
</div>
<div class="searchlist-item">
<div class="search-box">
<label for="keyword">关健词(选填)</label>
<input class="input" type="text" id="keyword" placeholder="火车/酒店名称或区域">
</div>
</div>
<div class="searchlist-item">
<el-button type="primary" :icon="Search"></el-button>
</div>
</div>
</template>
<script setup>
import {ref} from 'vue'
import {Search} from '@element-plus/icons-vue'
</script>
<style lang="scss">
</style>
4. menu.vue
vue
<template>
<el-aside width="200px" class="aside">
<div class="aside-list">
<!-- 菜单标签 -->
<el-menu
default-active="2"
class="el-menu-vertical-demo"
:collapse="isCollapse"
@open="handleOpen"
@close="handleClose"
>
<!-- 隐藏展开按钮 -->
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px" >
<el-radio-button :value="false" v-show="isCollapse">|||</el-radio-button>
<el-radio-button :value="true" v-show="!isCollapse">|||</el-radio-button>
</el-radio-group>
<!-- 需要多个这个菜单项就用v-for实现-->
<el-menu-item index="v.id" v-for="v in asidelist" :key="v.id">
<!-- 实现动态icon图标 -->
<!-- <el-icon><component :is="v.icon"></component></el-icon> -->
<i class="iconfont" :class="v.icon"></i>
<template #title>{{v.title}}</template>
</el-menu-item>
</el-menu>
</div>
</el-aside>
</template>
<script setup>
import { ref } from "vue";
// 设置isCollapse的值为true,用于控制展开或隐藏
const isCollapse = ref(true)
// 导入icon图标,没用到的组件导入会报错,可以在package.json文件中
// 增加一条rules:"no-unused-vars": "off"
import {
Document,
Menu as IconMenu,
Location,
Setting,
// 9.增加新的图标
OfficeBuilding,
Bowl
} from '@element-plus/icons-vue'
// 定义左侧菜单数组,10.增加icon
// let asidelist=ref([
// {id:1,title:'酒店',icon:OfficeBuilding},
// {id:2,title:'机票',icon:Document},
// {id:3,title:'火车票',icon:Setting},
// {id:4,title:'旅游',icon:Bowl},
// {id:5,title:'景点',icon:Location},
// {id:6,title:'汽车票',icon:Document},
// {id:7,title:'船票',icon:IconMenu},
// {id:8,title:'门票',icon:OfficeBuilding},
// ])
// 引入第三方图标
let asidelist = ref([
{id:1,title:'酒店',icon:'icon-jiudian'},
{id:2,title:'机票',icon:'icon-lvxing'},
{id:3,title:'火车票',icon:'icon-huoche'},
{id:4,title:'旅游',icon:'icon-lvyou1'},
{id:5,title:'景点',icon:'icon-jingdian'},
{id:6,title:'汽车票',icon:'icon-tuijianqiche'},
{id:7,title:'船票',icon:'icon-lunchuan'},
{id:8,title:'门票',icon:'icon-menpiao'},
])
</script>
<style lang="scss">
</style>
5. recommend-list.vue
vue
<template>
<div class="recommend-list">
<ul>
<li v-for="v in recommendlist" :key="v.id">
<div class="list-left">
<div class="list-left-img">
<img :src="require(`/src/assets/images/${v.img_url}`)" alt="">
</div>
<div class="list-left-title">
<div class="list-left-tagandtitle">
<h4>{{v.name}}</h4>
<img :src="require(`/src/assets/images/${v.starimg_url}`)" alt="">
<span class="badge-thumb"></span>
</div>
<div class="list-left-transport">
<p>{{v.transport}}</p>
</div>
<div class="list-left-tag">
<el-tag class="ml-2" type="danger" effect="plain" v-for="(k,i) in v.tag" :key="i">{{k}}</el-tag>
</div>
</div>
</div>
<!-- 右侧 -->
<div class="list-right">
<div class="list-right-comment">
<div class="list-right-describe">
<div class="p1">好</div>
<a href="#">3333条点评</a>
</div>
<div class="list-right-score">
<p>4.5</p>
</div>
</div>
<div class="list-right-price">
<p>¥3333</p>
<el-button type="primary">查看详情</el-button>
</div>
</div>
</li>
</ul>
</div>
</template>
<script setup>
import {ref} from 'vue'
let recommendlist = ref([
{id:1,name:'北京首都宾馆',img_url:'1.jpg',transport:'天安门/王府井 | 距市中心直线310米',starimg_url:'star5.png',tag:['网球场','商务中心','会议厅']},
{id:2,name:'北京京伦饭店',img_url:'2.jpg',transport:'国贸CBD | 距市中心直线4.1公里',starimg_url:'star4.png',tag:['停车场','健身室','SPA']},
{id:3,name:'北京新世界中心同派酒店',img_url:'3.jpg',transport:'前门/天坛公园/崇文门 | 距市中心直线1公里',starimg_url:'star4.png',tag:['桌球室','闪住','酒吧','行李寄存']},
{id:4,name:'北京新世界中心同派酒店',img_url:'4.jpg',transport:'前门/天坛公园/崇文门 | 距市中心直线1公里',starimg_url:'star4.png',tag:['桌球室','闪住','酒吧','行李寄存']},
])
</script>
<style>
</style>
6. recommend.vue
vue
<template>
<div class="recommend">
<div class="recommend-left">
<h2>推荐酒店</h2>
<Recommendlist></Recommendlist>
</div>
<div class="recommend-right">
<Banner></Banner>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import Banner from './banner.vue'
import Recommendlist from './recommend-list.vue'
</script>
<style>
</style>
7. toplist.vue
vue
<template>
<div class="topfilter">
<div>
<h4>位置区域</h4>
</div>
<!-- tabs切换 -->
<div class="topfilter-tab">
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
<!-- 数据绑定 -->
<el-tab-pane :label="v.label" :name="v.name" v-for="v in topfilterlist" :key="v.id">
<el-button v-for="(k,i) in v.list" :key="i" size="small" type="info" plain>{{k}}</el-button>
</el-tab-pane>
</el-tabs>
</div>
<div>
<h4>星级价格</h4>
</div>
<div class="topfilter-price">
<el-button size="small" type="info" plain v-for="(v,i) in pricelist" :key="i">{{v}}</el-button>
</div>
<div>
<h4>高级筛选</h4>
</div>
<div class="topfilter-filter">
<el-dropdown v-for="(v,i) in filterlist" :key="i">
<span class="el-dropdown-link">
{{v.title}}
<el-icon class="el-icon--right">
<!-- 箭头按钮 -->
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-for="(k,i) in v.list" :key="i">{{k}}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script setup>
import {ref} from 'vue'
//箭头图标
import { ArrowDown } from '@element-plus/icons-vue'
const activeName = ref('first')
let topfilterlist = ref([
{id:1,name:'first',label:'热门筛选',list:['天安门广场','王府井','北京大家','天安门广场','王府井','北京大家','天安门广场','王府井','北京大家','天安门广场','王府井','北京大家','天安门广场','王府井','北京大家','天安门广场','王府井','北京大家']},
{id:2,name:'second',label:'机场车站',list:['北京南站','北京西站','北京火车站','北京南站','北京西站','北京火车站','北京南站','北京西站','北京火车站']},
{id:3,name:'third',label:'商业区',list:['三里屯','国贸地区','西直门','三里屯','国贸地区','西直门','三里屯','国贸地区','西直门']},
{id:4,name:'fourth',label:'景点',list:['什刹海','前门大街','五道口','什刹海','前门大街','五道口','什刹海','前门大街','五道口']}
])
let pricelist = ref(['五星(钻级)','四星(钻级)','三星(钻级)','两星(钻级)','一星(钻级)'])
let filterlist = ref([
{title:'早餐',list:['含早餐','单份早餐','多份早餐']},
{title:'支付方式',list:['在线付款','到店付款','闪住']},
{title:'房型',list:['双床房','三床房','单人床房','大床房','特大床房']},
{title:'酒店设施',list:['免费停车','室内游泳','单人床房','大床房','特大床房']},
{title:'住宿类型',list:['免费停车','室内游泳','单人床房','大床房','特大床房']},
{title:'酒特色主题',list:['免费停车','室内游泳','单人床房','大床房','特大床房']},
])
</script>
<style>
</style>