Vue——formcreate表单设计器自定义组件实现(二)

前面我写过一个自定义电子签名的formcreate表单设计器组件,那时初识formcreate各种使用也颇为生疏,不过总算套出了一个组件不是。此次时隔半年又有机会接触formcreate,重新熟悉和领悟了一番各个方法和使用指南。趁热打铁将此次心得再次分享。

本次要实现的自定义组件是一个表格,表格在前端是个十分常见的组件,然而formcreate里面却没有内置,我翻了issues里面有大佬说可以直接用VxeTable来做,做不做内置都是一样的。于是沿着这个思路自己做了一番实践最终也实现了两个版本,一个是Element Table简易版,一个是VxeTable的高度定制。下面就具体说说实现方法,以及其中遇到的一些问题和解法。

Element Table实现自定义FormCreate表单设计器组件

在这里插入图片描述

自定义表头和列名

只要前端可以手动输入列名的label和value,我们就可以根据这串json,遍历实现一个表格。实现代码的代码如下:

<el-table:data="tableOptions.tableData":border="tableOptions.showBorder":show-summary="tableOptions.showSummary":summary-method="getSummaries"size="mini"style="width: fit-content"><!--多选列--><el-table-columnv-if="tableOptions.showMultiSelect"type="selection"width="50"align="center"/><!--序号列--><el-table-columnv-if="tableOptions.showIndex"type="index"label="序号"width="50"align="center"/><!--数据列--><el-table-columnv-for="column in tableOptions.tableColumns":key="column.value":label="column.label":prop="column.value"width="120"align="center"><template slot-scope="scope"><span v-if="tableOptions.readonly">{{ scope.row[column.value] }}</span><el-inputv-elsev-model="scope.row[column.value]":value="scope.row[column.value]"/></template></el-table-column></el-table><el-buttonv-if="!tableOptions.readonly"type="text"icon="el-icon-plus"@click="addRow">添加一行</el-button>

自定义组件生成规则

组件生产规则在上一篇文章中已经说过了,不熟悉的同学可以去回顾下。Vue——formcreate表单设计器自定义组件实现

这里简略说一下本次开发中新得到的一些体验和实验方法吧。

1、生成规则中如何使用自定义组件?

  • 在上一篇文章中我们将组件引入到组件生产规则js文件中,同时关联了自定义组件,代码如下:
