前面我寫過一個自定義電子簽名的formcreate表單設計器組件,那時初識formcreate各種使用也頗為生疏,不過總算套出了一個組件不是。此次時隔半年又有機會接觸formcreate,重新熟悉和領悟了一番各個方法和使用指南。趁熱打鐵將此次心得再次分享。
本次要實現(xiàn)的自定義組件是一個表格,表格在前端是個十分常見的組件,然而formcreate里面卻沒有內(nèi)置,我翻了issues里面有大佬說可以直接用VxeTable來做,做不做內(nèi)置都是一樣的。于是沿著這個思路自己做了一番實踐最終也實現(xiàn)了兩個版本,一個是Element Table簡易版,一個是VxeTable的高度定制。下面就具體說說實現(xiàn)方法,以及其中遇到的一些問題和解法。
Element Table實現(xiàn)自定義FormCreate表單設計器組件
自定義表頭和列名
只要前端可以手動輸入列名的label和value,我們就可以根據(jù)這串json,遍歷實現(xiàn)一個表格。實現(xiàn)代碼的代碼如下:
<el-table
:data="tableOptions.tableData"
:border="tableOptions.showBorder"
:show-summary="tableOptions.showSummary"
:summary-method="getSummaries"
size="mini"
style="width: fit-content"
>
<!--多選列-->
<el-table-column
v-if="tableOptions.showMultiSelect"
type="selection"
width="50"
align="center"
/>
<!--序號列-->
<el-table-column
v-if="tableOptions.showIndex"
type="index"
label="序號"
width="50"
align="center"
/>
<!--數(shù)據(jù)列-->
<el-table-column
v-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-input
v-else
v-model="scope.row[column.value]"
:value="scope.row[column.value]"
/>
</template>
</el-table-column>
</el-table>
<el-button
v-if="!tableOptions.readonly"
type="text"
icon="el-icon-plus"
@click="addRow"
>
添加一行
</el-button>
自定義組件生成規(guī)則
組件生產(chǎn)規(guī)則在上一篇文章中已經(jīng)說過了,不熟悉的同學可以去回顧下。Vue——formcreate表單設計器自定義組件實現(xiàn)
這里簡略說一下本次開發(fā)中新得到的一些體驗和實驗方法吧。
1、生成規(guī)則中如何使用自定義組件?
- 在上一篇文章中我們將組件引入到組件生產(chǎn)規(guī)則js文件中,同時關(guān)聯(lián)了自定義組件,代碼如下:
import SignBoard from "../components/esign/SignBoard.vue";
export const signboard = {
rule() {
return {
component: SignBoard, //掛載自定義組件
};
},
}
這種方法相對繁瑣一點,本次在git上面查詢問題時,偶然看到一句話說,只要是全局引入到自定義組件都可以直接在表單設計器中直接使用
,就像你使用iView
,ElementUI
一樣方便,經(jīng)測試確實可行,一起來看代碼;
- 全局引入到自定義組件,直接在生成規(guī)則中使用
1、main.js 全局引入表格組件
import FormTable from "@/views/process/components/table/FormTable.vue";
Vue.component("FormTable", FormTable)
2、tableRule.js 組件生產(chǎn)規(guī)則文件中使用
export const formTable = {
rule() {
return {
//生成組件的名稱
type: "FormTable",
//field formcreate生成的json文件中用了收集組件填充數(shù)據(jù)的字段名稱
field: "tableValue",
};
},
}
2、表單設計器中如何實現(xiàn)自定義組件的自定義屬性?
自定義屬性也定義在組件生成規(guī)則js文件中,寫在prop()
中。
export const formTable = {
//拖拽組件配置項(props)的生成規(guī)則
props() {
return [
//生成`checkbox`組件的`options`配置規(guī)則
FcDesigner.makeOptionsRule("options"),
{ type: "switch", field: "showSummary", title: "是否顯示表尾合計" },
];
}
};
有一些公共默認屬性,通常是標簽寬度,標簽位置,表單尺寸
等。如果我們需要一些自定義屬性需要自己在組件規(guī)則文件的props() 中添加一個對象,type可以是輸入框,開關(guān),計數(shù)器,單選,下拉框
等基本控件,可以是TableOptions,Struct
高級輸入等。
基礎控件使用參考:http://www.form-create.com/v2/element-ui/
高級控件使用參考:https://gitee.com/xaboy/form-create-designer/tree/master/src/components
當你不知道你所使用的控件怎么在組件規(guī)則里面使用時,可以找官方提供的組件源碼來看下,參觀里面的配置即可。
官方組件生成規(guī)則參考:https://gitee.com/xaboy/form-create-designer/tree/master/src/config/rule
3、Table組件自定義屬性
如上圖,Table中增加了設置表頭列名,是否顯示表格邊框,表尾合計(且支持自定義合計列),顯示序列號,顯示多選列,初始表格行數(shù)等屬性,其中開關(guān)按鈕,計數(shù)器組件等都比較簡單,可以設置默認值,控制屬性等,直接參考官方代碼就好。我會詳細說明下Struct
,Button
,TableOption
,多選下拉框
等實現(xiàn)過程。
Struct
Struct是一個點擊按鈕,彈出一個dialog,可以自由編寫輸入一串json的一個組件。效果如下:
這樣我們自定義屬性處理的內(nèi)容就可以非常靈活了,比如我們希望根據(jù)一串json配置自動生成一個自定義表格,這個下一節(jié)展開說?;蛘哒f我們可以定義表格初始化顯示的數(shù)據(jù)等等;
{
type: 'Struct',
field: 'headers',
title: '設置上傳的請求頭部',
props: {
defaultValue: {}
}
}
Button
上面的Struct組件是點擊一個按鈕彈出一個dialog,有的同學可能說,我不想點擊按鈕彈出dialog,我想做其他自定義操作可以嗎?當然可以啦~只不過官方并沒有給出button的使用說明,經(jīng)過研究和實踐,我們需要使用原生el-button同時為button綁定click事件
就能進行自定義操作了。
官方源碼參考:https://gitee.com/xaboy/form-create-designer/blob/master/src/config/base/field.js
這里我們來實現(xiàn)一個點擊按鈕給表格新增一行的小功能。實現(xiàn)思路為:
點擊按鈕更新表格行數(shù),這里我們需要先獲取表格原本的行數(shù),然后給其+1;
自定義組件中監(jiān)聽表格行數(shù)屬性的變化,然后重新繪制表格行數(shù);
根據(jù)這個思路一起來看下這個代碼如何實現(xiàn):
1、給按鈕設置點擊事件并更新表格行數(shù)
{ type: "hidden", field: "rowNums", value: 1 },
{
type: "el-button",
props: {
type: "primary",
size: "mini",
icon: "el-icon-delete"
},
inject: true,
on: {
click({ $f }) {
//更新組件規(guī)則,否則數(shù)據(jù)修改不會更新UI
let 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、如何獲取表格的行數(shù)?
這里我們通過一個隱藏字段來收集表格的行數(shù);
2、如何更新表格的行數(shù)?
首先我們需要獲取表格行數(shù)的屬性,并將其更新。注意此處只修改屬性值是沒用的,我們需要將這個規(guī)則進行刷新,否則不會更新Ui。
組件規(guī)則的操作可參考:更新指定規(guī)則
3、$f
是什么?
這里參考下官方文檔的解釋:獲取$f,他應該代表的就是FCDesigner對象,有興趣的同學可以打印看下他的結(jié)構(gòu)。
2、根據(jù)表格行數(shù)更新Ui
修改完表格行數(shù)后,我們需要在UI組件中監(jiān)聽這個數(shù)值的變化并根據(jù)這個數(shù)值更新UI。
props: {
formCreateInject: {
type: Object,
required: true
}
},
watch: {
//formCreateInject為組件生成時會給自定義組件注入的參數(shù)
"formCreateInject.rule.props": {
handler() {
//當表單設計器的自定義設置規(guī)則修改時,同步更新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({});
}
}
實現(xiàn)過程比較簡單,其中有一點解釋下,我們注意下這個formCreateInject
這個對象為表單設計器生成自定義組件時自動注入的參數(shù),這個屬性需在UI組件的自定義屬性中定義,否則沒法實現(xiàn)組件數(shù)據(jù)的回傳等等;
官方說明:預定義 props
TableOption
TableOption,根據(jù)名字就可以知道它是一個表格相關(guān)組件,如下圖:
點擊添加按鈕可以新增一行,在Table組件中就是用這個組件來實現(xiàn)自定義列名和表頭的。
官網(wǎng)源碼參考:https://gitee.com/xaboy/form-create-designer/blob/master/src/utils/index.js
{
type: "TableOptions",
field: "columns",
title: "設置表頭和列名",
props: {
defaultValue: []
},
},
輸入完成后我們將得到如下json:
[
{
label: 'seq',
value: ‘’
},
], //數(shù)據(jù)列
然后根據(jù)這個數(shù)據(jù)實現(xiàn)Ui組件中的列的繪制。
組件之間的聯(lián)動
這一節(jié)將介紹如何實現(xiàn)自定義行尾合計列的實現(xiàn)方式。
首先需添加一個下拉框來實現(xiàn)自定義列的選擇;
-
其次需要將已選的列回傳給Table組件,這里就用到了組件屬性之間的聯(lián)動,
可參考官方文檔:組件聯(lián)動概括來說就是,我們可以在某個組件規(guī)則的前后,甚至子級增加對另外一個組件規(guī)則的控制;在本例中,我們需要用TableOption控制表尾合計列多選拉下框的顯示
;所以合起來的代碼應該為
{
type: "TableOptions",
field: "columns",
title: "設置表頭和列名",
props: {
defaultValue: []
},
//組件聯(lián)動:設置完列名以后,更新顯示合計列的多選下拉列表
control: [
{
handle(val, fApi) {
sumColums = val;
sumColumsVal = [];
if (sumColums?.length > 0) {
sumColums.forEach(item => {
sumColumsVal.push(item.value);
});
}
//更新組件規(guī)則,否則數(shù)據(jù)修改不會更新UI
fApi.updateRule("sumColumns", {
value: sumColumsVal,
options: sumColums
});
return val?.length > 0;
},
append: "showSummary", //在某個組件后插入
rule: [
{
type: "select",
field: "sumColumns",
title: "自定義表尾合計列",
value: sumColumsVal,//選擇的數(shù)據(jù),類型為【】
options: sumColums,//選項數(shù)據(jù)
props: {
multiple: true
}
}
]
}
]
},
{ type: "switch", field: "showSummary", title: "是否顯示表尾合計" },
Ui組件中只計算某些列的合計實現(xiàn)如下:
//自定義合計方法,可以選擇只計算某些列的合計,不需要計算的返回空
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實現(xiàn)自定義FormCreate表單設計器組件
前面一節(jié)自己實現(xiàn)表格只能是比較簡單的樣式和效果,如果我想要更復雜的表格呢?如果只是增加更多的自定義屬性來控制表格的實現(xiàn),那么必定增加運營配置人員的負擔。此時VxeTable就為我們提供一個強大的功能,只要寫好高級配置的json,代碼中就可以根據(jù)這個json直接生成效果更為豐富的表格。
VxeTable官方文檔參考:https://vxetable.cn/#/table/start/install
本節(jié)我們用到的是VxeTable高級表格的能力,大概預覽下高級表格的實現(xiàn)代碼:
<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: number
name: string
nickname: string
role: string
sex: string
age: number
address: 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來進行編輯,就能快速實現(xiàn)不同效果的表格,這個方法對配置人員對要求較高T=T
實現(xiàn)過程不難,代碼就不放了。有興趣的同學可以自行實踐。文章來源:http://www.zghlxwxcb.cn/news/detail-628630.html
本篇文章介紹的內(nèi)容較多,相信經(jīng)過這篇介紹,以后再有自定義組件的需求時你一定都能游刃有余了。也有些盲點可能沒掃到,后續(xù)有研究會繼續(xù)更新的。有好的思路也歡迎評論區(qū)留言探討~文章來源地址http://www.zghlxwxcb.cn/news/detail-628630.html
到了這里,關(guān)于Vue——formcreate表單設計器自定義組件實現(xiàn)(二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!