需求 最近在开发项目时遇到这样一个问题:
这是最初的定版布局,但是后面由于政策越来越多,要是在沿袭之前的这种布局的话就难免不是那么美观了,于是就提出了以轮播的形式来展示:
这样做的好处在于无论后续再新增多少政策产品其美观度都不会受到太大影响
思路 对于实现以上的思路我这里采用的是将后台返回的数据在配合UI给的设计图,将数据首先处理成我想要的格式,然后将其处理成一个二维数组。其原理在于二维数组的最外层就相当于轮播图的item项,即二维数组的长度为多少就代表有几张轮播图,再利用内层循环去渲染每一张轮播图所对应的产品即可
代码 父组件:
<policyComponent :loading="loading" :policyList="policyList" @gotoApply="gotoApply" @gotoPolicyZone="gotoPolicyZone" />
data() {
return {
policyList: [],
}
}
// 获取政策数据
getPolicyData() {
const params = {...}
service.callAPIPOSTNoToken('请求路径', params, res => {
if (res.data.code === 200) {
this.policyList = res.data.data;
this.loading = false;
// 将数据处理成我想要的格式
this.policyList.forEach(v => {
v['bg_img'] = this.$imgUrl + v.data.zc_bg_img[0].refId;
v['bg'] = v.data.zc_bg;
v['icon'] = this.$imgUrl + v.data.lite[0].refId;
})
// 将数据处理成二维数组
if(res.data.data.length > 0) {
const result = res.data.data.reduce((acc, current, index) => {
if (index % 8 === 0) {
acc.push([current]);
} else {
acc[acc.length - 1].push(current);
}
return acc;
}, []);
this.policyList = result;
}
} else {
this.loading = false;
}
})
},
子组件:policyComponent
<template>
<view class="container">
<view class="container-box">
<swiper class="swiper" circular :indicator-dots="policyList.length > 1" :autoplay="false" circular :duration="600"
indicator-active-color="#0161d8" indicator-color="#d8d8d8" easing-function="easeInCubic">
<swiper-item v-for="(item, index) in policyList" :key="index">
<view class="swiper-box">
<view class="swiper-item uni-bg-red" v-for="(swiperItem, swiperIndex) in item" :key="swiperIndex" @click="navigateTo(swiperItem)">
<u--image :fade="true" duration="450" shape="circle" :showLoading="true" :src="swiperItem.icon" width="50px" height="50px"></u--image>
<view class="swiper-item-text text-ellipsis-clamp2">{{swiperItem.data && swiperItem.data.policy_name}}
</view>
</view>
</view>
</swiper-item>
</swiper>
</view>
</view>
</template>
<script>
export default {
props: {
policyList: {
type: Array,
default: () => ([])
},
loading: {
type: Boolean,
default: true
}
},
data() {
return {}
},
mounted() {},
methods: {
// 将数据转为parse格式
getButton(e) {
if (e) {
try {
return JSON.parse(e);
} catch (e) {
return e;
}
}
},
// 前往政策专区二级页面
navigateTo(item) {
let id = item.id;
this.$emit("gotoPolicyZone", item);
},
// 点击 去申请 按钮
gotoApply(subitem, item) {
const data = {
"subitem": subitem,
"item": item
};
this.$emit("gotoApply", data);
},
},
}
</script>
<style>
::v-deep .aply-btns .u-button {
margin-right: 10px important;
}
</style>
<style lang="scss" scoped>
.container {
width: 100%;
padding: 0 28rpx;
}
.container-box {
background-color: #fff;
border-radius: 10rpx;
}
.swiper {
height: 460rpx;
width: 100%;
box-sizing: border-box;
border-radius: 16rpx;
}
.swiper-box {
height: 100%;
width: 100%;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
padding: 20rpx 10rpx;
}
.swiper-item {
width: 25%;
box-sizing: border-box;
padding: 0 8rpx;
padding-bottom: 30rpx;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
}
.swiper-item-text {
width: 100%;
height: 65rpx;
font-size: 24rpx;
padding-top: 10rpx;
}
.text-ellipsis-clamp2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
到这里也就算了完成了