# LowCode - 可视化中的规则组件设计

### ☀️ 为什么需要规则组件

'#{data.count > 10 ? "red" : "yellow"}'

1. 用户需要学习模板字符串语法，并且在编辑器中编写模板字符串并不方便
2. 变量名需要手动编写，容易出现错误

### 🌧 设计要求

1. 单一变量结果，如#{data.count}
2. 条件判断，如'#{data.count > 10 ? "red" : "yellow"}'
3. 多条件判断，如#{data.count > 10? "red" : data.price > 100 ? "yellow" : "blue"}
4. 同时满足多个条件，如#{data.count > 10 && data.price > 100 ? "red" : "yellow"}

### 🌟 设计思路

#### 整体思路

[
{ conditions: conditions1, result: 'result1' },
{ conditions: conditions2, result: 'result2' },
{ result: 'result3' }
]

#### conditions思路

conditions: { variable: 'data.count', operator: '===', value: 10 },

conditions: [
{ variable: 'data.count', operator: '===', value: 10 },
{ variable: 'data.price', operator: '>', value: 100 }
],

### ☃️ 格式解析

function transformValue(value) {
if (typeof value === 'string') {
return `'\${value}'`;
}

return value;
}

function parseCondition(condition, data) {
const { variable, operator, value } = condition;
const conditionStr = operator
? `#{\${variable} \${operator} \${transformValue(value)}}`
: `#{\${variable}}`;

let result;
try {
// 把data传入模板字符串，返回模板字符串执行结果
result = template(conditionStr, data);
} catch (e) {}

return result;
}

function transform(config, data) {
let finalResult;
for (let i = 0; i < config.length; i += 1) {
const { conditions = [], result } = config[i];
if (!conditions.length) {
finalResult = result;
break;
}
if (conditions.every((condition) => parseCondition(condition, data))) {
finalResult = result;
break;
}
}

return finalResult;
}

### 🌈 代码实现思路

#### result结果项配置

resultFields: [
{
name: 'children',
label: '文本',
wrapperCol: 24,
labelCol: 2,
field: {
type: 'autocomplete',
props: {
allowClear: true,
}
}
},
{
name: 'type',
label: '类型',
field: {
type: 'autocomplete',
props: {
source: [
{ text: 'success', value: 'success' },
{ text: 'danger', value: 'danger' },
],
resultType: 'textType',
},
},
},
{
name: 'style',
label: '样式',
field: 'editor',
}
]

// 核心代码如下
import { FunctionComponent, ComponentClass } from 'react';

class PluginStore {
plugins = {};

registerField = (key, field) => {
if (this.plugins[key]) return;
this.plugins[key] = field;
};

getPlugins = () => {
return this.plugins;
};
}

const pluginStore = new PluginStore();

export default pluginStore;