功能:
后台可以配置卡面展示的内容,卡面配置分为三个组件展示,分别是
顶部组件:点击可弹出抽屉,可上传该组件背景图、配置展示的基本信息。
中间组件:点击可弹出抽屉,配置需要展示的钱包类型。
底部组件:点击可弹出抽屉,可上传模块图标、配置模块名称、小程序的跳转路线。
小程序根据后台配置的组件信息,展示相对应的组件和组件内部的模块。
后台代码:
代码核心 component :is="element.componentName"
左侧组件库ComponetnList对应BalanceTemplate、CardTemplate、InfoTemplate三个组件,可触发各自的点击事件,将组件添加到中间展示区域
<!--组件列表-->
<el-aside width="320px" style="background-color: #fff; overflow-x: hidden">
<div class="pv-10 ph-20 ds-fx jc-sb mb-20" style="border-top: 2px #e4e7ed
solid; border-bottom: 2px #e4e7ed solid">
<div class="ds-fx jc-c ai-c fs-14" style="color: #606266">卡面背景颜色</div>
<el-color-picker v-model="bgColor" @change="bgColorChange" />
</div>
<ComponetnList @addComponent="addComponent"></ComponetnList>
</el-aside>
<!--展示区域-->
<el-main>
<el-scrollbar>
<div ref="cardRef" class="w-full h-full">
<div class="ds-fx jc-c ai-c pt-20 pb-20 cardColor">
<div v-if="componentList.length === 0" style="height: calc(100vh -
200px); width:450px">
<el-empty style="height: 100%" description="你还未添加任何模块,">
<span style="color: #909398">请从左侧列表中选择添加</span>
</el-empty>
</div>
<div v-else style="height: 100%; width: 450px" :>
<draggable :list="componentList" ghost-class="ghost"
chosen-class="chosenClass" animation="300" @start="onStart"
@end="onEnd">
// 我这里的draggable拖动后不需要进行别的操作,如果需要别的操作的可在
@start和@end方法里面写逻辑
<template #item="{ element }">
<div class="item">
<component :is="element.componentName":ref="element.ref"@submit="submit"@removeComponent="removeComponent"@removeList="removeList" @addList="addList">
</component>
</div>
</template>
</draggable>
</div>
</div>
</div>
</el-scrollbar>
</el-main>
// 属性
const cardRef = ref();
const componentList: any[] = reactive([]);
// 方法
const addComponent = (val) => { // 页面右侧为组件列表,点击添加到卡面
let index = componentList.findIndex((item) => {
return item.componentName == val.componentName;
});
if (index > -1) {
componentList.splice(index, 1, val);
} else {
componentList.push(val);
}
};
const saveComponentList = () => {
let pictureBase64: any;
let parameter = {
componentList,
componentiInfo,
};
html2canvas(cardRef.value).then((canvas) => { // 截图功能
pictureBase64 = canvas.toDataURL('image/png');
const submitData: any = {
id,
parameter: JSON.stringify(parameter),
pictureBase64,
};
Ecard.updateParameter(submitData).then((res) => { // 保存到后端
if (res) {
ElMessage.success('保存成功');
}
});
});
};
// 从后端那拿组件数组回来(已经保存了组件配置)
const getCardCustom = (id: string) => {
Ecard.detailCardCustom(id).then((res) => {
if (res) {
let parameter = JSON.parse(res.parameter);
if (parameter !== null) {
Object.assign(componentList, parameter.componentList);
}
}
});
};
小程序主要代码:
因小程序没有component:is这个方法,采用了循环的方法来进行处理。
<view v-for="element in componenList" :key="element.componentName" class="pb-40">
<CardTemplate v-if="element.componentName === 'CardTemplate'" :cardTemplateInfo="cardTemplateInfo" :cardInfo="cardInfo"></CardTemplate>
<InfoTemplate v-if="element.componentName === 'InfoTemplate'" :InfoTemplateInfo="InfoTemplateInfo" :cardInfo="cardInfo"></InfoTemplate>
<BalanceTemplate
ref="balanceTemplateRef"
v-if="element.componentName === 'BalanceTemplate'"
:balanceTemplateInfo="balanceTemplateInfo"
:walletId="walletId"
></BalanceTemplate>
</view>
<script setup lang="ts">
// 引入组件
import CardTemplate from '../components/wallets/CardTemplate.vue';
import InfoTemplate from '../components/wallets/InfoTemplate.vue';
import BalanceTemplate from '../components/wallets/BalanceTemplate.vue';
// 获取数据
const detailCardCustom = async () => {
await ecard.detailCardCustom(cardInfo.user.userType).then((res: any) => {
if (res.data.data) {
let obj = JSON.parse(res.data.data);
obj.componentList.forEach((item: any) => {
componenList.push(item);
});
}
});
};
<script>