旅游网站(携程旅行网页学习 vue3+element)

news2024/10/6 16:31:36

旅游网站

1. 创建项目

  1. 在你要创建项目的路径下打开vscode,新建终端,然后输入vue ui,进入Vue项目管理器。
  2. 选择“创建”,确定项目路径,并点击“在此创建新项目”。
  3. 在项目文件夹中输入项目名称,点击下一步;
  4. 选择“手动配置项目”,然后点击下一步;
  5. 增加选择“router”和“css”两个配置项,然后点击下一步;
  6. 选择 CSS 预处理器。node-sass 是自动编译实时的,dart-sass 需要保存后才会生效,此处建议选择 Sass/SCSS(with dart-sass);pick a linter / formatter config可以选择第一个,只检查错误。选择完成后就可以创建项目。
  7. 提示创建成功后可以用vscode打开新建的项目。

2. 新建首页

注意:App.vue是整个项目的入口文件,这个文件保持干净,后续内容多了,结构才不出错,所以新建一个首页index.vue

  1. 为避免系统提示要组合词命名文件的错误,在package.json文件中修改“rules”的值:

    "rules": {
          "vue/multi-word-component-names": "off"
        }
    
  2. 在src文件夹下的views文件夹中新建index.vue。在index.vue文件中,先设置一个简单页面,输入如下代码:(安装了插件就可以输入vue,然后选择默认vue结构,会自动补全vue结构)

    <template>
      <h1>首页</h1>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style>
    
    </style>
    
  3. 按照路由的配置方法,在router文件下设置index.js文件,把不需要的路由删除或者注释。两步走,1引入子页面,2设置路由。

    代码如下

    import { 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
    后重启项目即可

  4. 修改App.vue文件为如下代码,在这个页面中引入需要的页

    <template>
      <router-view/>
    </template>
    

效果图:
在这里插入图片描述

3. 引入ElementPlus组件

  1. 用vscode打开项目,然后在终端中,项目路径下运行命令:npm install element-plus --save

  2. 在main.js文件中配置elementplus和ico图标库,导入方法见element官网,
    https://element-plus.org/zh-CN/,修改main.js为如下代码:

    import { 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

https://hotels.ctrip.com/?allianceid=4897&sid=799747&ouid=xiecheng370&bd_creative=27771225887&bd_vid=11944392447257964181&keywordid=137481675338【携程旅游】

在这里插入图片描述

  1. 首页布局。进入element官网,https://element-plus.org/zh-CN/,选择组件,然后选择Basic 基础组件中的Container 布局容器。根据上面的图,选择左上下结构,复制代码。
    在这里插入图片描述

  2. 粘贴到index.vue中里面并进行修改。此时也可以启动服务器查看布局结果
    代码如下:

    <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>
    

    效果图:
    在这里插入图片描述

  3. 将index.vue页面中的三个组成部分拆分成menu.vue、logo.vue和main.vue三个页
    (1)在views文件夹中新建menu.vue、logo.vue和main.vue三个页面,然后将这三个组成部分的代码分别输入到对应的页面中。具体如下:

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中,然后设置组件标签,代码如下:

<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 折叠面板。
在这里插入图片描述

  1. 打开Collapse 折叠面板的代码,分析其哪些功能代码是我们需要的,不要直接全部复制。leftmenu.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>
          </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>
    
  2. 启动服务器,查看此时网页效果
    效果图:
    在这里插入图片描述

    在这里插入图片描述

  3. 修改上面的代码,实现与网站几乎相同的效果。

(1)将展开隐藏按钮标签放入到菜单标签,并将展开隐藏的文字提示改为“|||”,并且将两个标签设置v-show属性,展开的时候显示,隐藏的时候隐藏标识符号。

(2)在script里面定义左侧菜单数组

(3)在菜单项中通过v-for去实现显示菜单组

(4)更改icon图标,可以在icon图标库中复制图标名字加到已导入的图标项中

(5)修改菜单项中设置icon图标的代码,实现动态加载图标

leftmenu.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>
  1. 启动服务器,查看此时的显示效果
    在这里插入图片描述

    在这里插入图片描述

  2. 调整按钮位置

    <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. 字体图标的引入

  1. 下载第三方图标,进入阿里巴巴矢量图库https://www.iconfont.cn/?spm=a313x.manage_type_myprojects.i3.2.74bc3a812ze26a,并保存在src中
    在这里插入图片描述

    在这里插入图片描述

  2. 全局引入
    在main.js中加上代码import '@/assets/font/iconfont.css'

  3. 修改menu中代码

    <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>
    
  4. 图标效果
    在这里插入图片描述

7. 左侧导航栏样式

  1. 新建样式index.css

  2. 代码
    index.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

<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>
```
  1. 引入样式
    在main.js中import '@/assets/css/index.css'

  2. 效果图
    在这里插入图片描述

    遇到问题:

    1. 隐藏张开按钮会跟随移动

    解决方式:

    ​ 修改#appde 样式
    ​ 删除text-align: center

    如不清楚,请看12.位置区域中的解决方式

8. 头部导航栏

  1. 修改logo.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>
    

​ 效果图:
在这里插入图片描述

  1. 横向排列、固定定位
    修改index.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样式

  2. 效果图
    在这里插入图片描述

  3. logo图
    在这里插入图片描述

  4. 修改代码

    <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>
    
  5. 修改样式

    .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. 搜索框

  1. 官网地址Input 输入框 | Element Plus (element-plus.org)

  2. 修改代码
    logo.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

    .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. 头部下拉菜单

  1. 官网Link 链接 | Element Plus (element-plus.org)

  2. 修改代码
    logo.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

    .header-right .el-link {
        margin: 0 20px;
    }
    /* 伪类选择器:可以用来选取获得焦点的元素
    当鼠标移入上去后取消黑色边框 */
    .el-dropdown-link:focus{
       outline: none;
    }
    

    效果图:
    在这里插入图片描述

11. 区域模块

  1. 修改代码
    main.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

    /* 区域展示部分 */
    .searchlist {
        width: 1400px;
        display: grid;
        grid-template-columns: repeat(5,auto);
        margin-top: 15px;
    }
    .searchlist-item {
        border: 1px solid #dadada;
        margin-left: -1px;
    }
    

    效果图:
    在这里插入图片描述

  2. 内部搜索框、时间选择器

    遇到问题

    输入框一直有黑边

    解决方式

    css中增加input样式

    main.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

    /* 右侧下面展示 */
    .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;
    }
    
    

    效果图:
    在这里插入图片描述

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b7e8454de1064819a38ccb10405dfa83.png)

12. 位置区域

使用网格布局

  1. 新建页面,并在index.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>
    
  2. 修改代码
    toplist.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;

<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中增加样式

.topfilter-price{
    display: flex;
    align-items: center;
}
.topfilter-filter{
    display: flex;
    align-items: center;
}
  1. indext.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;
        /* 下拉菜单间距 */
    }
    
    
  2. 效果图
    在这里插入图片描述

13. 走马灯和列表

  1. 新建文件,并引入
    recommend.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

    <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. 效果图
    在这里插入图片描述

  3. 修改代码,增加视图Recommend-left和Banner
    recommend.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

/* 推荐酒店 */
.recommend {
    width:1300px;
    display:flex;
    gap: 0 20px;
    padding: 10px 0;
}
.recommend-left {
    width: 900px;
}
.recommend-right {
    width: 400px;
}
  1. 修改代码
    banner.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

.banner {
    width: 400px;
    height: 620px;
}
/* 轮播图 */
.banner img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

遇到问题:

banner.vue中图片不显示

找不到路径

解决方式:

<!--相对路径引用 webpack 帮我们解析时需要使用 require() 把图片路径包裹起来 -->
<!-- 在public文件夹下是绝对路径,不需要经过webpack -->

<img :src="require(`/src/assets/images/${item.img_url}`)" alt="">

5.完善代码
recommend.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

<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

<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

/* 左侧导航栏 */
.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. 效果图
    在这里插入图片描述

    在这里插入图片描述

代码整合

1. index.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

<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

<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

<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

<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

<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

<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

<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>

8. 最终效果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1818462.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot调用WebService的实践

作者所在公司的系统间的信息交互是通过webservice完成。如&#xff1a;MES与SAP的交互&#xff0c;MES与WMS的交换&#xff0c;MES与SRM的交互&#xff0c;MES与IOT的交互等。 MES是用.NET VS2008 C#写的&#xff0c;调用webservice很简单&#xff0c;这里不再赘述。如有想了解…

AI 定位!只需一张图片就能找到你,锁定具体位置!精确到经纬度

你能猜到这张自拍的拍摄地点吗?别小瞧了AI的能力,答案可能会让你吓一跳。 这事交给现在的AI来处理&#xff0c;它只需要“看”一眼&#xff0c;就能把照片里的“底裤都给扒出来”&#xff1a; 美国&#xff0c;加利福尼亚州&#xff0c;旧金山机场洗手间&#xff0c;93号登机口…

【数据结构】第十五弹---C语言实现直接插入排序

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、排序的概念及其运用 1.1、排序的概念与分类 1.2、排序运用 1.3、常见的排序算法 1.4、常见的排序算法性能测试 2、常见排序算法的实现 2…

JAVA小知识16:JAVA常用的API

一、Math 方法名说明public static int abs(int a)获取参数绝对值public static double ceil(double a)向上取整public static double floor(double a)向下取整public static int round(float a)四舍五入public static int max(int a,int b)获取两个int值中的较大值public s…

AI绘画Stable Diffusion 3 正式开源,AI生图格局迎来巨变!(附模型下载)

大家好&#xff0c;我是向阳 就在刚刚&#xff0c;Stable Diffusion 3 Medium 如约而至。 几天前&#xff0c;Stability AI 在社交平台 X 上官宣&#xff0c;SD3 Medium 将在 6 月 12 日正式开源。 这一次&#xff0c;没有跳票&#xff0c;它是真的来了。 20 亿参数大小&…

python数据分析-房价数据集聚类分析

一、研究背景和意义 随着房地产市场的快速发展&#xff0c;房价数据成为了人们关注的焦点。了解房价的分布特征、影响因素以及不同区域之间的差异对于购房者、房地产开发商、政府部门等都具有重要的意义。通过对房价数据的聚类分析&#xff0c;可以深入了解房价的内在结构和规…

C语言 | 文件操作(上)【必收藏】

文件操作&#xff08;上&#xff09; 1、使用文件的原因2、什么是文件3、二进制文件和文本文件4、 流的打开与关闭4.1 流和标准流4.1.1 流4.1.2 标准流 4.2 文件指针4.3 文件的打开和关闭 5、文件的顺序读写5.1 顺序读写函数介绍5.1.1 fputc与fgetc 1、使用文件的原因 首先来看…

据阿谱尔统计显示,2023年全球凹版印刷机市场销售额约为9.1亿美元

根据阿谱尔 (APO Research&#xff09;的统计及预测&#xff0c;2023年全球凹版印刷机市场销售额约为9.1亿美元&#xff0c;预计在2024-2030年预测期内将以超过2.54%的CAGR&#xff08;年复合增长率&#xff09;增长。 由于对软包装和印刷包装的需求不断增长&#xff0c;全球凹…

Qt绘图项目 - 简易表盘

发话少说&#xff0c;放码过来 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();prot…

3-哈希表-81-四数之和-LeetCode18

3-哈希表-81-四数之和-LeetCode18 参考&#xff1a;代码随想录 LeetCode: 题目序号18 更多内容欢迎关注我&#xff08;持续更新中&#xff0c;欢迎Star✨&#xff09; Github&#xff1a;CodeZeng1998/Java-Developer-Work-Note 技术公众号&#xff1a;CodeZeng1998&#xff…

C#发送邮件

C#发送邮件代码&#xff0c;亲测可用。 using System; using System.Net; using System.Net.Mail;namespace MailSend {class Program{static void Main(string[] args){try{MailAddress receiver new MailAddress("666666666qq.com");//666666666qq.com 换成收件人…

告别混乱!7步打造精益管理模式,让企业效率翻倍

当下&#xff0c;企业要想立于不败之地&#xff0c;就必须注重管理效率的提升。然而&#xff0c;很多企业在追求高效运营的过程中&#xff0c;却常常陷入混乱和无效的努力中。那么&#xff0c;如何才能真正实现精益管理呢&#xff1f;深圳天行健精益管理咨询公司分享步骤如下&a…

【投稿优惠】2024年计算机科学与软件工程国际会议(ICCSSE 2024)

2024年计算机科学与软件工程国际会议 2024 International Conference on Computer Science and Software Engineering 会议简介 2024年计算机科学与软件工程国际会议是一个备受全球瞩目的学术盛会&#xff0c;旨在促进计算机科学和软件工程领域的学术交流与合作。此次会议将汇聚…

Android开发之音乐播放器添加排行需求

Music统计功能需求 1.记录歌曲名称与次数(歌曲播放结束算一次)&#xff0c;根据播放次数制作一个排行列表;&#xff08;开始说要记录歌手&#xff0c;后面debug发现这个字段没有&#xff0c;暂时不记录&#xff09; 2.记录播放歌曲的时长&#xff0c;时间累加&#xff1b;&…

基于安信可串口调试助手软件调试ESP8266串口WIFI模块ESP-01S应用功能

基于安信可串口调试助手软件调试ESP8266串口WIFI模块ESP-01S应用功能 ESP8266_01S引脚功能图ESP8266_01S原理图ESP8266_01S尺寸图检验工作1、USB-TTL串口工具(推荐使用搭载CP2102芯片的安信可USB-T1串口)与ESP8266_01S WiFi模块(推荐使用安信可ESP8266系列模组)接线(注意当…

使用谷歌 Gemini API 构建自己的 ChatGPT(一)

AI领域一直由OpenAI和微软等公司主导&#xff0c;而Gemini则崭露头角&#xff0c;以更大的规模和多样性脱颖而出。它被设计用于无缝处理文本、图像、音频和视频&#xff1b;这些基础模型重新定义了人工智能交互的边界。随着谷歌在人工智能领域强势回归&#xff0c;了解Gemini如…

HMI(人机交互)应用的15大领域,欢迎补充。

HMI&#xff08;Human-Machine Interface&#xff0c;人机界面&#xff09;可以应用于许多不同的场景和行业&#xff0c;包括但不限于以下几个方面&#xff1a; 工业控制系统&#xff1a;HMI在工业生产中广泛应用&#xff0c;用于监控和控制生产过程。例如&#xff0c;工厂中的…

数据库学霸笔记

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

前端问题整理

Vue vue mvvm&#xff08;Model-View-ViewModel&#xff09;架构模式原理 Model 是数据层&#xff0c;即 vue 实例中的数据View 是视图层&#xff0c; 即 domViewModel&#xff0c;即连接Model和Vue的中间层&#xff0c;Vue实例就是ViewModelViewModel 负责将 Model 的变化反映…

构建企业核心竞争力:拥有自主大模型,引领行业未来

前言 随着人工智能技术的飞速发展&#xff0c;大模型技术已经成为推动行业进步的重要力量。在这个变革的时代&#xff0c;作为一位具有前瞻性的企业家&#xff0c;您深知拥有自主大模型对于提升公司竞争力、引领行业未来的重要性。本文将为您详细介绍大模型的市场现状以及企业…