vue3+TS项目 静态页面

197 阅读2分钟

home页面下分成banner、search、region、card等组件

└─src
    ├─assets
    │  └─home
    ├─components
    │  ├─hospital_bottom
    │  ├─hospital_top
    │  └─icons
    ├─router
    ├─style
    └─views
        ├─home
        │  ├─banner
        │  ├─card
        │  ├─region
        │  └─search
        └─hospital

home

<template>
  <!-- banner图 -->
  <banner></banner>
  <!-- 搜索框和筛选 -->
  <search></search>
  <!-- 筛选 -->
  <region></region>
  <!-- 医院信息卡片 -->
  <div class="hospital">
    <card v-for="i in cardNum"></card>
  </div>
</template>

<script setup lang='ts'>
import banner from './banner/index.vue'
import search from './search/index.vue'
import card from './card/index.vue'
import region from './region/index.vue'
import { ref } from 'vue'

const cardNum = ref(10)
</script>

<style scoped lang='scss'>
.hospital {
  width: 1000px;
  margin: 30px 0;
  padding-right: 90px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}
</style>

banner

<template>
  <!-- banner图 -->
  <div class="banner">
    <el-carousel indicator-position="outside" height="350px">
      <el-carousel-item v-for="item in banner_list" :key="item">
        <!-- <h3 class="small justify-center" text="2xl">{{ item }}</h3> -->
        <img :src="item" alt="">
      </el-carousel-item>
    </el-carousel>
  </div>
</template>

<script setup lang='ts'>
import { ref } from 'vue'

const banner_list = ref([
  'http://syt.atguigu.cn/_nuxt/img/web-banner1.b91d1a1.png',
  'http://syt.atguigu.cn/_nuxt/img/web-banner1.b91d1a1.png'
])
</script>

<style scoped lang='scss'>
.banner {
  img {
    width: 100%;
  }
}
</style>

search

<template>
  <!-- 搜索框 -->
  <div class="search">
    <el-autocomplete clearable placeholder="请输入医院搜索"></el-autocomplete>
    <el-button type="primary" :icon="Search"></el-button>
  </div>
</template>

<script setup lang='ts'>
import { Search } from '@element-plus/icons-vue'
import { ref } from 'vue'
const keyWord = ref('')
</script>

<style scoped lang='scss'>
// 常用的3中深度选择器: 
// 1.css : >>>
// 2.less: /deep/
// 3.scss: ::v-deep
.search {
  margin: 10px 0;
  text-align: center;

  ::v-deep(.el-input__wrapper) {
    width: 600px;
    margin-left: 10px;
  }
}
</style>

region

<template>
<!-- 筛选条件 -->
<div class="filter">
    <h1>医院</h1>
    <div class="level">
      <span>等级:</span>
      <ul>
        <li>三级甲等</li>
        <li>三级乙等</li>
        <li>二级甲等</li>
        <li>二级乙等</li>
        <li>其他</li>
      </ul>
    </div>
    <div class="area">
      <span>区域:</span>
      <ul>
        <li>东城区</li>
        <li>西城区</li>
        <li>朝阳区</li>
        <li>丰台区</li>
        <li>海淀区</li>
        <li>石景山区</li>
        <li>通州区</li>
        <li>顺义区</li>
        <li>大兴区</li>
      </ul>
    </div>
  </div>
</template>

<script setup lang='ts'>

</script>

<style scoped lang='scss'>
.filter {
  color: #999;
  font-size: 14px;

  h1 {
    font-size: 16px;
    color: #333;
    font-weight: 700;
    margin: 30px 0;
  }

  .level {
    display: flex;

    ul {
      display: flex;
      gap: 35px;
      margin-left: 10px;
    }
  }

  .area {
    display: flex;
    margin: 20px 0;

    ul {
      display: flex;
      gap: 35px;
      margin-left: 10px;
    }
  }
}
</style>

card

<template>
  <!-- 医院列表数据 -->
  <el-card class="box-card" shadow="hover">
    <div class="left">
      <div class="title">北京大学国际医院</div>
      <div class="content">
        <div class="flex-item">
          <Histogram style="width: 1.3em; height: 1.3em; margin-right: 5px" />
          <span>三级甲等</span>
        </div>
        <div class="flex-item">
          <Clock style="width: 1.3em; height: 1.3em; margin-right: 5px" />
          <span>每天放号</span>
        </div>
      </div>
    </div>
    <div class="right">
      <img src="@/assets/home/hospital.jpg" alt="">
    </div>
  </el-card>
</template>

<script setup lang='ts'>

</script>

<style scoped lang='scss'>
.box-card {
  width: 48%;
  margin: 10px 0;

  ::v-deep(.el-card__body) {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .left {
    font-size: 16px;
    color: #333;
    width: 60%;

    .title {
      margin-bottom: 20px;
    }

    .content {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-size: 14px;
      color: #999;

      .flex-item {
        display: flex;
        align-items: center;
      }
    }
  }

  .right {
    img {
      width: 80px;
      height: 80px;
    }
  }
}
</style>

封装axios

// 对axios进行二次封装,作用:
// 1. 统一处理请求和响应,如添加请求头、错误处理等。
// 2. 拦截请求和响应,如添加loading效果、统一处理token过期等。
// 3. 封装常用的请求方法,如get、post等。
// 4. 支持配置请求的基础地址、超时时间等。

import axios from 'axios';

// 创建一个axios实例,并设置基础URL和超时时间
const request = axios.create({
    baseURL: 'https://api.example.com', // 设置请求的基础地址
    timeout: 5000 // 设置请求的超时时间
})

// 使用请求拦截器
request.interceptors.request.use(config => {
    // 在发送请求之前做些什么,如添加请求头、loading效果等,config需要返回
    return config;
})


// 使用相应拦截器
request.interceptors.response.use(response => {
    // 在接收到响应之后做些什么,如处理loading效果、错误处理等
    return response.data;
}, error => {
    return Promise.reject(new Error(error));
})

export default request;

配置跨域

// vite.config.ts中配置代理跨域
  server: {
    proxy: {
      '/api': {
        target: 'http://syt.atguigu.cn', // 设置目标服务器地址
        changeOrigin: true
      }
    }
  }

api目录 home的api放在index.ts中

import request from "@/utils/request";

enum HomeApi {
    HOSPITAL_LIST = '/hosp/hospital/',
}

export const getHospitalList = (page: number, limit: number) => {
    return request.get(HomeApi.HOSPITAL_LIST + `${page}/${limit}`);
}