Vue3项目记录:draggable实现拖动功能、component:is实现动态组件功能、html2canvas实现截图功能。小程序实现展示后台卡面配置功能。

功能:

后台可以配置卡面展示的内容,卡面配置分为三个组件展示,分别是

顶部组件:点击可弹出抽屉,可上传该组件背景图、配置展示的基本信息。

中间组件:点击可弹出抽屉,配置需要展示的钱包类型。

底部组件:点击可弹出抽屉,可上传模块图标、配置模块名称、小程序的跳转路线。

小程序根据后台配置的组件信息,展示相对应的组件和组件内部的模块。

后台代码:

代码核心 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>

                 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值