Files
gterFang/src/views/HomeView.vue
2023-07-14 15:47:09 +08:00

655 lines
18 KiB
Vue

<template>
<div class="home">
<pageTopBar></pageTopBar>
<!-- <headerNavigation></headerNavigation> -->
<!-- 搜索模块 -->
<seachModule></seachModule>
<!-- 房源展示 -->
<div class="dis-f jus-x al-item" style="margin-top:25px;">
<div class="body-maxWidth dis-f al-item">
<div v-for="(item, i) in apartmentData.data" :key="i">
<listItem :style="{ 'margin-left': i === 0 ? 0 : '12px' }" :data="item" v-if="i < 4"></listItem>
</div>
<!-- <listItem style="margin-left:12px;"></listItem>
<listItem style="margin-left:12px;"></listItem>
<listItem style="margin-left:12px;"></listItem> -->
</div>
</div>
<!-- 科普 -->
<div class="dis-f jus-x al-item" style="margin-top:25px;">
<div class="body-maxWidth dis-f al-item jus-bet">
<div>
<div class="information-box dis-f">
<div class="dis-f al-item jus-bet s-w-100">
<div class="list-box">
<div class="dis-f al-item mg-b-5">
<img src="../assets/homeImage/informationO.png" class="img" alt="">
<span class="title">攻略</span>
</div>
<div v-for="(item, i) in informationData" :key="i" class="dis-f al-item list-li">
<div class="list-mark"></div>
<span>{{ item }}</span>
</div>
</div>
<div class="list-box">
<div class="dis-f al-item mg-b-5">
<img src="../assets/homeImage/informationT.png" class="img" alt="">
<span class="title">科普</span>
</div>
<div v-for="(item, i) in informationData" :key="i" class="dis-f al-item list-li">
<div class="list-mark"></div>
<span>{{ item }}</span>
</div>
</div>
</div>
<div class="dis-f jus-x al-item s-w-100">
<img src="../assets/homeImage/listOnMore.svg" class="list-btn" alt="">
<img src="../assets/homeImage/listMore.svg" class="list-btn mg-l-20" alt="">
</div>
</div>
<div class="information-wx-img" style="margin-top:20px;">
<img src="../assets/homeImage/informationWx.svg" class="information-wx-img" alt="">
</div>
</div>
<div class="information-right-box dis-f jus-bet"
v-if="indexData.data.operationNumber && indexData.data.operationNumber.length">
<div class="dis-f jus-bet al-item" style="flex-wrap: wrap;">
<div class="img-box pos-r" v-for="(item, i) in indexData.data.operationNumber" :key="i"
:style="{ 'margin-top': i > 1 ? '19px' : 0 }">
<img :src="item.image" class="img-box" alt="">
<div class="img-list">
<img :src="item.qrcode" class="img" alt="">
<div>
{{ item.name }}
</div>
</div>
</div>
</div>
<!-- <div class="dis-f jus-bet al-item">
<div class="img-box pos-r">
<img src="../assets/homeImage/informationRightBoxThird.svg" class="img-box" alt="">
<div class="img-list">
<img src="../assets/homeImage/thirdCode.png" class="img" alt="">
<div>
微信扫码关注
</div>
</div>
</div>
<div class="img-box pos-r">
<img src="../assets/homeImage/informationRightBoxFourth.svg" class="img-box" alt="">
<div class="img-list">
<img src="../assets/homeImage/fourthCode.png" class="img" alt="">
<div>
微信扫码关注
</div>
</div>
</div>
</div> -->
</div>
</div>
</div>
<!-- 瀑布流 -->
<div class="dis-f jus-x">
<div class="body-maxWidth dis-f al-item" style="margin-top:50px;">
<div v-for="(item, i) in ListSelectBtn.data" :key="i" class="dis-f al-item" @click="listDataTypeChange(item)">
<div class="list-tab-btn" :class="{ 'click-tab-btn': ListSelectBtn.selectType === item.type }">
<div style="z-index: 666;position: relative;">
{{ item.name }}
</div>
<div class="tab-marker" v-show="ListSelectBtn.selectType === item.type"></div>
</div>
<div :class="{ 'line-btn': i !== ListSelectBtn.data.length - 1 }"></div>
</div>
</div>
</div>
<div class="dis-f jus-x">
<div class="body-maxWidth dis-f al-item">
<div class="waterfall-box s-w-100">
<div>
<div ref="waterfall1">
<div class="waterfall-first-box dis-f">
<div class="info-box dis-f jus-x al-item first" @click="indexWaterfallBoxCheck(indexData.data.tabs[0])">
<div>
<div class="img-box dis-f jus-x al-item">
<img src="../assets/homeImage/person.png" class="img" alt="">
</div>
<div class="text-center">{{ indexData.data.tabs && indexData.data.tabs[0].name }}</div>
</div>
</div>
<div class="info-box dis-f jus-x al-item second" @click="indexWaterfallBoxCheck(indexData.data.tabs[1])">
<div>
<div class="img-box dis-f jus-x al-item">
<img src="../assets/homeImage/intermediary.png" class="img" alt="">
</div>
<div class="text-center">{{ indexData.data.tabs && indexData.data.tabs[1].name }}</div>
</div>
</div>
<div class="info-box dis-f jus-x al-item third" @click="indexWaterfallBoxCheck(indexData.data.tabs[2])">
<div>
<div class="img-box dis-f jus-x al-item">
<img src="../assets/homeImage/brand.png" class="img" alt="">
</div>
<div class="text-center">{{ indexData.data.tabs && indexData.data.tabs[2].name }}</div>
</div>
</div>
<div class="info-box dis-f jus-x al-item" @click="indexWaterfallBoxCheck(indexData.data.tabs[3])">
<div>
<div class="img-box dis-f jus-x al-item">
<img src="../assets/homeImage/seek.png" class="img" alt="">
</div>
<div class="text-center">{{ indexData.data.tabs && indexData.data.tabs[3].name }}</div>
</div>
</div>
</div>
<indexWaterfallBox v-for="(item, i) in waterfallList['1']" :data="item" :key="i"></indexWaterfallBox>
</div>
</div>
<div>
<div ref="waterfall2">
<indexWaterfallBox v-for="(item, i) in waterfallList['2']" :data="item" :key="i"></indexWaterfallBox>
</div>
<!-- <img src="../assets/homeImage/liveImg.svg" class="live-img" alt=""> -->
</div>
<div>
<div ref="waterfall3">
<indexWaterfallBox v-for="(item, i) in waterfallList['3']" :data="item" :key="i"></indexWaterfallBox>
</div>
</div>
<div>
<div ref="waterfall4">
<indexWaterfallBox v-for="(item, i) in waterfallList['4']" :data="item" :key="i"></indexWaterfallBox>
</div>
</div>
</div>
</div>
</div>
<div class="dis-f jus-x bottom-tps">
- 到底了 -
</div>
<indexRegularBox></indexRegularBox>
</div>
</template>
<script setup>
import { reactive, ref, getCurrentInstance, onMounted, nextTick, onBeforeUnmount, watchEffect } from "vue";
import listItem from "../components/apartmentList/apartmentList.vue";
import pageTopBar from '../components/pageTopBar/pageTopBar.vue';
import indexWaterfallBox from "../components/indexWaterfallBox/indexWaterfallBox.vue";
import seachModule from "../components/seachModule/seachModule.vue";
import indexRegularBox from '../components/indexRegularBox/indexRegularBox.vue';
import headerNavigation from '../components/public/head.vue';
import { useRouter } from 'vue-router'
import store from '../store/index';
import api from "../utils/api";
//
let informationData = [
'123456', '2456789', '3456789', '47894564', '545649879987'
]
let ListSelectBtn = reactive({ data: [], selectType: 'recommend' })
//首页数据
let indexData = reactive({ data: {} })
let seachTypeData = reactive({ data: [] })
// api.index().then(res => {
// if (res.code === 200) {
// seachTypeData.data = res.data.combination
// indexData.data = res.data
// ListSelectBtn.data = res.data.recommendedTab
// }
// })
watchEffect(() => {
seachTypeData.data = store.state.seachTypeData
indexData.data = store.state.indexData
ListSelectBtn.data = store.state.ListSelectBtn
if (indexData.data.length) {
indexData.data.tabs.map(res => {
if (res.name === "个人房源") {
res.path = '/personHousing'
} else if (res.name === "中介房源") {
res.path = '/intermediaryHousing'
} else if (res.name === "求房源") {
res.path = '/needHousing'
} else if (res.name === "品牌公寓") {
res.path = ''
}
})
}
})
//公寓数据
let apartmentData = reactive({ data: [] })
api.getApartment().then(res => {
if (res.code === 200) {
apartmentData.data = res.data
}
})
//获取实例
let currentInstance = null
//瀑布流数据
let pages = ref(1)
let waterfallList = reactive({ 1: [], 2: [], 3: [], 4: [] })
//判断最小值
let getMinHeight = (data) => {
if (!currentInstance.ctx.$refs.waterfall1) return
let waterfallAll = [
currentInstance.ctx.$refs.waterfall1.offsetHeight,
currentInstance.ctx.$refs.waterfall2.offsetHeight,
currentInstance.ctx.$refs.waterfall3.offsetHeight,
currentInstance.ctx.$refs.waterfall4.offsetHeight
]
let min = Math.min(waterfallAll[0], waterfallAll[1], waterfallAll[2], waterfallAll[3])
let index = waterfallAll.indexOf(min)
waterfallList[index + 1].push(data)
// console.log(index,waterfallAll)
}
//瀑布流添加
let addListData = (data) => {
data.map((res) => {
setTimeout(() => {
getMinHeight(res)
}, 500)
})
}
//开关
let loadMore = ref(true)
//瀑布流数据
let getRecommendList = () => {
api.recommendList({
page: pages.value,
limit: 30,
type: ListSelectBtn.selectType
}).then(res => {
console.log(res)
if (res.code === 200) {
if (res.data.pagevalue) addListData(res.data.data)
if (res.data.data.length >= 30) {
loadMore.value = true
} else {
loadMore.value = false
}
}
})
}
//标签切换
let listDataTypeChange = (item) => {
ListSelectBtn.selectType = item.type
loadMore.value = false
waterfallList[1] = []
waterfallList[2] = []
waterfallList[3] = []
waterfallList[4] = []
pages.value = 1
getRecommendList()
}
//监听滚动条
const onPageSrcoll = (e) => {
if (!loadMore.value) return
let body = document.documentElement ? document.documentElement : document.body ?
document.body :
document.querySelector('.element');
let scrollTop = body.scrollTop
let clientHeight = body.clientHeight
let offsetHeight = body.offsetHeight
if (scrollTop + clientHeight === offsetHeight) {
if (loadMore.value) {
loadMore.value = false
pages.value += 1
getRecommendList()
}
}
}
//瀑布流模块
const router = useRouter()
let indexWaterfallBoxCheck = (res) => {
router.push({
path: res.path
})
}
onMounted(() => {
document.documentElement.scrollTop = 0
currentInstance = getCurrentInstance()
setTimeout(() => {
getRecommendList()
window.addEventListener('scroll', onPageSrcoll, true);
}, 1000)
})
onBeforeUnmount(() => {
window.removeEventListener('scroll', onPageSrcoll);
})
</script>
<script>
export default {
name: 'HomeView'
}
</script>
<style scoped>
img {
object-fit: contain;
}
.dis-f {
display: flex;
}
.jus-x {
justify-content: center;
}
.al-item {
align-items: center;
}
.pos-r {
position: relative;
}
.body-maxWidth {
width: 1200px;
min-width: 1200px;
}
.s-w-100 {
width: 100%;
}
.jus-bet {
justify-content: space-between;
}
.bottom-tps {
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 14px;
color: #555555;
text-align: center;
}
.information-box {
width: 836px;
height: 329px;
background: inherit;
background-color: rgba(255, 255, 255, 1);
border: none;
border-radius: 16px;
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
font-size: 14px;
padding: 15px 20px 10px 20px;
box-sizing: border-box;
flex-wrap: wrap;
.list-btn {
width: 8px;
height: 14px;
}
.mg-l-20 {
margin-left: 20px;
}
.list-box {
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 16px;
text-align: left;
letter-spacing: normal;
color: #333333;
width: 375px;
.mg-b-5 {
margin-bottom: 5px;
}
.title {
font-family: 'PingFangSC-Semibold', 'PingFang SC Semibold', 'PingFang SC', sans-serif;
font-weight: 650;
font-style: normal;
font-size: 18px;
color: #000000;
text-align: left;
margin-left: 15px;
}
.img {
width: 24px;
height: 24px;
}
.list-li {
margin-top: 20px;
cursor: pointer;
}
.list-mark {
width: 6px;
height: 6px;
border-radius: 50%;
background: #d7d7d7;
margin-right: 15px;
}
}
}
.information-wx-img {
width: 836px;
height: 120px;
border-radius: 10px;
}
.information-right-box {
width: 352px;
height: 469px;
background: inherit;
background-color: rgba(255, 255, 255, 1);
border: none;
border-radius: 16px;
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
font-size: 14px;
box-sizing: border-box;
padding: 25px 18px;
flex-direction: column;
.img-box {
width: 149px;
height: 200px;
background: inherit;
background-color: rgba(255, 255, 255, 0);
border: none;
border-radius: 8px;
.img-list {
width: 149px;
height: 200px;
border-radius: 8px;
position: absolute;
top: 0;
left: 0;
background: #fff;
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 14px;
text-align: center;
line-height: 24px;
display: none;
padding-top: 30px;
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
}
}
.img {
width: 110px;
height: 110px;
border-radius: 8px;
}
.img-box:hover .img-list {
display: block;
}
}
.list-tab-btn {
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 20px;
color: #555555;
height: 48px;
line-height: 48px;
position: relative;
cursor: pointer;
.tab-marker {
width: 20px;
height: 20px;
border-radius: 50%;
background: #50e3c2;
position: relative;
top: -45px;
left: -10px;
}
}
.click-tab-btn {
font-family: 'PingFangSC-Semibold', 'PingFang SC Semibold', 'PingFang SC', sans-serif;
font-weight: 650;
font-style: normal;
font-size: 20px;
color: #000000;
}
.line-btn {
width: 1px;
background: #d7d7d7;
height: 21px;
margin: 0 30px;
}
.waterfall-box {
display: flex;
margin-top: 30px;
justify-content: space-between;
.waterfall-first-box {
width: 284px;
height: 284px;
background-color: rgba(255, 255, 255, 1);
border-radius: 16px;
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
flex-wrap: wrap;
margin-bottom: 20px;
.first {
border-right: 1px dashed #ebebeb;
border-bottom: 1px dashed #ebebeb;
}
.second {
border-bottom: 1px dashed #ebebeb;
}
.third {
border-right: 1px dashed #ebebeb;
}
.info-box {
width: 142px;
height: 142px;
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 14px;
color: #555555;
cursor: pointer;
.text-center {
text-align: center;
}
.img-box {
width: 56px;
height: 56px;
border-radius: 16px;
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.0784313725490196);
margin-bottom: 10px;
}
.img {
width: 30px;
height: 30px;
}
}
}
}
/deep/.el-carousel__arrow {
border: 2px solid #545454;
width: 50px;
height: 50px;
}
/deep/.el-icon {
font-size: 20px;
}
/deep/.el-carousel__indicator--horizontal {
padding: var(--el-carousel-indicator-padding-vertical) 2px;
}
/deep/ .el-carousel__button {
width: 8px;
height: 8px;
border-radius: 4px;
}
/deep/ .is-active button {
background: #62b1ff;
}
/deep/ .el-input__wrapper {
background: inherit;
background-color: rgba(246, 246, 246, 1);
border-right: 0px;
border-radius: 8px 0 0 8px;
}
/deep/ .el-input__inner {
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 16px;
color: #7F7F7F;
text-align: left;
}
</style>