兴蜀大屏轮播组件部分提交
This commit is contained in:
@ -1,68 +1,62 @@
|
||||
<template>
|
||||
<div class="swiper-container">
|
||||
<div class="swiper-wrapper">
|
||||
<div
|
||||
class="swiper-slide"
|
||||
:class="getSlideClass(index)"
|
||||
v-for="(slide, index) in slides"
|
||||
:key="index"
|
||||
:style="getSlideStyle(index)"
|
||||
>
|
||||
<div class="swiper-slide">
|
||||
<!-- 使用具名插槽传递每个slide的内容和索引 -->
|
||||
<div class="slide-content">
|
||||
<div class="slide-image">
|
||||
<slot name="slide" :slide="slide" :index="index" />
|
||||
<slot name="slide" />
|
||||
</div>
|
||||
<!-- <div class="slide-text">-->
|
||||
<!-- <h3>{{ slide.title }}</h3>-->
|
||||
<!-- <p>{{ slide.description }}</p>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="slide-text">
|
||||
<h3>{{ slide.title }}</h3>
|
||||
<p>{{ slide.description }}</p>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="swiper-controls">-->
|
||||
<!-- <button class="swiper-button" @click="prevSlide">←</button>-->
|
||||
<!-- <button class="swiper-button" @click="nextSlide">→</button>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="swiper-controls">
|
||||
<button class="swiper-button" @click="prevSlide">←</button>
|
||||
<button class="swiper-button" @click="nextSlide">→</button>
|
||||
</div> -->
|
||||
|
||||
<!-- <div class="swiper-pagination">-->
|
||||
<!-- <div-->
|
||||
<!-- class="pagination-bullet"-->
|
||||
<!-- v-for="(slide, index) in slides"-->
|
||||
<!-- :key="index"-->
|
||||
<!-- :class="{ active: currentIndex === index }"-->
|
||||
<!-- @click="goToSlide(index)"-->
|
||||
<!-- ></div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="swiper-pagination">
|
||||
<div
|
||||
class="pagination-bullet"
|
||||
v-for="(slide, index) in slides"
|
||||
:key="index"
|
||||
:class="{ active: currentIndex === index }"
|
||||
@click="goToSlide(index)"
|
||||
></div>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, onMounted, onBeforeUnmount, ref } from 'vue'
|
||||
import { defineComponent, onMounted, onBeforeUnmount, ref } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Carousel',
|
||||
name: "Carousel",
|
||||
props: {
|
||||
slides: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => [
|
||||
{
|
||||
title: '左侧卡片',
|
||||
description: '淡入效果从左侧进入',
|
||||
image: 'https://via.placeholder.com/600x400/3498db/ffffff?text=Left'
|
||||
},
|
||||
{
|
||||
title: '中间卡片',
|
||||
description: '淡入效果居中放大',
|
||||
image: 'https://via.placeholder.com/600x400/e74c3c/ffffff?text=Center'
|
||||
},
|
||||
{
|
||||
title: '右侧卡片',
|
||||
description: '淡入效果从右侧进入',
|
||||
image: 'https://via.placeholder.com/600x400/2ecc71/ffffff?text=Right'
|
||||
title: "左侧卡片",
|
||||
description: "淡入效果从左侧进入",
|
||||
image: "https://via.placeholder.com/600x400/3498db/ffffff?text=Left"
|
||||
}
|
||||
// {
|
||||
// title: "中间卡片",
|
||||
// description: "淡入效果居中放大",
|
||||
// image: "https://via.placeholder.com/600x400/e74c3c/ffffff?text=Center"
|
||||
// },
|
||||
// {
|
||||
// title: "右侧卡片",
|
||||
// description: "淡入效果从右侧进入",
|
||||
// image: "https://via.placeholder.com/600x400/2ecc71/ffffff?text=Right"
|
||||
// }
|
||||
]
|
||||
},
|
||||
autoPlayInterval: {
|
||||
@ -71,62 +65,71 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const currentIndex = ref(0)
|
||||
const autoPlayTimer = ref(null)
|
||||
const currentIndex = ref(0);
|
||||
const autoPlayTimer = ref(null);
|
||||
|
||||
const getSlideClass = (index) => {
|
||||
const diff = index - currentIndex.value
|
||||
if (diff === 0) return 'center'
|
||||
if (diff === -1 || (currentIndex.value === 0 && index === props.slides.length - 1)) return 'left'
|
||||
if (diff === 1 || (currentIndex.value === props.slides.length - 1 && index === 0)) return 'right'
|
||||
return ''
|
||||
}
|
||||
const diff = index - currentIndex.value;
|
||||
if (diff === 0) return "center";
|
||||
if (
|
||||
diff === -1 ||
|
||||
(currentIndex.value === 0 && index === props.slides.length - 1)
|
||||
)
|
||||
return "left";
|
||||
if (
|
||||
diff === 1 ||
|
||||
(currentIndex.value === props.slides.length - 1 && index === 0)
|
||||
)
|
||||
return "right";
|
||||
return "";
|
||||
};
|
||||
|
||||
const getSlideStyle = (index) => {
|
||||
const diff = index - currentIndex.value
|
||||
const diff = index - currentIndex.value;
|
||||
if (
|
||||
Math.abs(diff) > 1 &&
|
||||
!(currentIndex.value === 0 && index === props.slides.length - 1) &&
|
||||
!(currentIndex.value === props.slides.length - 1 && index === 0)
|
||||
) {
|
||||
return { display: 'none' }
|
||||
return { display: "none" };
|
||||
}
|
||||
return {}
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
const prevSlide = () => {
|
||||
currentIndex.value = (currentIndex.value - 1 + props.slides.length) % props.slides.length
|
||||
resetAutoPlay()
|
||||
}
|
||||
currentIndex.value =
|
||||
(currentIndex.value - 1 + props.slides.length) % props.slides.length;
|
||||
resetAutoPlay();
|
||||
};
|
||||
|
||||
const nextSlide = () => {
|
||||
currentIndex.value = (currentIndex.value + 1) % props.slides.length
|
||||
resetAutoPlay()
|
||||
}
|
||||
currentIndex.value = (currentIndex.value + 1) % props.slides.length;
|
||||
resetAutoPlay();
|
||||
};
|
||||
|
||||
const goToSlide = (index) => {
|
||||
currentIndex.value = index
|
||||
resetAutoPlay()
|
||||
}
|
||||
currentIndex.value = index;
|
||||
resetAutoPlay();
|
||||
};
|
||||
|
||||
const startAutoPlay = () => {
|
||||
pauseAutoPlay()
|
||||
pauseAutoPlay();
|
||||
autoPlayTimer.value = window.setInterval(() => {
|
||||
nextSlide()
|
||||
}, props.autoPlayInterval)
|
||||
}
|
||||
nextSlide();
|
||||
}, props.autoPlayInterval);
|
||||
};
|
||||
|
||||
const pauseAutoPlay = () => {
|
||||
if (autoPlayTimer.value) {
|
||||
clearInterval(autoPlayTimer.value)
|
||||
autoPlayTimer.value = null
|
||||
clearInterval(autoPlayTimer.value);
|
||||
autoPlayTimer.value = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const resetAutoPlay = () => {
|
||||
pauseAutoPlay()
|
||||
startAutoPlay()
|
||||
}
|
||||
pauseAutoPlay();
|
||||
startAutoPlay();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// const container = document.querySelector('.swiper-container')
|
||||
@ -135,16 +138,16 @@ export default defineComponent({
|
||||
// container.addEventListener('mouseleave', startAutoPlay)
|
||||
// }
|
||||
// startAutoPlay()
|
||||
})
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
const container = document.querySelector('.swiper-container')
|
||||
const container = document.querySelector(".swiper-container");
|
||||
if (container) {
|
||||
container.removeEventListener('mouseenter', pauseAutoPlay)
|
||||
container.removeEventListener('mouseleave', startAutoPlay)
|
||||
container.removeEventListener("mouseenter", pauseAutoPlay);
|
||||
container.removeEventListener("mouseleave", startAutoPlay);
|
||||
}
|
||||
pauseAutoPlay()
|
||||
})
|
||||
pauseAutoPlay();
|
||||
});
|
||||
|
||||
return {
|
||||
currentIndex,
|
||||
@ -153,9 +156,9 @@ export default defineComponent({
|
||||
prevSlide,
|
||||
nextSlide,
|
||||
goToSlide
|
||||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -168,13 +171,13 @@ export default defineComponent({
|
||||
.swiper-container {
|
||||
width: 17.03125vw;
|
||||
position: relative;
|
||||
//padding: 2.083vw 0;
|
||||
/* padding: 2.083vw 0; */
|
||||
}
|
||||
|
||||
.swiper-wrapper {
|
||||
display: flex;
|
||||
position: relative;
|
||||
//height: 400px;
|
||||
/* height: 400px; */
|
||||
}
|
||||
|
||||
.swiper-slide {
|
||||
|
||||
@ -1,95 +1,95 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
|
||||
const state = reactive({
|
||||
tabs: [
|
||||
'公共服务站点 300', '培训机构 130', '咨询机构 220',
|
||||
'教育中心 150', '职业介绍所 180', '就业服务中心 210'
|
||||
"公共服务站点 300",
|
||||
"培训机构 130",
|
||||
"咨询机构 220",
|
||||
"教育中心 150",
|
||||
"职业介绍所 180",
|
||||
"就业服务中心 210"
|
||||
],
|
||||
activeIndex: 0
|
||||
})
|
||||
});
|
||||
|
||||
const scrollContainer = ref(null)
|
||||
const canScrollLeft = ref(false)
|
||||
const canScrollRight = ref(false)
|
||||
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 { scrollLeft, scrollWidth, clientWidth } = scrollContainer.value;
|
||||
canScrollLeft.value = scrollLeft > 0;
|
||||
canScrollRight.value = scrollLeft < scrollWidth - clientWidth - 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 滚动到指定位置
|
||||
const scrollTo = (direction) => {
|
||||
if (!scrollContainer.value) return
|
||||
if (!scrollContainer.value) return;
|
||||
|
||||
const container = scrollContainer.value
|
||||
const scrollAmount = 300 // 每次滚动量
|
||||
const container = scrollContainer.value;
|
||||
const scrollAmount = 300; // 每次滚动量
|
||||
|
||||
if (direction === 'left') {
|
||||
container.scrollBy({ left: -scrollAmount, behavior: 'smooth' })
|
||||
if (direction === "left") {
|
||||
container.scrollBy({ left: -scrollAmount, behavior: "smooth" });
|
||||
} else {
|
||||
container.scrollBy({ left: scrollAmount, behavior: 'smooth' })
|
||||
container.scrollBy({ left: scrollAmount, behavior: "smooth" });
|
||||
}
|
||||
|
||||
// 滚动结束后检查状态
|
||||
setTimeout(checkScroll, 300)
|
||||
}
|
||||
setTimeout(checkScroll, 300);
|
||||
};
|
||||
|
||||
// 点击标签
|
||||
const selectTab = (index) => {
|
||||
state.activeIndex = index
|
||||
state.activeIndex = index;
|
||||
// 可选:自动滚动到选中标签
|
||||
scrollToTab(index)
|
||||
}
|
||||
scrollToTab(index);
|
||||
};
|
||||
|
||||
// 滚动到指定标签
|
||||
const scrollToTab = (index) => {
|
||||
if (!scrollContainer.value) return
|
||||
if (!scrollContainer.value) return;
|
||||
|
||||
const container = scrollContainer.value
|
||||
const tab = container.children[index]
|
||||
if (!tab) 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
|
||||
const containerWidth = container.clientWidth;
|
||||
const tabLeft = tab.offsetLeft;
|
||||
const tabWidth = tab.offsetWidth;
|
||||
|
||||
container.scrollTo({
|
||||
left: tabLeft - (containerWidth - tabWidth) / 2,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
behavior: "smooth"
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
checkScroll()
|
||||
window.addEventListener('resize', checkScroll)
|
||||
})
|
||||
checkScroll();
|
||||
window.addEventListener("resize", checkScroll);
|
||||
});
|
||||
</script>
|
||||
|
||||
<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>-->
|
||||
<!-- <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 ref="scrollContainer" class="scroll-area" @scroll="checkScroll">
|
||||
<div
|
||||
v-for="(tab, index) in state.tabs"
|
||||
:key="index"
|
||||
@ -102,24 +102,23 @@ onMounted(() => {
|
||||
</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>-->
|
||||
<!-- <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>
|
||||
|
||||
<img class="echart" src="~@/assets/recruitment/echart.svg" alt="">
|
||||
<img class="echart" src="~@/assets/recruitment/echart.svg" alt="" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
.costomCaedWrapper {
|
||||
|
||||
.echart {
|
||||
margin-top: 1.5vw;
|
||||
width: 100%;
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
import { defineProps } from "vue";
|
||||
import { ref, reactive, onMounted, getCurrentInstance } from "vue";
|
||||
onMounted(() => {
|
||||
console.log(props.type1, "ceshi");
|
||||
});
|
||||
import Carousel from "@/views/recruitment/components/carousel.vue";
|
||||
const props = defineProps({
|
||||
title: {
|
||||
@ -13,8 +17,24 @@ const props = defineProps({
|
||||
description: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
type1: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
title: "",
|
||||
count: "",
|
||||
class: ""
|
||||
})
|
||||
},
|
||||
type2: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
title: "",
|
||||
count: "",
|
||||
class: ""
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -25,19 +45,19 @@ const props = defineProps({
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="modelItem1">
|
||||
<div class="title">岗位种类数</div>
|
||||
<div class="count">200.000</div>
|
||||
<div :class="type1.class">
|
||||
<div class="title">{{ type1.title }}</div>
|
||||
<div class="count">{{ type1.count }}</div>
|
||||
</div>
|
||||
<div class="modelItem2">
|
||||
<div class="title">岗位人员数</div>
|
||||
<div class="count">1246</div>
|
||||
<div :class="type2.class">
|
||||
<div class="title">{{ type2.title }}</div>
|
||||
<div class="count">{{ type2.count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cardWrapper">
|
||||
<slot name="card">
|
||||
<carousel />
|
||||
<slot>
|
||||
<!-- <carousel /> -->
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
@ -53,13 +73,8 @@ const props = defineProps({
|
||||
|
||||
.cardWrapper {
|
||||
position: relative;
|
||||
left: 50%;
|
||||
top: 0.78125vw;
|
||||
transform: translateX(-50%);
|
||||
//background: url("~@/assets/recruitment/card_bg.svg") no-repeat;
|
||||
//background-size: 100% 100%;
|
||||
width: 17.03125vw;
|
||||
height: 16.615vw;
|
||||
height: calc(100% - 6.2vw);
|
||||
margin: 0 1vw;
|
||||
}
|
||||
|
||||
.row {
|
||||
@ -68,31 +83,32 @@ const props = defineProps({
|
||||
|
||||
.count {
|
||||
font-size: 1.042vw;
|
||||
color: #48FAFC;
|
||||
color: #48fafc;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #FFFFFF;
|
||||
color: #ffffff;
|
||||
margin-bottom: 0.46875vw;
|
||||
font-size: 0.729vw;
|
||||
}
|
||||
|
||||
.modelItem1 {
|
||||
padding-top: 1.09375vw;
|
||||
text-align: right;
|
||||
padding-left: 4vw;
|
||||
text-align: left;
|
||||
background: url("~@/assets/recruitment/model1.svg") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 7.823vw;
|
||||
background-size: auto 100%;
|
||||
width: 9.823vw;
|
||||
height: 4.167vw;
|
||||
margin-right: 3.021vw;
|
||||
}
|
||||
|
||||
.modelItem2 {
|
||||
padding-top: 1.09375vw;
|
||||
text-align: right;
|
||||
padding-left: 4vw;
|
||||
text-align: left;
|
||||
background: url("~@/assets/recruitment/model2.svg") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 6.823vw;
|
||||
background-size: auto 100%;
|
||||
width: 9.823vw;
|
||||
height: 4.167vw;
|
||||
}
|
||||
}
|
||||
@ -110,12 +126,12 @@ const props = defineProps({
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
text-transform: none;
|
||||
color: #A9F0FF;
|
||||
color: #a9f0ff;
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-right: 1.042vw;
|
||||
color: #A9F0FF;
|
||||
color: #a9f0ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user