gterFang/src/views/HomeView.vue

732 lines
19 KiB
Vue

<template>
<div class="home box-min-1200-src">
<!-- <pageTopBar :bannerList="bannerList.data.home"></pageTopBar> -->
<pageTopBar></pageTopBar>
<!-- 搜索模块 -->
<seachModule :getDataList="personHouseingInfo"></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.slice(0, 4)" :key="i">
<listItem :style="{ 'margin-left': i === 0 ? 0 : '12px' }" :data="item"
@click="publicJump(`/apartmentDetail?uniqid=${item['id']}`)"></listItem>
</div>
</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">{{ informationData && informationData[0].name }}</span>
</div>
<div v-for="(item, i) in informationData && informationData[0].list" :key="i"
class="dis-f al-item list-li">
<div class="list-mark"></div>
<div class="text-s" @click="informationDataOpen(item)">
<span class="text">{{ item.title }}</span>
</div>
</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">{{ informationData && informationData[1].name }}</span>
</div>
<div v-for="(item, i) in informationData && informationData[1].list" :key="i"
class="dis-f al-item list-li">
<div class="list-mark"></div>
<div class="text-s" @click="informationDataOpen(item)">
<span class="text">{{ item.title }}</span>
</div>
</div>
</div>
</div>
<div class="dis-f jus-x al-item s-w-100" v-if="false">
<img src="../assets/homeImage/listOnMore.svg" class="list-btn" alt="">
<img src="../assets/homeImage/listOnMore.svg" class="list-btn r-no-list mg-l-20" alt="">
<!-- <img src="../assets/homeImage/listMore.svg"
class="list-btn mg-l-20" alt=""> -->
</div>
</div>
<div v-if="advData?.banner?.image" class="information-wx-img" style="margin-top:20px;">
<!-- <img src="../assets/homeImage/informationWx.svg" class="information-wx-img" alt=""> -->
<!-- <img v-lazy="`${require('@/assets/homeImage/informationWx.svg')}`" class="information-wx-img" alt=""> -->
<img :src="advData?.banner?.image" 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=""> -->
<img v-lazy="item.image" class="img-box" alt="">
<div class="img-list">
<!-- <img :src="item.qrcode" class="img" alt=""> -->
<img v-lazy="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 v-show="waterfallList.length === 0">
<skeletonBox v-for="item in noWaterfallList" :key="item">
</skeletonBox>
</div>
<div class="waterfall-box s-w-100" ref="list" v-show="waterfallList.length > 0">
<div class="waterfall-first-box item dis-f al-item jus-x" style="flex-wrap: wrap;">
<div v-for="(item, i) in indexData.data.tabs" :key="i" class="info-box dis-f al-item jus-x"
:class="[i == 0 ? 'first' : i == 1 ? 'second' : i == 2 ? 'third' : '']" style="flex-wrap: wrap;"
@click="housingPage(item.path)">
<div>
<div class="img-box dis-f jus-x al-item">
<img src="../assets/homeImage/person.png" alt="" v-if="i == 0" class="img">
<img src="../assets/homeImage/intermediary.png" alt="" v-if="i == 1" class="img">
<img src="../assets/homeImage/brand.png" alt="" v-if="i == 2" class="img">
<img src="../assets/homeImage/seek.png" alt="" v-if="i == 3" class="img">
</div>
<div class="text-center s-w-100">
{{ item.name }}
</div>
</div>
</div>
</div>
<indexWaterfallBox v-for="(item, i) in waterfallList" :data="item" :key="i" :listMasonryInstance="listMasonryInstance"></indexWaterfallBox>
</div>
</div>
</div>
<div class="dis-f jus-x bottom-tps">
- {{ loadText }} -
</div>
<footerTool></footerTool>
<!-- <indexRegularBox></indexRegularBox> -->
</div>
<back-to-top></back-to-top>
</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 skeletonBox from '../components/skeletonBox/skeletonBox.vue'
import footerTool from '@/components/footer/footer.vue'
import { useRouter } from 'vue-router'
import store from '../store/index';
import api from "../utils/api";
import { ElMessage } from 'element-plus'
import backToTop from '@/components/public/backToTop.vue'
import Masonry from 'masonry-layout';
//瀑布实例
let listMasonryInstance = null
//
let informationData = ref([
{}, {}
])
let informationDataOpen = (item) => {
window.open(item.url)
}
let ListSelectBtn = reactive({ data: [], selectType: 'recommend' })
//首页数据
let indexData = reactive({ data: {} })
let seachTypeData = reactive({ data: [] })
let advData = ref({})
// api.index().then(res => {
// if (res.code === 200) {
// seachTypeData.data = res.data.combination
// indexData.data = res.data
// ListSelectBtn.data = res.data.recommendedTab
// }
// })
watchEffect(() => {
advData.value = store.state.advData
seachTypeData.data = store.state.seachTypeData
indexData.data = store.state.indexData
ListSelectBtn.data = store.state.ListSelectBtn
if (indexData.data.tabs.length) {
indexData.data.tabs.map(res => {
if (res.url === '/pages/personList/personList') {
res.path = '/personHousing'
} else if (res.url === '/pages/personList/personList?intermediary=1') {
res.path = '/intermediaryHousing'
} else if (res.url === "/pages/restOfWorld/restOfWorld") {
res.path = '/needHousing'
} else if (res.url === '/pages/irentList/irentList') {
res.path = '/apartment'
}
})
}
informationData.value = store.state.indexData.articleList
})
//公寓数据
let apartmentData = reactive({ data: [] })
api.getApartment().then(res => {
if (res.code === 200) {
apartmentData.data = res.data
}
})
//获取实例
let currentInstance = null
let pagevalue = ref(0)
//瀑布流数据
let pages = ref(1)
let waterfallList = ref([])
let noWaterfallList = ref(3)
//轮播
// let bannerList = reactive({ data: [] })
// let banner = () => {
// api.banner().then(res => {
// if (res.code === 200) {
// bannerList.data = res.data
// }
// })
// }
//开关
let loadMore = ref(true)
let loadText = ref('下拉加载更多')
//瀑布流数据
let getRecommendList = () => {
loadText.value = '加载中.....'
const limit = 30
api.recommendList({
page: pages.value,
limit,
type: ListSelectBtn.selectType,
pagevalue: pagevalue.value
}).then(res => {
// console.log(res)
if (res.code === 200) {
if (res.data.pagevalue) {
if (pages.value === 1) waterfallList.value = []
waterfallList.value = waterfallList.value.concat(res.data.data)
pagevalue.value = res.data.pagevalue
}
if (res.data.data.length >= limit) {
loadMore.value = true
loadText.value = '下拉加载更多'
} else {
loadMore.value = false
loadText.value = '到底了'
}
nextTick(() => {
listMasonryInstance.reloadItems();
listMasonryInstance.layout();
setTimeout(() => {
listMasonryInstance.reloadItems();
listMasonryInstance.layout();
}, 600)
})
} else {
ElMessage({
message: res.message,
center: true,
})
}
})
}
//标签切换
let listDataTypeChange = (item) => {
ListSelectBtn.selectType = item.type
loadMore.value = false
pages.value = 1
pagevalue.value = 0
getRecommendList()
}
//监听滚动条
const onPageSrcoll = (e) => {
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 - 100) {
if (loadMore.value) {
loadMore.value = false
pages.value += 1
getRecommendList()
}
}
}
//瀑布流模块
const router = useRouter()
//跳转个人房源
let personHouseingInfo = (type, data, areaItem) => {
let areaItems = {}
let setData = null
if (type === "location") {
areaItems = JSON.parse(areaItem)
setData = data.toString()
} else {
setData = data.id
}
router.push({
path: `/personHousing`,
query: {
[type]: setData,
areaItem: areaItems['id'] ? `${areaItems['id']}` : ''
},
// params:{
// type,
// data:JSON.stringify(data)
// }
})
}
//跳转房源页
let housingPage = (path) => {
router.push({
path: path,
})
}
const list = ref(null)
onMounted(() => {
listMasonryInstance = new Masonry(list.value, {
itemSelector: '.item',
gutter: 20
});
document.documentElement.scrollTop = 0
currentInstance = getCurrentInstance()
getRecommendList()
// banner()
window.addEventListener('scroll', onPageSrcoll, true);
})
onBeforeUnmount(() => {
window.removeEventListener('scroll', onPageSrcoll, true);
})
// 公共跳转
const publicJump = path => {
//router.push(path)
window.open(`${document.location.origin}${path}`)
}
</script>
<script>
export default {
name: 'HomeView'
}
</script>
<style scoped lang="less">
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;
padding: 30px 0;
}
.information-box {
width: 836px;
min-height: 309px;
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;
cursor: pointer;
}
.r-no-list {
transform: rotate(180deg);
}
.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: 16px;
color: #000000;
text-align: left;
margin-left: 15px;
}
.img {
width: 24px;
height: 24px;
}
.list-li {
margin-top: 15px;
cursor: pointer;
.text-s {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.text:hover {
text-decoration: underline;
}
.text {
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 14px;
text-align: left;
letter-spacing: normal;
color: #333333;
}
}
}
.list-mark {
width: 6px;
height: 6px;
border-radius: 50%;
background: #d7d7d7;
margin-right: 15px;
}
}
}
.information-wx-img {
width: 836px;
height: 140px;
border-radius: 10px;
display: block;
}
.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;
cursor: pointer;
}
}
.list-tab-btn:hover {
color: #333;
}
.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:hover {
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.2);
}
.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;
cursor: pointer;
}
.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: 15px;
color: #7F7F7F;
text-align: left;
}
</style>