<template>
<view class="wrapper">
<view class="wrapper-tap">
<view class="tap" @click="handleRegion('region')">
地区
<view :class="isShowPopup?'triangle-show':'triangle'"></view>
</view>
<view class="tap" @click="handleRegion('screen')">
筛选
<view :class="isScreen?'triangle-show':'triangle'"></view>
</view>
</view>
<!-- 遮罩层 -->
<view :class="isShowPopup?'make':''" @touchmove.stop.prevent="disabledScroll" @click="isShowPopup = false"></view>
<!-- 地区 -->
<view class="popup-box" :class="isShowPopup?'popup-transition':'popup-none'">
<view class="region-box">
<scroll-view class="region-province" scroll-y="true">
<view class="item-province" :class="activeProvince == index?'active-item':''" v-for="(item,index) in cityAddr"
:key="index" @click="handleActiveName('province',index)">
{{item.name}}
</view>
</scroll-view>
<scroll-view class="region-province" scroll-y="true"
:style="{width:!cityArea||cityArea.length==0?'100%':'250rpx'}" v-if="cityColumns.length>0">
<view :style="{width:!cityArea||cityArea.length==0?'100%':'250rpx'}" class="item-province"
:class="activeCity == index?'active-item-city':''" v-for="(item,index) in cityColumns" :key="index"
@click="handleActiveName('city',index)">
{{item.name}}
</view>
</scroll-view>
<scroll-view class="region-province" scroll-y="true" v-if="cityArea&&cityArea.length>0">
<view class="item-province" :class="activeArea == index?'active-item-city':''"
v-for="(item,index) in cityArea" :key="index" @click="handleActiveName('area',index)">
{{item.name}}
</view>
</scroll-view>
</view>
<view class="region-btn">
<view class="region-reset" @click="handleReset('region')">
重置
</view>
<view class="region-view" @click="handleViewCode('region')">
查看
</view>
</view>
</view>
<view :class="isScreen?'make':''" @click="isScreen = false"></view>
<!-- 筛选 -->
<view class="popup-box" :class="isScreen?'popup-transition-screen':'popup-none'">
<view class="screen-box">
<view class="screen-title" style="margin-top: 32rpx;">
品种
</view>
<scroll-view scroll-y="true" class="screen-scroll">
<view class="screen-item-check">
<view class="screec-item-variety" :class="item.isSelect?'active-item':''"
v-for="(item,index) in varietyDataList" :key="index" @click="handleSelectData(item)">
<view class="screec-item-text">
{{item.name}}
</view>
<view v-if="item.isSelect" class="right-icon"></view>
</view>
</view>
</scroll-view>
<view class="screen-title" style="margin-top: 48rpx;">
价格区间(元)
</view>
<view class="fillIn-the-blank">
<input placeholder-style="text-align: center;" type="number" @input="(e)=>handleChangePriceMin(e)"
:value="paramsData.priceMin" class="fillIn-input" placeholder="最低价" />
<text style="padding: 0 20rpx;">一</text>
<input placeholder-style="text-align: center;" type="number" @input="(e)=>handleChangePriceMax(e)"
:value="paramsData.priceMax" class="fillIn-input" placeholder="最高价" />
</view>
</view>
<view class="region-btn">
<view class="region-reset" @click="handleReset('screen')">
重置
</view>
<view class="region-view" @click="handleViewCode('screen')">
查看 ({{total>999?'999+':total}}宝贝)
</view>
</view>
</view>
</view>
</template>
<script>
import {
petItemPageCount
} from "@/api/home.js"
import {
debounce
} from "@/utils/utils.js"
export default {
props: {
// 地区数据
areaList: {
type: Array,
default: () => []
},
// 品种数据
varietyList: {
type: Array,
default: () => []
},
},
data() {
return {
total: 0, // 商品数量
activeProvince: -1, // 切换选中的省
activeCity: -1, //切换选中的市
activeArea: -1, //切换选中的市
isShowPopup: false, // 地区控制是否展示
isScreen: false, // 筛选控制是都展示
varietyDataList: [], // 品种
paramsData: {
provinceCode: [],
ids: [],
priceMin: "", //最低值
priceMax: "" // 最高值
} // 数据缓存
}
},
watch: {
varietyList: {
immediate: true,
deep: true,
handler(newVal, oldVal) {
this.varietyDataList = JSON.parse(JSON.stringify(this.varietyList))
}
}
},
computed: {
// 省
cityAddr() {
return this.areaList.length > 0 ? this.areaList : []
},
//市
cityColumns() {
let province = this.cityAddr[this.activeProvince]
let areaVOList = province ? province.areaVOList : []
let city = this.cityAddr.length > 0 ? areaVOList : []
return city
},
// 区
cityArea() {
let province = this.cityAddr[this.activeProvince] // 省
let city = province ? province.areaVOList[this.activeCity] : [] // 市
let areaVOList = city ? city.areaVOList : [] // 区
let area = this.cityAddr.length > 0 ? areaVOList : []
return []
},
},
methods: {
// 获取商品数量
handleGetCount(param) {
let params = {
petBreedIds: param.ids.join(','),
priceMin: param.priceMin || "",
priceMax: param.priceMax || ""
}
petItemPageCount(params).then((res) => {
if (res.code == 200) {
this.total = res.data
}
}).catch((err) => {
console.log(err, 'err')
})
},
// 控件
handleRegion(type) {
if (type == 'region') {
// 地区展开关闭 控制 事件
this.isShowPopup = !this.isShowPopup
this.isScreen = false
} else {
// 筛选展开关闭 控制 事件
this.isScreen = !this.isScreen
this.isShowPopup = false
}
},
// 城市切换
handleActiveName(type, index) {
if (type == 'province') {
this.activeProvince = index
this.activeCity = 0
}
if (type == 'city') {
this.activeCity = index
this.activeArea = 0
}
if (type == 'area') {
this.activeArea = index
}
},
// 选择品种
handleSelectData(data) {
const {
id
} = data
let newArr = JSON.parse(JSON.stringify(this.varietyDataList))
newArr = newArr.map((item) => {
let obj = {
...item
}
if (item.id === id) {
obj = {
...obj,
isSelect: !obj.isSelect
}
}
return obj
})
this.varietyDataList = newArr
let ids = this.varietyDataList.map((item) => {
if (item.isSelect) {
return item.id
}
}).filter((v) => v)
this.paramsData.ids = ids
this.handleGetCount(this.paramsData)
},
//
handleChangePriceMin: debounce(function(val) {
this.paramsData.priceMin = val.detail.value
this.handleGetCount(this.paramsData)
}, 500),
handleChangePriceMax: debounce(function(val) {
this.paramsData.priceMax = val.detail.value
this.handleGetCount(this.paramsData)
}, 500),
//查看
handleViewCode(type) {
if (type == 'region') {
let province = this.cityAddr[this.activeProvince].code
let city = this.cityColumns[this.activeCity].code
let area
if (this.cityArea && this.cityArea.length > 0) {
area = this.cityArea[this.activeArea].code
}
let provinceCode = this.cityArea && this.cityArea.length > 0 ? [province, city, area] : [province, city]
this.paramsData = {
...this.paramsData,
provinceCode
}
this.isShowPopup = false
}
if (type == 'screen') {
let {
priceMin,
priceMax
} = this.paramsData
let ids = this.varietyDataList.map((item) => {
if (item.isSelect) {
return item.id
}
}).filter((v) => v)
this.paramsData = {
...this.paramsData,
ids,
priceMin,
priceMax
}
this.isScreen = false
}
console.log(this.paramsData, 'params')
this.confirm(this.paramsData)
},
//触发事件
confirm(val) {
this.$emit('confirm', val)
},
// 重置
handleReset(type) {
if (type == 'region') {
this.activeProvince = -1
this.activeCity = -1
this.activeArea = -1
this.paramsData = {
...this.paramsData,
provinceCode: []
}
}
if (type == 'screen') {
let newArr = JSON.parse(JSON.stringify(this.varietyDataList))
this.varietyDataList = newArr.map((item) => {
return {
...item,
isSelect: false
}
})
this.paramsData = {
...this.paramsData,
ids: [],
priceMin: "",
priceMax: ""
}
}
this.$emit('reset', this.paramsData)
},
// 阻止滚动
disabledScroll() {
return
}
}
}
</script>
<style lang="scss" scoped>
.wrapper {
width: 100%;
position: relative;
}
.make {
position: fixed;
width: 100%;
height: 100vh;
background: #000000;
opacity: 0.6;
z-index: 9;
}
.wrapper-tap {
display: flex;
align-items: center;
justify-content: space-between;
width: 750rpx;
height: 72rpx;
background: linear-gradient(180deg, #FFFFFF 0%, #FBF8F4 100%);
border-radius: 28rpx 28rpx 0rpx 0rpx;
.tap {
display: flex;
align-items: center;
justify-content: center;
width: 50%;
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
}
}
.popup-box {
position: absolute;
z-index: 999;
width: 100%;
height: 0rpx;
background: #ffffff;
border-radius: 0rpx 0rpx 28rpx 28rpx;
overflow: hidden;
}
.popup-transition {
// animation-name: example;
// animation-duration: 2s;
height: 800rpx;
}
.popup-transition-screen {
height: 770rpx;
}
.popup-none {
display: none;
}
//正三角
.triangle {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid #D0D0D0;
margin-left: 10rpx;
}
//倒三角
.triangle-show {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #FD991B;
}
// 展开动画
@keyframes example {
from {
height: 0rpx;
}
to {
height: 800rpx;
}
}
// 地区
.region-box {
width: 100%;
height: 648rpx;
display: flex;
// align-items: center;
justify-content: flex-start;
border-radius: 0rpx 0rpx 28rpx 28rpx;
.region-province {
width: 270rpx;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.item-province {
width: 270rpx;
height: 108rpx;
background-color: #f7f7f7;
display: flex;
align-items: center;
justify-content: center;
}
.active-item {
color: #FD991B;
border-left: 1rpx solid #FD991B;
border-width: 15rpx;
background-color: #ffffff;
}
.active-item-city {
color: #FD991B;
background-color: #ffffff;
}
}
}
// 按钮
.region-btn {
position: absolute;
bottom: 32rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 32rpx 28rpx 0;
box-sizing: border-box;
.region-reset {
width: 335rpx;
height: 88rpx;
border-radius: 50rpx;
border: 2rpx solid #FE8706;
font-size: 32rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #FD981A;
text-align: center;
line-height: 88rpx;
margin-right: 10rpx;
}
.region-view {
width: 335rpx;
height: 88rpx;
background: linear-gradient(177deg, #FAB33A 0%, #FE8706 100%);
border-radius: 50rpx;
font-size: 32rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #FFFFFF;
text-align: center;
line-height: 88rpx;
margin-left: 10rpx;
}
}
// 筛选
.screen-box {
width: 100%;
height: 620rpx;
display: flex;
// align-items: center;
flex-direction: column;
justify-content: center;
border-radius: 0rpx 0rpx 28rpx 28rpx;
padding: 0 28rpx;
box-sizing: border-box;
.screen-title {
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 600;
color: #333333;
margin-bottom: 18rpx;
}
.screen-scroll {
width: 100%;
height: 300rpx;
// margin-top: 20rpx;
.screen-item-check {
width: 100%;
height: 300rpx;
display: grid;
grid-template-columns: repeat(3, 31.33%);
grid-template-rows: repeat(3, 33.33%);
grid-row-gap: 18rpx;
grid-column-gap: 18rpx;
justify-content: center;
// display: flex;
// align-items: center;
// flex-wrap: wrap;
// justify-content: flex-start;
.screec-item-variety {
display: flex;
align-items: center;
justify-content: center;
width: auto;
height: 60rpx;
background: #F5F5F5;
border-radius: 4rpx;
box-sizing: border-box;
position: relative;
// padding: 14px 73rpx;
// margin-right: 18rpx;
// margin-bottom: 18rpx;
.screec-item-text {
width: auto;
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
}
.right-icon {
position: absolute;
width: 33rpx;
height: 32rpx;
right: 0rpx;
bottom: -1rpx;
background-image: url('https://files.yiyujiehe.com/common/2023-11-13/069de3c6f9bf480d9f8017dfbfc7c8c0.png');
background-size: 100% 100%;
background-repeat: no-repeat;
}
}
.active-item {
border: 2rpx solid #FE8706;
}
}
}
.fillIn-the-blank {
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
margin: 0 auto;
.fillIn-input {
width: 290rpx;
height: 82rpx;
line-height: 2em;
border-radius: 50rpx;
border: 2rpx solid #999999;
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
padding: 0rpx 20rpx;
box-sizing: border-box;
}
}
}
</style>
需要传两个列表也可以优化成,代码比较通俗易懂,直接改动源码即可
data:{
list:[],
list2:[]
}