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}`);
}