- 移除 Element UI 的 el-carousel 组件 -引入 Swiper 库并实现轮播功能 - 优化轮播项的样式和布局 - 添加自定义左右按钮和分页器 - 实现视频自动播放和轮播同步 - 优化轮播切换效果,支持 fade切换
430 lines
11 KiB
Vue
430 lines
11 KiB
Vue
<template>
|
||
<div class="operating-container">
|
||
<div class="top">
|
||
<p class="fw-bold fs-24 title">简单4步,轻松完成你的调研</p>
|
||
<p class="desc">创建、编辑、投放、分析,让洞察更简单</p>
|
||
</div>
|
||
<div style="height: 80%">
|
||
<div class="swiper-container" ref="swiperContainer">
|
||
<div class="swiper-wrapper">
|
||
<div
|
||
v-for="(item, index) in operatingList"
|
||
:key="index"
|
||
class="swiper-slide"
|
||
>
|
||
<div class="flex" style="justify-content: center">
|
||
<div style="margin-right: 9%">
|
||
<div class="flex-start operating-item" >
|
||
<p class="progress" :style="{'color':item.btnColor}">
|
||
<span class="fs-36">
|
||
{{index+1}}
|
||
</span>
|
||
<img src="@/assets/img/home/xiegang.png" alt="">
|
||
<span>
|
||
{{operatingList.length}}
|
||
</span>
|
||
</p>
|
||
<div class="info">
|
||
<p>{{item.title}}</p>
|
||
<p>{{item.desc}}</p>
|
||
</div>
|
||
</div>
|
||
<ul class="desc-item">
|
||
<li class="flex" v-for="(tips,index) in item.descList" :key="index">
|
||
<p class="block"></p>
|
||
{{tips}}
|
||
<span class="fs-12 tag" v-if="index === 0 && item.isShowTag">
|
||
新功能
|
||
</span>
|
||
</li>
|
||
</ul>
|
||
<a-button type="primary" @click="toSurveyInfo(item,index)">
|
||
立即体验
|
||
<img src="@/assets/img/home/tow.png" alt=""
|
||
style="margin-left: 5px;margin-bottom: 2px">
|
||
</a-button>
|
||
</div>
|
||
<div>
|
||
<video
|
||
ref="videoPlayer"
|
||
class="video-player"
|
||
width="820"
|
||
height="420"
|
||
autoplay
|
||
muted
|
||
playsinline
|
||
style="width: 100%;">
|
||
|
||
<source :src="getVideo(index)" type="video/mp4">
|
||
Your browser does not support the video tag.
|
||
</video>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 分页器 -->
|
||
<div class="swiper-pagination" ref="pagination"></div>
|
||
|
||
<!-- 自定义左右按钮 -->
|
||
<div class="custom-swiper-button-prev" ref="prevBtn" @click="goPre">
|
||
<img ref="prevImg" src="@/assets/img/home/kanoicon.png" alt="Previous" />
|
||
</div>
|
||
<div class="custom-swiper-button-next" ref="nextBtn" @click="goNext">
|
||
<img ref="nextImg" src="@/assets/img/home/pkicon.png" alt="Next" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script setup>
|
||
import {ref, onMounted, onBeforeUnmount} from 'vue'
|
||
import Swiper from 'swiper';
|
||
import 'swiper/swiper-bundle.css';
|
||
import { useRouter } from 'vue-router';
|
||
import { getQueryUserSurvey } from '@/api/home';
|
||
|
||
const router = useRouter();
|
||
const emit = defineEmits(['create-survey']);
|
||
|
||
const swiperContainer = ref(null);
|
||
const pagination = ref(null);
|
||
const prevBtn = ref(null);
|
||
const nextBtn = ref(null);
|
||
const prevImg = ref(null);
|
||
const nextImg = ref(null);
|
||
|
||
// 🟩 存储 Swiper 实例
|
||
let mySwiper = null;
|
||
|
||
const goPre = () => {
|
||
if (mySwiper) {
|
||
mySwiper.slidePrev(); // 👈 使用实例方法
|
||
}
|
||
};
|
||
|
||
const goNext = () => {
|
||
if (mySwiper) {
|
||
mySwiper.slideNext(); // 👈 使用实例方法
|
||
}
|
||
};
|
||
|
||
const operatingList = ref(
|
||
[
|
||
{
|
||
title: '多种方式',
|
||
desc:'快速创建问卷',
|
||
descList:[
|
||
'一句话AI生成问卷,高效智能','20+专业场景模板,快速创建','WORD模板上传,一键导入','空白创建编辑,灵活简单'
|
||
],
|
||
btnColor:'green',
|
||
isShowTag:true
|
||
},
|
||
{
|
||
title: '编辑质检',
|
||
desc:'设计快速搞定',
|
||
descList:[
|
||
'30+专业题型及模型题组,多种逻辑适配各类场景','AI多维度问卷质检,快速识别问题提供建议',
|
||
'多种主题、九宫格抽奖, 自定义问卷风格', '多人协作编辑,便捷协同快捷高效'
|
||
],
|
||
btnColor:'green',
|
||
key:'design'
|
||
},{
|
||
title: '精准触达',
|
||
desc:'投放轻松高效',
|
||
descList:[
|
||
'多元样本资源精准圈选,在线一站式投放','标准链接及二维码,问卷快捷私发群发','自定义链接参数,记录多渠道样本来源','回收进度、配额进度在线实时追踪'
|
||
],
|
||
btnColor:'green',
|
||
key:'accurate'
|
||
},{
|
||
title: '数据分析',
|
||
desc:'多种维度洞察',
|
||
descList:[
|
||
'AI数据清洗,无效数据在线剔除','AI智能总结,调研结论一键洞察','专业模型看板,直达分析结论','个性化交叉分析,多维数据挖掘'
|
||
],
|
||
btnColor:'green',
|
||
key:'particulars'
|
||
}])
|
||
const toSurveyInfo = async (item,index) => {
|
||
let res = await getQueryUserSurvey()
|
||
const {sn} = res.data
|
||
const urlJson = {
|
||
design: `/survey/planet/design?sn=${sn}`,
|
||
accurate: `/survey/publish/accurate?sn=${sn}`,
|
||
particulars: `/survey/analyse/diagram?sn=${sn}`,
|
||
};
|
||
if (index === 0){
|
||
// 在第 101 行通过事件通知父组件调用 Scene.vue 文件的 createScene 方法
|
||
const sceneObj = {
|
||
title: '智能创建',
|
||
description: 'AI随行,调研随心',
|
||
value: 1
|
||
};
|
||
// 通过事件向父组件发送信号,让父组件调用 Scene 组件的 createScene 方法
|
||
emit('create-survey', sceneObj, 0);
|
||
}else{
|
||
if (res.data.flag){
|
||
await router.push({
|
||
path: urlJson[item.key],
|
||
query: {
|
||
sn,
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
const getVideo = (index) => {
|
||
return require(`@/assets/img/home/video${index+1}.mp4`)
|
||
}
|
||
const addVideoEndedListener =()=> {
|
||
const videos = document.querySelectorAll('.video-player');
|
||
|
||
videos.forEach((video, index) => {
|
||
video.addEventListener('ended', () => {
|
||
if (index < operatingList.value.length - 1) {
|
||
mySwiper.slideNext(); // 自动滑动到下一页
|
||
}
|
||
});
|
||
// // 使用 WeakMap 或 data-* 存储监听器,方便后续移除
|
||
// video._onVideoEnd = onVideoEnd;
|
||
// video.addEventListener('ended', onVideoEnd);
|
||
});
|
||
}
|
||
/**
|
||
* 更新左右图标
|
||
* @param currentIndex
|
||
*/
|
||
const updateButtonImages = (currentIndex) => {
|
||
// 获取 next 按钮的 img 元素
|
||
const nextImgElement = nextImg.value;
|
||
const prevImgElement = prevImg.value;
|
||
|
||
if (currentIndex === 0) {
|
||
prevImg.value.src = require('@/assets/img/home/arrow-dis.png');
|
||
nextImg.value.src = require('@/assets/img/home/arrow-act.png');
|
||
prevImgElement.style.transform = 'rotate(0deg)';
|
||
} else if (currentIndex === 3) {
|
||
nextImg.value.src = require('@/assets/img/home/arrow-dis.png');
|
||
nextImgElement.style.transform = 'rotate(180deg)';
|
||
}else{
|
||
// 其他情况恢复默认图片
|
||
prevImg.value.src = require('@/assets/img/home/arrow-act.png');
|
||
nextImg.value.src = require('@/assets/img/home/arrow-act.png');
|
||
prevImgElement.style.transform = 'rotate(180deg)';
|
||
nextImgElement.style.transform = 'rotate(0deg)';
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 自动播放视频
|
||
*/
|
||
const autoPlayCurrentVideo = () => {
|
||
const activeSlide = mySwiper.slides[mySwiper.realIndex];
|
||
if (activeSlide) {
|
||
const video = activeSlide.querySelector('.video-player');
|
||
if (video) {
|
||
video.play().catch(err => {
|
||
console.warn('视频自动播放失败(可能被浏览器策略阻止)', err);
|
||
});
|
||
}
|
||
}
|
||
};
|
||
|
||
onMounted(() => {
|
||
// 🟩 初始化 Swiper 并赋值给 mySwiper
|
||
mySwiper = new Swiper(swiperContainer.value, {
|
||
loop: false,
|
||
autoplay: {
|
||
delay: 1300,
|
||
},
|
||
pagination: {
|
||
el: pagination.value,
|
||
clickable: true,
|
||
},
|
||
navigation: {
|
||
nextEl: nextBtn.value,
|
||
prevEl: prevBtn.value,
|
||
},
|
||
effect: 'fade',
|
||
fadeEffect: {
|
||
// crossFade: true, // 启用交叉淡出
|
||
},
|
||
simulateTouch: false, // 禁止滑动切换
|
||
on: {
|
||
init: () => {
|
||
updateButtonImages(0)
|
||
addVideoEndedListener(); // 初始化时添加监听器
|
||
},
|
||
slideChange: () => {
|
||
updateButtonImages(mySwiper.realIndex)
|
||
autoPlayCurrentVideo(); // 每次切换时播放当前页视频
|
||
},
|
||
},
|
||
});
|
||
});
|
||
// 在组件卸载时清理监听器
|
||
onBeforeUnmount(() => {
|
||
const videos = document.querySelectorAll('.video-player');
|
||
videos.forEach(video => {
|
||
if (video._onVideoEnd) {
|
||
video.removeEventListener('ended', video._onVideoEnd);
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
p{
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
.fs-36{
|
||
font-size: 36px;
|
||
}
|
||
.fs-34{
|
||
font-size: 34px;
|
||
}
|
||
li{
|
||
list-style-type: none;
|
||
}
|
||
.operating-container{
|
||
margin-top: 20px;
|
||
min-height: 600px;
|
||
height: 600px;
|
||
.top{
|
||
margin-bottom: 40px;
|
||
}
|
||
&>div:first-child {
|
||
text-align: center;
|
||
|
||
}
|
||
.title{
|
||
margin-bottom: 5px;
|
||
}
|
||
.desc{
|
||
color: #7F7F81;
|
||
}
|
||
.operating-item{
|
||
.progress{
|
||
display: flex;
|
||
align-items: baseline;
|
||
letter-spacing: 1px;
|
||
& :nth-child(1){
|
||
color: #70B937;
|
||
font-size: 45px;
|
||
font-weight: 400;
|
||
}
|
||
& :nth-child(2){
|
||
height: 33px;
|
||
}
|
||
& :nth-child(3){
|
||
color: #000;
|
||
font-size: 24px;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
.info{
|
||
font-size: 24px;
|
||
font-weight: bold;
|
||
margin-left: 20px;
|
||
white-space: nowrap;
|
||
}
|
||
}
|
||
.desc-item{
|
||
font-weight: bold;
|
||
font-size: 12px;
|
||
color: #000;
|
||
margin-left: 5%;
|
||
margin-bottom: 40px;
|
||
width: max-content;
|
||
li{
|
||
margin: 20px 0;
|
||
justify-content: flex-start;
|
||
.block{
|
||
width: 8px;
|
||
height: 8px;
|
||
background-color: #000;
|
||
margin-right: 10px;
|
||
}
|
||
.tag{
|
||
font-weight: 500;
|
||
font-size: 13px;
|
||
color: #2F5EF2;
|
||
background-color: #E2E8FA;
|
||
border: 1px solid #2F5EF2;
|
||
padding: 1px 5px;
|
||
border-radius: 6px;
|
||
margin-left: 10px
|
||
}
|
||
}
|
||
}
|
||
}
|
||
:deep(.el-carousel__arrow--right){
|
||
border: 1px solid #C1C1C2;
|
||
background: transparent;
|
||
color: #C1C1C2;
|
||
}
|
||
:deep(.el-carousel__arrow--left){
|
||
border: 1px solid #C1C1C2;
|
||
background: transparent;
|
||
color: #C1C1C2;
|
||
}
|
||
:deep(.el-carousel__container) {
|
||
height: 100%;
|
||
}
|
||
|
||
.swiper-container {
|
||
height: 100%;
|
||
width: 95%;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.swiper-slide {
|
||
//display: flex;
|
||
//align-items: center;
|
||
//justify-content: center;
|
||
font-size: 24px;
|
||
height: 100%;
|
||
//position: absolute; /* 必须设置为绝对定位才能实现 fade 切换 */
|
||
width: 100%;
|
||
//top: 0;
|
||
//left: 0;
|
||
//transition: opacity 1s ease;
|
||
}
|
||
|
||
/* 自定义按钮样式 */
|
||
.custom-swiper-button-prev,
|
||
.custom-swiper-button-next {
|
||
position: absolute;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
z-index: 10;
|
||
cursor: pointer;
|
||
width: 40px;
|
||
height: 40px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
//background-color: rgba(0, 0, 0, 0.5);
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.custom-swiper-button-prev img,
|
||
.custom-swiper-button-next img {
|
||
width: 30px;
|
||
height: 30px;
|
||
filter: brightness(100%);
|
||
}
|
||
|
||
.custom-swiper-button-prev {
|
||
left: 0;
|
||
}
|
||
|
||
.custom-swiper-button-next {
|
||
right: 0;
|
||
}
|
||
</style>
|