import SignBoard from "../components/esign/SignBoard.vue";export const signboard = {rule() {return {component: SignBoard, //挂载自定义组件};},
}

这种方法相对繁琐一点,本次在git上面查询问题时,偶然看到一句话说,只要是全局引入到自定义组件都可以直接在表单设计器中直接使用,就像你使用iViewElementUI一样方便,经测试确实可行,一起来看代码;

  • 全局引入到自定义组件,直接在生成规则中使用
1、main.js 全局引入表格组件
import FormTable from "@/views/process/components/table/FormTable.vue";
Vue.component("FormTable", FormTable)2、tableRule.js 组件生产规则文件中使用
export const formTable = {rule() {return {//生成组件的名称type: "FormTable",//field formcreate生成的json文件中用了收集组件填充数据的字段名称field: "tableValue",};},
}

2、表单设计器中如何实现自定义组件的自定义属性?

自定义属性也定义在组件生成规则js文件中,写在prop()中。

export const formTable = {//拖拽组件配置项(props)的生成规则props() {return [//生成`checkbox`组件的`options`配置规则FcDesigner.makeOptionsRule("options"),{ type: "switch", field: "showSummary", title: "是否显示表尾合计" },];}
};

有一些公共默认属性,通常是标签宽度,标签位置,表单尺寸等。如果我们需要一些自定义属性需要自己在组件规则文件的props() 中添加一个对象,type可以是输入框,开关,计数器,单选,下拉框等基本控件,可以是TableOptions,Struct高级输入等。
基础控件使用参考:http://www.form-create.com/v2/element-ui/
高级控件使用参考:https://gitee.com/xaboy/form-create-designer/tree/master/src/components
当你不知道你所使用的控件怎么在组件规则里面使用时,可以找官方提供的组件源码来看下,参观里面的配置即可。
官方组件生成规则参考:https://gitee.com/xaboy/form-create-designer/tree/master/src/config/rule

3、Table组件自定义属性

Alt
如上图,Table中增加了设置表头列名,是否显示表格边框,表尾合计(且支持自定义合计列),显示序列号,显示多选列,初始表格行数等属性,其中开关按钮,计数器组件等都比较简单,可以设置默认值,控制属性等,直接参考官方代码就好。我会详细说明下StructButtonTableOption多选下拉框等实现过程。

Struct

Struct是一个点击按钮,弹出一个dialog,可以自由编写输入一串json的一个组件。效果如下:
这样我们自定义属性处理的内容就可以非常灵活了,比如我们希望根据一串json配置自动生成一个自定义表格,这个下一节展开说。或者说我们可以定义表格初始化显示的数据等等;
在这里插入图片描述

{type: 'Struct',field: 'headers',title: '设置上传的请求头部',props: {defaultValue: {}}
}
Button

上面的Struct组件是点击一个按钮弹出一个dialog,有的同学可能说,我不想点击按钮弹出dialog,我想做其他自定义操作可以吗?当然可以啦~只不过官方并没有给出button的使用说明,经过研究和实践,我们需要使用原生el-button同时为button绑定click事件就能进行自定义操作了。
官方源码参考:https://gitee.com/xaboy/form-create-designer/blob/master/src/config/base/field.js

这里我们来实现一个点击按钮给表格新增一行的小功能。实现思路为:

  1. 点击按钮更新表格行数,这里我们需要先获取表格原本的行数,然后给其+1;
  2. 自定义组件中监听表格行数属性的变化,然后重新绘制表格行数;

根据这个思路一起来看下这个代码如何实现:
1、给按钮设置点击事件并更新表格行数

 { type: "hidden", field: "rowNums", value: 1 },{type: "el-button",props: {type: "primary",size: "mini",icon: "el-icon-delete"},inject: true,on: {click({ $f }) {//更新组件规则,否则数据修改不会更新UIlet rowNums = $f.getRule("rowNums").value$f.updateRule("rowNums", {value: rowNums+1,});const rule = $f.rule;if (rule) {rule.addRow = true;$f.updateRule(rule);}}},native: true,children: ["新增一行"]},

这里有一些知识点需要说明下:
1、如何获取表格的行数?
这里我们通过一个隐藏字段来收集表格的行数;
2、如何更新表格的行数?
首先我们需要获取表格行数的属性,并将其更新。注意此处只修改属性值是没用的,我们需要将这个规则进行刷新,否则不会更新Ui。
组件规则的操作可参考:更新指定规则
3、$f是什么?
这里参考下官方文档的解释:获取$f,他应该代表的就是FCDesigner对象,有兴趣的同学可以打印看下他的结构。

2、根据表格行数更新Ui
修改完表格行数后,我们需要在UI组件中监听这个数值的变化并根据这个数值更新UI。

props: {formCreateInject: {type: Object,required: true}
},watch: {//formCreateInject为组件生成时会给自定义组件注入的参数"formCreateInject.rule.props": {handler() {//当表单设计器的自定义设置规则修改时,同步更新FormCreateDesiger中的自定义组件this.update();},deep: true},},update(){let rowNums = this.formCreateInject.rule.props?.rowNums ?? 1;for (let i = 0; i < rowNums - this.tableOptions.tableData.length; i++) {this.tableOptions.tableData.push({});}
}

实现过程比较简单,其中有一点解释下,我们注意下这个formCreateInject这个对象为表单设计器生成自定义组件时自动注入的参数,这个属性需在UI组件的自定义属性中定义,否则没法实现组件数据的回传等等;
官方说明:预定义 props

TableOption

TableOption,根据名字就可以知道它是一个表格相关组件,如下图:
在这里插入图片描述

点击添加按钮可以新增一行,在Table组件中就是用这个组件来实现自定义列名和表头的。
官网源码参考:https://gitee.com/xaboy/form-create-designer/blob/master/src/utils/index.js

{type: "TableOptions",field: "columns",title: "设置表头和列名",props: {defaultValue: []},
},

输入完成后我们将得到如下json:

[{ label: 'seq', value: ‘’},
], //数据列

然后根据这个数据实现Ui组件中的列的绘制。

组件之间的联动

这一节将介绍如何实现自定义行尾合计列的实现方式。

  1. 首先需添加一个下拉框来实现自定义列的选择;
  2. 其次需要将已选的列回传给Table组件,这里就用到了组件属性之间的联动,可参考官方文档:组件联动概括来说就是,我们可以在某个组件规则的前后,甚至子级增加对另外一个组件规则的控制;在本例中,我们需要用TableOption控制表尾合计列多选拉下框的显示;所以合起来的代码应该为
{type: "TableOptions",field: "columns",title: "设置表头和列名",props: {defaultValue: []},//组件联动:设置完列名以后,更新显示合计列的多选下拉列表control: [{handle(val, fApi) {sumColums = val;sumColumsVal = [];if (sumColums?.length > 0) {sumColums.forEach(item => {sumColumsVal.push(item.value);});}//更新组件规则,否则数据修改不会更新UIfApi.updateRule("sumColumns", {value: sumColumsVal,options: sumColums});return val?.length > 0;},append: "showSummary", //在某个组件后插入rule: [{type: "select",field: "sumColumns",title: "自定义表尾合计列",value: sumColumsVal,//选择的数据,类型为【】options: sumColums,//选项数据props: {multiple: true}}]}]
},
{ type: "switch", field: "showSummary", title: "是否显示表尾合计" },

Ui组件中只计算某些列的合计实现如下:

//自定义合计方法,可以选择只计算某些列的合计,不需要计算的返回空
getSummaries(param) {//需要计算合计的列let sumColumns = this.formCreateInject.rule.props?.sumColumns;const { columns, data } = param;const sums = [];columns.forEach((column, index) => {if (index === 0) {sums[index] = "合计";return;}let values = [];if (sumColumns?.length > 0) {//只计算选中列的合计values = data.map(item => {return sumColumns.indexOf(column.property) != -1? Number(item[column.property]): "-";});} else {//默认计算所有列的合计values = data.map(item => Number(item[column.property]));}if (!values.every(value => isNaN(value))) {sums[index] = values.reduce((prev, curr) => {const value = Number(curr);if (!isNaN(value)) {return prev + curr;} else {return prev;}}, 0);} else {sums[index] = "";}});return sums;
}

VxeTable实现自定义FormCreate表单设计器组件

前面一节自己实现表格只能是比较简单的样式和效果,如果我想要更复杂的表格呢?如果只是增加更多的自定义属性来控制表格的实现,那么必定增加运营配置人员的负担。此时VxeTable就为我们提供一个强大的功能,只要写好高级配置的json,代码中就可以根据这个json直接生成效果更为丰富的表格。

VxeTable官方文档参考:https://vxetable.cn/#/table/start/install
本节我们用到的是VxeTable高级表格的能力,大概预览下高级表格的实现代码:

<template><div><vxe-grid v-bind="gridOptions"/></div>
</template><script lang="ts" setup>
import { reactive } from 'vue'
import { VxeGridProps } from 'vxe-table'interface RowVO {id: numbername: stringnickname: stringrole: stringsex: stringage: numberaddress: string
}const gridOptions = reactive<VxeGridProps<RowVO>>({border: true,height: 300,align: null,columnConfig: {resizable: true},columns: [{ type: 'seq', width: 50 },{ field: 'name', title: 'name' },{ field: 'sex', title: 'sex' },{ field: 'address', title: 'Address' }],toolbarConfig: {slots: {buttons: 'toolbar_buttons'}},data: [{ id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: 'Man', age: 28, address: 'Shenzhen' },{ id: 10002, name: 'Test2', nickname: 'T2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },{ id: 10003, name: 'Test3', nickname: 'T3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' }]
})
</script>

由上述代码可见,Vxetable的代码非常简洁,只需要一个option配置项就可以来,那么沿着这个思路,我们就可以把option放在自定义属性中用Struct来进行编辑,就能快速实现不同效果的表格,这个方法对配置人员对要求较高T=T

实现过程不难,代码就不放了。有兴趣的同学可以自行实践。

本篇文章介绍的内容较多,相信经过这篇介绍,以后再有自定义组件的需求时你一定都能游刃有余了。也有些盲点可能没扫到,后续有研究会继续更新的。有好的思路也欢迎评论区留言探讨~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/27692.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

THS4301 振荡问题排查及解决过程

项目背景简介: 本项目是基于一款微弱信号处理前级模拟电路设计方案。 问题描述: 在生产标定中,发现以前的程序在小量程标定后,切换到差分和单端后,两者的直流偏置不一样,且切换到差分输入时,能发现有振荡现象(有设备单端输入也有振荡); 排查分析过程: 1)首先可以…

tomcat上部署jpress

一.确保有jdk&#xff0c;tomcat和mysql环境 二.新建jpress数据库&#xff0c;新建jpress用户并赋予所有权限 三.将jpress的war上传到tomcat/apache-tomcat-8.5.70/webapps&#xff0c;具体根据你的实际tomcat安装路径为准&#xff0c;上传完成后他会自己解包 四.到浏览器完…

JAVA实现图书管理系统(思路,和完整代码)

因为文件过多每个文件之间的关系如下&#xff08;每个文件中都只有一个类&#xff09;&#xff1a; 因为JAVA属于面向对象编程的语言&#xff0c;所以我们想要实现图书管理系统就得分以下几步&#xff1a; 找出其中的所有的对象实现所有的对象完成对象之间的交互 在图书管理系…

【产品经理】高阶产品如何提出有效解决方案?(1方法论+2案例+1清单)

每一件事情总有它的解决方案&#xff0c;在工作中亦是如此&#xff0c;而有效的解决方案&#xff0c;一定是具有系统性的。 有效的解决方案&#xff0c;一定是系统性的解决方案。 什么是系统性解决方案&#xff1f; 从系统结构&#xff08;或连接关系&#xff09;入手&#x…

【C语言】初识C语言+进阶篇导读

✨个人主页&#xff1a; Anmia.&#x1f389;所属专栏&#xff1a; C Language &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 本篇目的是面向编程新手&#xff0c;没接触过编程的人。以及C进阶的导读。 内容是C语言重要知识点的简单解释&#xff0c;不做详解。给…

73. 矩阵置零

题目链接&#xff1a;力扣 解题思路&#xff1a; 方法一&#xff1a;比较容易想到的方向&#xff0c;使用两个数组row和col保存有0的行或者列&#xff0c;然后将有0的那一行或那一列的所有元素都设置为0 AC代码 class Solution {public void setZeroes(int[][] matrix) {in…

小尺寸、高效率的88W8997-A0-CBQ2E005-T无线互连芯片,NV24C64DWVLT3G 64Kb EEPROM存储器

88W8997-A0-CBQ2E005-T 是业界尺寸最小、能效最高的MU-MIMO无线互连组合芯片&#xff0c;面向企业级和消费级市场。88W8997是业界首款全面支持Bluetooth 4.2以及未来Bluetooth 5.0全套功能的28nm 2 x 2 802.11ac Wave-2组合芯片。该器件实现了高达867Mbps的峰值数据传送速率&am…

9-数据结构-栈(C语言版)

数据结构-栈&#xff08;C语言版&#xff09; 目录 数据结构-栈&#xff08;C语言版&#xff09; 1.栈的基础知识 1.入栈&#xff0c;出栈的排列组合 情景二&#xff1a;Catalan函数&#xff08;计算不同出栈的总数&#xff09; 2.栈的基本操作 1.顺序存储 (1)顺序栈-定义…

自学python,学了又忘,感觉学不好是为啥呢

一、前言 最近发现&#xff0c;身边很多的小伙伴学Python都会遇到一个问题&#xff0c;就是资料也看了很多&#xff0c;也花了很多时间去学习但还是很迷茫&#xff0c;时间长了又发现之前学的知识点很多都忘了&#xff0c;都萌生出了想半路放弃的想法。 其实造成这样情况根本的…

使用toad库进行机器学习评分卡全流程

1 加载数据 导入模块 import pandas as pd from sklearn.metrics import roc_auc_score,roc_curve,auc from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression import numpy as np import math import xgboost as xgb …

搭建 elasticsearch8.8.2 伪集群 windows

下载windows 版本 elasticsearch8.8.2 以下链接为es 历史版本下载地址&#xff1a; Past Releases of Elastic Stack Software | Elastic windows 单节点建立方案&#xff1a; 下载安装包 elasticsearch-8.8.2-windows-x86_64.zip https://artifacts.elastic.co/download…

element-plus:el-date-picker日期只选择年月不要日

<el-date-picker v-model"value" type"month" format"YYYY-MM" value-format"YYYY-MM" />使用format属性将时间显示格式修改为YYYY–MM 年月格式 使用value-format将绑定值的格式修改为YYYY–MM年月格式

一台电脑给另外一台电脑共享网络

这里写自定义目录标题 有网的电脑上操作一根网线连接两台电脑没网的电脑上 有网的电脑上操作 右键->属性->共享 如同选择以太网&#xff0c;勾选。确认。 一根网线连接两台电脑 没网的电脑上 没网的电脑为mips&麒麟V10 新增个网络配置ww&#xff0c;设置如下。 …

携手区块链技术,踏上可信“双碳”之路 | 研讨会回顾

自中央明确提出碳达峰碳中和的“双碳”目标以来&#xff0c;区块链技术凭借能为碳排放、碳足迹打上可信标签的天赋异禀&#xff0c;引起了政策部门、学术界及产业实践代表们的高度重视。 7月11日&#xff0c;在第33个全国节能宣传周之际、全国低碳日前夕&#xff0c;微众区块链…

R语言安装包Seurat

环境Ubuntu22&#xff0c;R4.1 also installing the dependencies ‘curl’, ‘openssl’, ‘httr’, ‘plotly’ R包安装的时候报了这个错误ERROR: dependencies httr, plotly are not available for package Seurat 解决方法&#xff0c;退出R&#xff0c;在terminal中键入…

C# OpenCvSharp 读取rtsp流

效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Extensions; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using Syste…

k8s --pod详解

目录 一、Pod基础概念 1、pod简介 2、在Kubrenetes集群中Pod有如下两种使用方式 3、pause容器使得Pod中的所有容器可以共享两种资源&#xff1a;网络和存储。 &#xff08;1&#xff09;网络 &#xff08;2&#xff09;存储 4、kubernetes中的pause容器主要为每个容器提供…

24届近5年南京理工大学自动化考研院校分析

今天学长给大家带来的是南京理工大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、南京理工大学 ​ 学校简介 南京理工大学是隶属于工业和信息化部的全国重点大学&#xff0c;学校由创建于1953年的新中国军工科技最高学府——中国人民解放军军事工程学院&#xf…

最小二乘问题和非线性优化

最小二乘问题和非线性优化 0.引言1.最小二乘问题2.迭代下降法3.最速下降法4.牛顿法5.阻尼法6.高斯牛顿(GN)法7.莱文贝格马夸特(LM)法8.鲁棒核函数 0.引言 转载自此处&#xff0c;修正了一点小错误。 1.最小二乘问题 在求解 SLAM 中的最优状态估计问题时&#xff0c;我们一般…

linux gcc __attribute__

__attribute__ 1. 函数属性1.1 __attribute__((noreturn))1.2 __attribute__((format))1.3 __attribute__((const)) 2. 变量属性2.1. __attribute__((aligned))2.2. __attribute__((packed)) 3. 类型属性 __attribute__ 是 GCC 编译器提供的一种特殊语法&#xff0c;它可以用于…