Files
rsxm-master/src/views/recruitment/components/costomCaed.vue
2025-10-21 15:51:27 +08:00

258 lines
5.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="costomCaedWrapper">
<div class="horizontal-scroll-container">
<!-- 左侧滚动按钮 -->
<!-- <button-->
<!-- class="scroll-button left"-->
<!-- :class="{ visible: canScrollLeft }"-->
<!-- @click="scrollTo('left')"-->
<!-- >-->
<!-- <svg viewBox="0 0 24 24">-->
<!-- <path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"/>-->
<!-- </svg>-->
<!-- </button>-->
<!-- 横向滚动区域 -->
<div ref="scrollContainer" class="scroll-area" @scroll="checkScroll">
<div
v-for="(tab, index) in state.tabs"
:key="index"
class="tab-item"
:class="{ active: state.activeIndex === index }"
@click="selectTab(index)"
>
{{ tab }}
</div>
</div>
<!-- 右侧滚动按钮 -->
<!-- <button-->
<!-- class="scroll-button right"-->
<!-- :class="{ visible: canScrollRight }"-->
<!-- @click="scrollTo('right')"-->
<!-- >-->
<!-- <svg viewBox="0 0 24 24">-->
<!-- <path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"/>-->
<!-- </svg>-->
<!-- </button>-->
</div>
<NetworkMap />
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from "vue";
import NetworkMap from "../card/NetworkMap.vue";
const state = reactive({
tabs: [
"公共服务站点 40",
// "培训机构 130",
// "咨询机构 220",
"劳务公司 13",
"招聘与猎头机构 5",
"⼈⼒资源服务外包机构HRO3",
"职业中介与公共就业服务机构 8"
],
activeIndex: 0
});
const scrollContainer = ref(null);
const canScrollLeft = ref(false);
const canScrollRight = ref(false);
// 检查滚动状态
const checkScroll = () => {
if (scrollContainer.value) {
const { scrollLeft, scrollWidth, clientWidth } = scrollContainer.value;
canScrollLeft.value = scrollLeft > 0;
canScrollRight.value = scrollLeft < scrollWidth - clientWidth - 1;
}
};
// 滚动到指定位置
const scrollTo = (direction) => {
if (!scrollContainer.value) return;
const container = scrollContainer.value;
const scrollAmount = 300; // 每次滚动量
if (direction === "left") {
container.scrollBy({ left: -scrollAmount, behavior: "smooth" });
} else {
container.scrollBy({ left: scrollAmount, behavior: "smooth" });
}
// 滚动结束后检查状态
setTimeout(checkScroll, 300);
};
// 点击标签
const selectTab = (index) => {
state.activeIndex = index;
// 可选:自动滚动到选中标签
scrollToTab(index);
};
// 滚动到指定标签
const scrollToTab = (index) => {
if (!scrollContainer.value) return;
const container = scrollContainer.value;
const tab = container.children[index];
if (!tab) return;
const containerWidth = container.clientWidth;
const tabLeft = tab.offsetLeft;
const tabWidth = tab.offsetWidth;
container.scrollTo({
left: tabLeft - (containerWidth - tabWidth) / 2,
behavior: "smooth"
});
};
onMounted(() => {
checkScroll();
window.addEventListener("resize", checkScroll);
});
</script>
<style lang="scss" scoped>
.costomCaedWrapper {
.echart {
margin-top: 1.5vw;
width: 100%;
height: auto;
display: block;
}
}
.horizontal-scroll-container {
position: relative;
display: flex;
align-items: center;
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
.scroll-area {
display: flex;
overflow-x: auto;
scroll-behavior: smooth;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE/Edge */
flex: 1;
}
.scroll-area::-webkit-scrollbar {
display: none; /* Chrome/Safari */
}
.tab-item {
position: relative;
flex: 0 0 auto;
margin: 0 8px;
padding: 0 0.5vw;
height: 1.875vw;
text-align: center;
font-size: 0.729vw;
line-height: 1.875vw;
border: 1px solid rgba(203, 242, 250, 0.2);
border-radius: 4px;
background: linear-gradient(
90deg,
rgba(203, 242, 250, 0) 0%,
rgba(203, 242, 250, 0.19) 51%,
rgba(203, 242, 250, 0) 100%
);
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
&.active::before {
transform: rotate(180deg);
position: absolute;
content: "";
background: url("~@/assets/images/recruitment/network-tabs-arrow.svg")
no-repeat;
background-size: auto 100%;
width: 0.6vw;
height: 0.6vw;
left: 0;
top: 50%;
margin: -0.3vw 0 0 -0.5vw;
}
&.active::after {
position: absolute;
content: "";
background: url("~@/assets/images/recruitment/network-tabs-arrow.svg")
no-repeat;
background-size: auto 100%;
width: 0.6vw;
height: 0.6vw;
right: 0;
top: 50%;
margin: -0.3vw -0.45vw 0 0;
}
}
.tab-item.active {
border: 1px solid rgba(203, 242, 250, 0.2);
border-radius: 4px;
background: linear-gradient(
90deg,
rgba(48, 220, 255, 0.12) 0%,
rgba(48, 220, 255, 0.84) 51%,
rgba(48, 220, 255, 0.12) 100%
);
color: white;
font-weight: 500;
}
.tab-item:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.scroll-button {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 1.875vw;
height: 1.875vw;
border-radius: 50%;
background: #0b1318;
border: 1px solid #0b1318;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
cursor: pointer;
opacity: 0;
transition: opacity 0.3s;
z-index: 10;
display: flex;
align-items: center;
justify-content: center;
}
.scroll-button.visible {
opacity: 1;
}
.scroll-button.left {
left: 0;
}
.scroll-button.right {
right: 0;
}
.scroll-button svg {
width: 24px;
height: 24px;
fill: #666;
}
.scroll-button:hover {
background: #f0f0f0;
}
</style>