<template>
<div class="pic-module">
<!-- tab以及上传图片按钮 -->
<div class="pic-module__top">
<div class="left-box">
<div class="tab-box" @click="changeTab">
<div
v-for="(item, index) in tabList"
:key="index"
:class="item.className"
>
{{ item.name }}
</div>
</div>
<div v-if="uploadSettingVisiable" class="upload-box" @click="uploadDialogVisiable">
<span class="upload-box__img"></span>
<span class="upload-box__text">上传图片</span>
</div>
</div>
<DateTime />
</div>
<!-- 轮播图需求:鼠标移入左侧或者右侧的固定区域,上下翻页的按钮进行显示 -->
<a-spin tip="Loading..." :spinning="spinning">
<div class="active-content">
<swiper
:modules="modules"
:slides-per-view="1"
:scrollbar="{ draggable: false }"
:loop="true"
:pagination="{clickable: false}"
:navigation="navigation"
class="swiper-content"
@slideChange="onSlideChange"
>
<!-- 这里是轮播的图片,一定要循环多个,不然渲染会失败 -->
<swiper-slide v-for="(item, index) in links" :key="index">
<img :src="item" alt="" class="pic" />
</swiper-slide>
<!-- 这里是对于tab1有工具按钮的特殊配置 -->
<div v-if="activeTab === 'tab1'" class="tool-box" @click="(event) => handleTool(event)">
<img src="@/assets/images/fullScreen.png" alt="" class="pic-dialog" />
<img src="@/assets/images/enlarge.png" alt="" class="pic-enlarge" />
<img src="@/assets/images/shrink.png" alt="" class="pic-shrink" />
</div>
<!-- 这里是左翻页的固定框,类名自定义 -->
<div class="preBox">
<!-- 这里是左翻页,类名是自己定义的,需要在配置中进行赋值 -->
<div class="swiper-button-prev"></div>
</div>
<!-- 这里是右翻页的固定框,类名自定义 -->
<div class="nextBox">
<!-- 这里右左翻页,类名是自己定义的,需要在配置中进行赋值 -->
<div class="swiper-button-next"></div>
</div>
</swiper>
</div>
</a-spin>
</div>
<!-- 这个是tab1工具按钮点击后的弹窗 -->
<Dialog
:showDialog="showDialog"
:imgUrl="imgUrl"
@closeDialog="dialogVisible"
/>
<!-- 这个是上传图片按钮点击后的的弹窗 -->
<UploadDialog
v-if="showUploadDialog"
:showUploadDialog="!!showUploadDialog"
:activeTab="activeTab"
:imgUrl="links"
:qyStoreId="qyStoreId"
@closeDialog="uploadDialogVisiable"
@submitDialog="submitDialog"
/>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs, watch} from 'vue'
// 引入时间组件
import DateTime from '@/components/DateTime.vue'
// 引入提示框
import { message } from 'ant-design-vue'
// 引入图片放大的弹窗
import Dialog from '@/components/Dialog/index.vue'
// 引入设置图片的弹窗
import UploadDialog from '@/components/UploadDialog/index.vue'
// 引入请求
import G from '@/request/G'
import { useStore } from 'vuex'
// 引入swiper组件
import { Swiper, SwiperSlide } from "swiper/vue";
import "swiper/css/pagination"; // 轮播图底面的小圆点
import "swiper/css/navigation"; // 轮播图两边的左右箭头
// 引入swiper核心和所需模块
import { Navigation,Pagination } from "swiper/modules";
export default defineComponent({
name: 'PicModule',
components: {
DateTime,
Dialog,
UploadDialog,
Swiper,
SwiperSlide
},
props: {
storeId: { // 拿到的机构Id
type: String,
default: ''
}
},
setup (props) {
const store = useStore()
const data = reactive({
spinning: true, // 是否处于加载中
tabList: [
{
name: 'tab0',
className: 'common-tab active-tab'
},
{
name: 'tab1',
className: 'common-tab'
}
], // tab的样式
activeTab: 'tab0', // 当前活跃的tab
scaleNumber: 1, // tab1的放大缩小基数
showDialog: false, // 当前的图片是否要放大
imgUrl: '', // 当前图片的地址
qyStoreId: '', // 企业的storeId
showUploadDialog: false,
uploadSettingVisiable: false,
modules: [Pagination, Navigation],
links: [] as string[],
currentPage: 0, // 默认是第一张,这个变量主要用于tab1的工具按钮进行区分
navigation: { // 这里就是自定义分页器的配置
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
}
})
// 初始化图表
const init = (val:string) => {
data.imgUrl = ''
data.links = []
let params = {
_api: 'XXXX',
storeId: val,
drawType: data.activeTab === 'tab0' ? 1 : 2,
_v: '1.0'
} as any
params = G.buildInputs(params)
G.baseAjax({
type: 'POST',
data: G.param(params) + '&_at=' + G.buildAt(params)
}).then((res:any) => {
const { success, model } = res
if (success) {
if (model) {
// 给图片赋值
data.links = model.split(',')
}
} else {
message.error(res.msgInfo)
}
data.spinning = false
})
}
// tab切换
const changeTab = (event: MouseEvent) => {
data.spinning = true
const target = event.target as HTMLElement
const value = target.innerText
data.activeTab = value
data.tabList.forEach((item) => {
item.className = 'common-tab'
if (item.name === value) {
item.className = 'common-tab active-tab'
}
})
const picDom: any = document.getElementsByClassName('pic')
if (picDom && picDom.length) {
for (let i = 0; i < picDom.length; i++) {
picDom[i].style.transform = `scale(1)`
}
}
init(data.qyStoreId)
}
// 点击图表工具中的弹窗全屏、放大、缩小
const handleTool = (event: MouseEvent) => {
const target = event.target as HTMLElement
const value = target.className
const picDom: any = document.getElementsByClassName('pic')[data.currentPage]
if (value === 'pic-dialog') {
data.imgUrl = picDom.getAttribute('src')
// 弹窗全屏
dialogVisible(true)
} else if (value === 'pic-enlarge') {
// 放大
data.scaleNumber += 0.2
picDom.style.transform = `scale(${data.scaleNumber})`
} else if (value === 'pic-shrink') {
// 缩小
data.scaleNumber -= 0.2
if (data.scaleNumber > 0.2) {
picDom.style.transform = `scale(${data.scaleNumber})`
} else {
message.error('不能缩小了!')
}
}
}
// 是否显示tab1的弹窗
const dialogVisible = (val: boolean) => {
data.showDialog = val
}
// 上传图片弹窗
const uploadDialogVisiable = (val: boolean) => {
data.showUploadDialog = val
}
const submitDialog = (val: {cqImgUrl:string[];nyImgUrl:string[]}) => {
if (data.activeTab === 'tab0') {
data.links = val.cqImgUrl
}
if (data.activeTab === 'tab1') {
data.links = val.nyImgUrl
}
uploadDialogVisiable(false)
}
// 监听当前的storeId
watch(
() => props.storeId,
(val: string) => {
if (val) {
data.qyStoreId = val
// 请求当前的图表
init(val)
data.uploadSettingVisiable = parseInt(store.state.userInfo.userRole) === 100
}
},
{
immediate: true,
deep: true
}
)
const onSlideChange = (swiper:any) => {
data.currentPage = swiper.activeIndex
}
return {
...toRefs(data),
changeTab,
handleTool,
dialogVisible,
uploadDialogVisiable,
submitDialog,
onSlideChange
}
}
})
</script>
<style lang="scss" scoped>
.pic-module {
&__top {
display: flex;
justify-content: space-between;
flex-wrap: nowrap;
height: 121px;
}
.tab-box {
display: flex;
flex-wrap: nowrap;
.common-tab {
cursor: pointer;
position: relative;
width: 280px;
height: 96px;
text-align: center;
font-size: 44px;
font-weight: 600;
color: #cbccce;
line-height: 96px;
&::after {
content: "";
position: absolute;
right: -20px;
width: 2px;
height: 96px;
background: linear-gradient(
180deg,
rgba(46, 139, 234, 0) 0%,
#2e8bea 50%,
rgba(46, 139, 234, 0) 100%
);
}
&:last-of-type {
left: 40px;
&:after {
background: none;
}
}
}
.active-tab {
background: url("@/assets/images/tab_active_bg.png") no-repeat;
background-size: 100% 100%;
color: #fff;
}
}
.active-content {
position: relative;
height: 1115px;
// height: 1079px;
margin: 40px 0 44px;
.pic {
object-fit: contain;
width: 100%;
height: 1115px;
transform: scale(1);
}
.tool-box {
display: flex;
flex-direction: column;
position: absolute;
right: 4px;
bottom: 0;
z-index: 200;
.pic-dialog,
.pic-enlarge,
.pic-shrink {
cursor: pointer;
display: inline-block;
margin-bottom: 24px;
}
}
}
.left-box {
display: flex;
align-items: center;
}
.upload-box {
cursor: pointer;
display: flex;
align-items: center;
margin-left: 60px;
&__img {
display: inline-block;
width: 32px;
height: 32px;
background: url("@/assets/images/uploadImg.png") no-repeat;
background-size: 100% 100%;
margin-right: 10px;
}
&__text {
font-size: 32px;
color: #589CFD;
}
}
}
</style>
<style lang="scss">
.swiper-pagination-bullet {
display: inline-block;
width: 16px;
height: 16px;
background: rgba(255,255,255,0.25);
margin-right: 24px!important;
}
.swiper-pagination-bullet-active {
background: #3196FA;
}
.swiper-button-prev {
display: none;
position: relative;
width: 80px;
height: 80px;
background: url("@/assets/images/prev.png") no-repeat;
background-size: 100% 100%;
}
.swiper-button-next {
display: none;
width: 80px;
height: 80px;
background: url("@/assets/images/next.png") no-repeat;
background-size: 100% 100%;
}
.swiper-button-prev:after,.swiper-button-next:after {
display: none;
}
.preBox {
z-index: 100;
position: absolute;
top: 0;
left: 0;
display: inline-block;
width: 120px;
height: 1100px;
&:hover {
.swiper-button-prev {
display: inline-block;
}
}
}
.nextBox {
z-index: 100;
position: absolute;
top: 0;
right: 0;
display: inline-block;
width: 120px;
height: 1100px;
&:hover {
.swiper-button-next {
display: inline-block;
}
}
}
</style>
换版本
本来一开始用的swiper7.4.1,但是分页器一直不出来,元素审查都没有找到对应的代码,所以换了版本。
增加下面的代码
import Swiper, {Navigation, Pagination} from "swiper";
// 新版Swiper默认只导出核心部分,需要如导航、分页等组件的话需要另外导入,并使用Swiper.use()添加
Swiper.use([Navigation, Pagination]);