Vform3 功能扩展,组件及子组件复制导入

Vform3 是一款通过配置json数据,动态生成表单页面的可视化配置页面,方便我们快速的编写表单。

存在的问题:

  1.  我们在项目的实际开发中发现很多组件,区域内容,组件加载的逻辑是相识和相同的,例如不同的页面之间都存在国家地区组件,前一个表单的数据是又后一个表单生成的等等。
  2.  作为一名程序员,配置化的方式,有时增加了我们的负担,例如我们需要通过某个按钮去控制列表的展示,我们在配置页面编写点击事件时,无法方便查看到列表对应的ID,此时我们需要点击列表组件才能知道对应的ID,如果能够看到生成后的vue代码,我们就能够方便的找到ID。

无法满足:

        Vform3官方目前提供的只有导入,导出整个表单的功能。

        Vform3官方目前生成的SFC也是这个表单的,无法查看到局部代码块。

      我们只能这么做:

  1. 方式一:A表单配置了的组件想要导入到B表单,需要先查看整个A表单的JSON,从中获取我们想要的组件JSON数据,再和B进行合并,重新导入。
  2. 方式二:A表单和B表单一个个对比复制

我们希望实现类似这样的功能:

  1.  选择某个组件,我们就能获取对应的配置数据
  2. 表格、页面、卡片等容器组件能整体复制,并导入到另外一个表单中
  3. 能够查看到每个组件或容器组件SFC的生成,方便我们编写代码

 

实现效果图

 

问题一功能实现:

通过组件层次结构树去实现我们问题一的功能。增加三个按钮去实现导入,预览和复制功能。

具体代码:

修改文件src\components\form-designer\toolbar-panel\index.vue

<el-tree
        ref="nodeTree"
        :data="nodeTreeData"
        node-key="id"
        default-expand-all
        highlight-current
        class="node-tree"
        icon-class="el-icon-arrow-right"
        @node-click="onNodeTreeClick"
      >
        <template #default="{ node, data }">
          <span class="custom-tree-node">
            <span>{{ node.label }}</span>
            <span>
              <el-button
                type="primary"
                size="small"
                v-if="containerShow(data)"
                @click="importClick(node,data)"
              >导入</el-button>
              <el-button type="primary" size="small" @click="exportClick(node,data)">预览</el-button>
              <el-button type="primary" size="small" @click="onCopy(node,data,$event)">复制</el-button>
            </span>
          </span>
        </template>
</el-tree>

     //源码中的方法 注解掉组件不能选择问题
     onNodeTreeClick(nodeData, node, nodeEl) {
      if (nodeData.selectable !== undefined && !nodeData.selectable) {
        // this.$message.info(
        //   this.i18nt("designer.hint.currentNodeCannotBeSelected")
        // );
      } else {
        const selectedId = nodeData.id;
        const foundW = this.findWidgetById(selectedId);
        if (!!foundW) {
          this.designer.setSelected(foundW);
        }
      }
    },
    // 导出方法
    exportClick(nodeData, node) {
      const foundW = this.findWidgetById(node.id);
      this.jsonContent1= JSON.stringify(deepClone(foundW), null, "  ")
      this.showExportJsonDialogFlag = true

    },
    //导入方法
    importClick(nodeData, node) {
      ElMessageBox.prompt("请输入数据", "组件导入", {
        confirmButtonText: "确认",
        cancelButtonText: "取消"
      })
        .then(({ value }) => {
          //this.designer.widgetList 所有组件的json都配置在这里
          //过滤获取到当前点击节点widget数据
          let foundW = {};
          traverseAllWidgets(this.designer.widgetList, w => {
            if (w.id === node.id) {
              foundW = w;
            }
          });
          try {
            let json = JSON.parse(value);
            //重新设置名称,id,key
            const nameNew = json.type + this.ramdon5();
            json.id = nameNew;
            if (json.key) {
              json.key = this.ramdon5();
            }
            if (json.options) {
              json.options.name = nameNew;
            }
            if(json.type==='table-cell'){
              //表格单元格导入
              foundW.cols.push(json);
            }else  if(foundW.type==='table'){
              //表格行列导入
              foundW.rows.push(json);
            }
            else{
              //容器导入
              foundW.widgetList.push(json);
            } 
           
          } catch (e) {
            ElMessage({
              type: "fail",
              message: `请输入正确的JSON`
            });
            return;
          }
          ElMessage({
            type: "success",
            message: `导出成功`
          });
        })
        .catch(e => {
          ElMessage({
            type: "info",
            message: e
          });
        });
    },
    //控制是否显示可导入
    containerShow(node) {
      const foundW = this.findWidgetById(node.id);
      if (foundW) {
        if (foundW.category) {
          return true
        }
        if(foundW.cols){
          return true
        }
      }
      return false;
    },
    ramdon5() {
      return Math.floor(
        (Math.random() + Math.floor(Math.random() * 9 + 1)) * 10 ** (5 - 1)
      );
    },
    //复制JSON数据到剪切板
    onCopy(nodeData, node,e) {
      const foundW = this.findWidgetById(node.id);
      //vform 自带的工具方法
      copyToClipboard(
        JSON.stringify(foundW),
        e,
        this.$message,
        this.i18nt("designer.hint.copyJsonSuccess"),
        this.i18nt("designer.hint.copyJsonFail")
      );
    }

修改文件\src\utils\util.js

//过滤获取widget的方法
export function traverseAllWidgets(widgetList, handler) {
  if (!widgetList) {
    return
  }
  widgetList.map(w => {
    handler(w)

    if (w.type === 'grid') {
      w.cols.map(col => {
        handler(col)
        traverseAllWidgets(col.widgetList, handler)
      })
    } else if (w.type === 'table') {
      w.rows.map(row => {
        handler(row)//额外添加的 为了实现在列中导入组件
        row.cols.map(cell => {
          handler(cell)
          traverseAllWidgets(cell.widgetList, handler)
        })
      })
    } else if (w.type === 'tab') {
      w.tabs.map(tab => {
        traverseAllWidgets(tab.widgetList, handler)
        handler(tab)//额外添加的 为了实现tab中导入组件
      })
    } else if (w.type === 'sub-form' || w.type === 'grid-sub-form') {
      traverseAllWidgets(w.widgetList, handler)
    } else if (w.category === 'container') {  //自定义容器
      traverseAllWidgets(w.widgetList, handler)
    }
  })
}

 问题二功能实现:

        待补充

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值