flat:AI+
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
<template>
|
||||
<view v-if="show" class="modal-mask">
|
||||
<view class="modal-container">
|
||||
<!-- 头部 -->
|
||||
<view class="modal-header">
|
||||
<text class="back-btn" @click="handleClose">
|
||||
<uni-icons type="left" size="24"></uni-icons>
|
||||
</text>
|
||||
<text class="modal-title">{{ title }}</text>
|
||||
<view class="back-btn"></view>
|
||||
</view>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<view class="content-wrapper">
|
||||
<!-- 左侧筛选类别 -->
|
||||
<scroll-view class="filter-nav" scroll-y>
|
||||
<view
|
||||
v-for="(item, index) in filterOptions"
|
||||
:key="index"
|
||||
class="nav-item"
|
||||
:class="{ active: activeTab === item.key }"
|
||||
@click="scrollTo(item.key)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 右侧筛选内容 -->
|
||||
<scroll-view class="filter-content" :scroll-into-view="activeTab" scroll-y>
|
||||
<template v-for="(item, index) in filterOptions" :key="index">
|
||||
<view class="content-item">
|
||||
<view class="item-title" :id="item.key">{{ item.label }}</view>
|
||||
<checkbox-group class="check-content" @change="(e) => handleSelect(item.key, e)">
|
||||
<label
|
||||
v-for="option in item.options"
|
||||
:key="option.value"
|
||||
class="checkbox-item"
|
||||
:class="{ checkedstyle: selectedValues[item.key]?.includes(String(option.value)) }"
|
||||
>
|
||||
<checkbox
|
||||
style="display: none"
|
||||
:value="String(option.value)"
|
||||
:checked="selectedValues[item.key]?.includes(String(option.value))"
|
||||
/>
|
||||
<text class="option-label">{{ option.label }}</text>
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</template>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<view class="modal-footer">
|
||||
<button class="footer-btn" type="default" @click="handleClear">清除</button>
|
||||
<button class="footer-btn" type="primary" @click="handleConfirm">确认</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed, onBeforeMount } from 'vue';
|
||||
import useDictStore from '@/stores/useDictStore';
|
||||
const { getTransformChildren } = useDictStore();
|
||||
const props = defineProps({
|
||||
show: Boolean,
|
||||
title: {
|
||||
type: String,
|
||||
default: '筛选',
|
||||
},
|
||||
area: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['confirm', 'close', 'update:show']);
|
||||
|
||||
// 当前激活的筛选类别
|
||||
const activeTab = ref('');
|
||||
|
||||
// 存储已选中的值 {key: [selectedValues]}
|
||||
const selectedValues = reactive({});
|
||||
|
||||
const filterOptions = ref([]);
|
||||
|
||||
onBeforeMount(() => {
|
||||
const arr = [
|
||||
getTransformChildren('education', '学历要求'),
|
||||
getTransformChildren('experience', '工作经验'),
|
||||
getTransformChildren('scale', '公司规模'),
|
||||
];
|
||||
if (props.area) {
|
||||
arr.push(getTransformChildren('area', '区域'));
|
||||
}
|
||||
filterOptions.value = arr;
|
||||
activeTab.value = 'education';
|
||||
});
|
||||
|
||||
// 处理选项选择
|
||||
const handleSelect = (key, e) => {
|
||||
selectedValues[key] = e.detail.value.map(String);
|
||||
};
|
||||
const scrollTo = (key) => {
|
||||
activeTab.value = key;
|
||||
};
|
||||
// 清除所有选择
|
||||
const handleClear = () => {
|
||||
Object.keys(selectedValues).forEach((key) => {
|
||||
selectedValues[key] = [];
|
||||
});
|
||||
};
|
||||
|
||||
// 确认筛选
|
||||
function handleConfirm() {
|
||||
emit('confirm', selectedValues);
|
||||
handleClose();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const handleClose = () => {
|
||||
emit('update:show', false);
|
||||
emit('close');
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
height: 88rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 32rpx;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
position: relative;
|
||||
|
||||
.back-btn {
|
||||
font-size: 36rpx;
|
||||
width: 48rpx;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.filter-nav {
|
||||
width: 200rpx;
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.nav-item {
|
||||
height: 100rpx;
|
||||
padding: 0 20rpx;
|
||||
line-height: 100rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
|
||||
&.active {
|
||||
background-color: #fff;
|
||||
color: #007aff;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
|
||||
.content-item {
|
||||
margin-top: 40rpx;
|
||||
.item-title {
|
||||
width: 281rpx;
|
||||
height: 52rpx;
|
||||
font-family: Inter, Inter;
|
||||
font-weight: 400;
|
||||
font-size: 35rpx;
|
||||
color: #000000;
|
||||
line-height: 41rpx;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
text-transform: none;
|
||||
}
|
||||
}
|
||||
.content-item:first-child {
|
||||
margin-top: 0rpx;
|
||||
}
|
||||
|
||||
.check-content {
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
place-items: center;
|
||||
|
||||
.checkbox-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 228rpx;
|
||||
height: 65rpx;
|
||||
margin: 20rpx 20rpx 0 0;
|
||||
text-align: center;
|
||||
background-color: #d9d9d9;
|
||||
|
||||
.option-label {
|
||||
font-size: 28rpx;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.checkedstyle {
|
||||
background-color: #007aff;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
border-top: 1rpx solid #eee;
|
||||
|
||||
.footer-btn {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
line-height: 100rpx;
|
||||
|
||||
&:first-child {
|
||||
border-right: 1rpx solid #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user