Formula Editor
A relatively complete formula editor.
Features
- Visual design
- Relatively comprehensive error prompts
- Auto-completion prompts
- Customizable variables and synchronous/asynchronous functions
- Online debugging
- Dynamic formula execution engine
Design
The formulas generated by the online editor fully comply with js syntax.
In order to better display the formula, we abstract an object named material
. This object can be a variable
or function
. Users can customize materials
. These materials
will be displayed in the editor for easy viewing and use.
The data structure of the variable
and examples can be found in VarInfo API
The data structure of the function
and examples can be found in FunInfo API
In order to enable the editor to render material
correctly, we have limited its format. A material
consists of entry variable + namespace + material name
. The default entry variable
is $
. The following are legal material definitions:
- Age field
$.field.age
- Applicant field
$.model.applicant
in the model - Addition function
$.fun.sum
- Get the current time function
$.fun.now
- Call xxAPI
$.api.xx
The data structure of the namespace
and examples can be found in Namespace API
Therefore, a regular formula
would be: $.fun.sum($.field.age, 3)
.
During actual execution, the execution engine will convert material
and formula
into JS code, such as:
const $ = {
fun: {
sum() {
return Array.from(arguments).reduce((a, b) => a + b)
},
},
field: {
age: 18, // From default value or user input value
},
}
const asyncFunction = Object.getPrototypeOf(async () => {}).constructor
const asyncFn = new asyncFunction('$', `return ${formulaValue}`)
return await asyncFn($)
Setup
This setup assumes your client app is created with Vite and vue-ts template.
In your package.json
, you shall have the dependencies compatible with the following:
"dependencies": {
"@idealworld/formula-editor":"^1.0.0",
"@element-plus/icons-vue": "^2.1.0",
"element-plus": "^2.3.12",
"vue": "^3.3.4"
}
In your main.ts
, you shall import the libraries and CSS:
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import FormulaEditor from ''@idealworld/formula-editor'
import ''@idealworld/formula-editor/dist/style.css'
createApp(App).use(ElementPlus).use(FormulaEditor).mount('#app')
Import components from this library in your own component:
<script setup lang="ts">
import { ref } from 'vue'
import { iwInterface } from ''@idealworld/formula-editor'
const checkPass = ref<boolean>(true)
const formulaValue = ref<string>(`$.fun.concat($.fun.sum(1,$.field.age),3, true, ['1','2'], 'string',$.param.someVar)`)
const dialogVisible = ref<boolean>(false)
const targetVar: iwInterface.VarInfo = {
name: 'formName',
label: '表单标题',
kind: iwInterface.VarKind.STRING,
note: '表单的显示名称',
minLen: 2,
maxLen: 20,
}
const materials: iwInterface.Namespace[] = [
{
name: 'field',
label: '字段',
isVar: true,
showLabel: true,
color: '#f8e3c5',
items: [
{
name: 'applicant',
label: '申请人',
kind: iwInterface.VarKind.STRING,
note: '表单申请人姓名',
minLen: 2,
maxLen: 20,
cates: ['基础信息'],
},
],
},
{
name: 'model',
label: '模型',
isVar: true,
showLabel: true,
color: '#e1f3d8',
items: [
{
name: 'accountName',
label: '账号',
kind: iwInterface.VarKind.STRING,
note: '账号名',
minLen: 2,
maxLen: 20,
cates: ['账户'],
},
{
name: 'phone',
label: '手机号',
kind: iwInterface.VarKind.STRING,
cates: ['账户'],
},
],
},
{
name: 'api',
label: 'API',
isVar: false,
showLabel: true,
color: '#d9ec00',
items: [
{
name: 'getUserInfo',
label: '获取用户基础信息',
note: `根据用户Id获取用户信息`,
input: [
{
label: '用户Id',
kind: iwInterface.VarKind.STRING,
},
],
isVarLen: false,
isAsync: true,
body: `return await (await fetch('http://x.x.x.x/user/'+arguments[0])).json()`,
output: {
kind: iwInterface.VarKind.ANY,
},
cates: ['用户'],
},
],
},
]
</script>
<template>
<el-button @click="dialogVisible = true">打开</el-button>
<el-dialog v-model="dialogVisible">
<!-- v-model:formulaValue:formula value -->
<!-- v-model:checkPass:Check the formula correct -->
<!-- :targetVar:Target object of the formula -->
<!-- :materials:Material collection -->
<iw-editor v-model:formulaValue="formulaValue" v-model:checkPass="checkPass" :targetVar="targetVar" :materials="materials" />
</el-dialog>
</template>
For the complete parameters of iw-editor
, see: EditorProps API