一、 xml文件
根据template is 属性判断是哪一个组件
根据elementType来映射不同组件
<import src="./components/goods/"/>
<import src="./components/icon/"/>
<import src="./components/img/"/>
<import src="./components/label/"/>
<import src="./components/placeholder/"/>
<import src="./components/tab/"/>
<import src="./components/title/"/>
<import src="./components/welfare/"/>
<view class="container" style="background: {{bgColor}}">
<header title="{{title}}" fixed/>
<block wx:for="{{components}}" wx:for-index="idx" wx:for-item="item" wx:key="componentId">
<template is="{{ componentMap[] }}" data="{{...item, labelGoods, subLabels, customBar, bgColor}}"/>
</block>
</view>
二、 js文件
import { getHomeData } from '../../../service/tabbar/'
const app = getApp()
Page({
data: {
customBar: app.globalData.customBar,
title: '',
bgColor: '',
components: [],
componentMap: {
1: 'tab',
2: 'icon',
3: 'img',
4: 'welfare',
5: 'label',
6: 'title',
7: 'placeholder',
8: 'goods',
},
activeTab: 0,// tab 组件专属
activeLabel: 0,// label组件专属
activeSubLabel: 0,// label组件专属
subLabels: [],// 子标签
labelGoods: [1, 2, 1, 2, 3, 4],// label 的商品列表
},
// 获取首页数据
async fetchHomeData(){
let res = await getHomeData()
if(!res)return false;
let { title, bgColor, components } = res;
console.log('components', components)
components.forEach(v=>{
if(v.elementType === 5){
if(v.list.length){
this.setData({subLabels: v.list[0]['subTags'] || []})
}
// 调接口获取商品列表
}
})
this.setData({
title,
bgColor,
components,
})
},
onTabClick(e) {
const index = e.detail.index
if(index !== this.data.activeTab){
const tabs = e.target.dataset.tabs || [];
this.setData({
activeTab: index
})
}
},
onIconClick(e){
let info = e.currentTarget.dataset.info || {};
console.log(info)
let { linkType, linkUrl } = info
if(linkType === 4){
wx.navigateTo({
url: `/pages/webview/index?url=${linkUrl}`
})
}
},
onImgClick(e){
let info = e.currentTarget.dataset.info || {};
console.log(info)
let { linkType, linkUrl } = info
if(linkType === 4){
wx.navigateTo({
url: `/pages/webview/index?url=${linkUrl}`
})
}
},
onLabelClick(e){
console.log('e', e)
},
onSubLabelClick(e){
console.log('e', e)
},
jump(e){
wx.switchTab({
url: '/pages/tabBar/category/index'
})
},
onShow(){
this.fetchHomeData();
}
})
三、 json文件
{
"navigationStyle": "custom",
"usingComponents": {
"header": "/components/Header/index",
"goods-item": "/components/GoodsItem/index",
"mp-tabs": "@miniprogram-component-plus/tabs"
},
"onReachBottomDistance": 50
}
四、 css文件
.container{
position: relative;
min-height: 100vh;
}
.tabs-content{
height: 0rpx;
}
/* tab组件 */
.tab{
position: relative;
height: 98rpx;
background: #000;
}
.tab_bg--img{
position: absolute;
top: 0rpx;
left: 0rpx;
width: 750rpx;
height: 284rpx;
}
.tab-class{
height: 80rpx;
margin: 0 30rpx;
padding-top: 20rpx;
font-size: 32rpx;
color: #fff;
}
.tab-active{
position: relative;
}
.tab-active::before{
position: absolute;
content: '';
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 46rpx;
height: 4rpx;
background: #ffffff;
border-radius: 2rpx;
}
.weui-tabs-bar__wrp{
background: transparent !important;
}
.tab-container{
display: flex;
justify-content: space-between;
width: 100%;
height: 98rpx;
overflow: hidden;
}
.tab-scroll{
width: 670rpx;
}
.tab-more{
height: 98rpx;
width: 79rpx;
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
box-shadow: -7rpx 0 20rpx 3rpx rgba(217,52,90,0.5);
}
.tab-more image{
width: 32rpx;
height: 32rpx;
}
/* placeholder组件 */
.placeholder{
position: relative;
width: 100%;
height: 20rpx;
}
/* icon组件 */
.icon{
position: relative;
display: flex;
flex-wrap: wrap;
width: 714rpx;
margin: 0 auto;
background-color: #fff;
border-radius: 30rpx;
padding-top: 20rpx;
}
.icon-item{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 136rpx;
margin-bottom: 30rpx;
margin-right: 9rpx;
}
.icon-item:nth-child(5n+5){
margin-right: 0rpx;
}
.icon-img{
width: 96rpx;
height: 80rpx;
}
.icon-text{
font-size: 24rpx;
font-weight: 400;
color: #333333;
}
/* img组件 */
.banner{
position: relative;
width: 714rpx;
height: 301rpx;
margin: 0 auto;
border-radius: 30rpx;
transform: translateY(0);
overflow: hidden;
}
.banner-img{
width: 714rpx;
height: 301rpx;
}
/* title组件 */
.title{
width: 750rpx;
height: 76rpx;
margin: 0 auto;
overflow: hidden;
display: flex;
justify-content: space-between;
}
.title-bg{
width: 750rpx;
height: 76rpx;
}
.title-left{
}
.title-right{
}
/* 特价福利组件 */
.welfare{
width: 714rpx;
height: 225rpx;
padding: 0 20rpx;
background-color: #ffffff;
margin: 0 auto;
border-bottom-left-radius: 30rpx;
border-bottom-right-radius: 30rpx;
overflow: hidden;
}
.welfare-scroll{
width: 100%;
height: 100%;
white-space: nowrap;
}
.welfare-goods-item{
display: inline-block;
width: 180rpx;
height: 224rpx;
margin-right: 12rpx;
}
.welfare-goods-img{
position: relative;
text-align: center;
}
.welfare-goods-img image{
width: 148rpx;
height: 148rpx;
}
.welfare-goods-tag{
position: absolute;
bottom: 0rpx;
left: 50%;
display: flex;
justify-content: center;
align-items: center;
height: 30rpx;
max-width: 180rpx;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
padding: 0 7rpx;
background: #eca482;
border-radius: 5rpx;
transform: translateX(-50%);
font-size: 22rpx;
font-weight: 400;
color: #ffffff;
}
.welfare-goods-price{
text-align: center;
}
.welfare-goods-price text:first-child{
font-size: 24rpx;
color: #e85148;
}
.welfare-goods-price text:last-child{
font-size: 28rpx;
font-weight: 500;
color: #e85148;
}
/* 商品组件 */
.goods{
}
/* 标签组件 */
.label{
position: sticky;
width: 100%;
height: 129rpx;
z-index: 10;
}
.label-goods__list{
width: 100%;
border-top-left-radius: 30rpx;
border-top-right-radius: 30rpx;
overflow: hidden;
background-color: #ffffff;
min-height: calc(100vh - 260rpx);
padding-top: 24rpx;
}
.label-class{
padding: 0 96rpx;
height: 60rpx;
border-bottom-width: 6rpx !important;
padding-top: 10rpx;
}
.label-class text{
font-size: 28rpx;
color: #333;
}
.label-tabs .weui-tabs-bar__item{
position: relative;
}
.label-tabs .weui-tabs-bar__item:not(:last-child)::after{
position: absolute;
content: '';
top: 24rpx;
right: 0;
width: 1rpx;
height: 26rpx;
background-color: #d5d5d5;
}
.label-active{
position: relative;
}
.label-active::before{
position: absolute;
content: '';
bottom: 1rpx;
left: 50%;
width: 63rpx;
height: 8rpx;
background: linear-gradient(102deg,#fb4b3d, #fd8044);
box-shadow: 0rpx 1rpx 7rpx 4rpx rgba(246,66,52,0.33);
border-radius: 4rpx;
transform: translateX(-50%);
z-index: -1;
}
.label-sub__tabs{
}
.sub-label-class{
display: flex !important;
align-items: center;
justify-content: center;
height: 40rpx;
background-color: #fff;
margin-left: 18rpx;
margin: 14rpx 0 14rpx 18rpx;
border: 2rpx solid #fff !important;
border-radius: 10rpx;
padding: 0 23rpx;
font-size: 24rpx;
font-weight: 400;
box-sizing: border-box;
}
.label-sub__tabs .weui-tabs-bar__item:last-child .sub-label-class{
margin-right: 18rpx;
}
.sub-label-active{
background-color: #fcefee;
border: 2rpx solid #e85148 !important;
color: #E85148;
}