【组件】常用组件封装

49 阅读1分钟

Http配置表单

Http配置表单,可配置Http接口调用的参数

image.png

/* 
Http配置表单
可配置Http接口调用的参数
*/

import { CloseOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, Card, Form, Input, Select, Space } from 'antd';
import { useMemo } from 'react';
import TextArea from 'antd/es/input/TextArea';

/* Http配置表单 */
const HttpConfigForm: React.FC = () => {
  const [form] = Form.useForm();

  /* 模拟后端返回的Http配置 */
  const httpConfig = {
    host: 'http://127.0.0.1:4523/m1/6920757-6636810-default',
    api: '/api/chat',
    method: 'GET',
    params: {
      a: '1',
      'b-2': '2',
    },
    headers: {
      'access-token': 'abc',
      contextType: 'application/json',
    },
    body: {
      array: [1, 2, 3],
      boolean: true,
      color: 'gold',
      null: null,
      number: 123,
      object: {
        a: 'b',
        c: 'd',
      },
      string: 'Hello World',
    },
  };

  /* httpConfig转表单值 */
  const formValues = useMemo(() => {
    return {
      ...httpConfig,
      params: Object.entries(httpConfig.params),
      headers: Object.entries(httpConfig.headers),
      body: JSON.stringify(httpConfig.body),
    };
  }, [httpConfig]);

  /* 表单值转换成最终输出 */
  const convertFormValues = (values: any) => {
    if (!values) return;
    values.params = values.params && Object.fromEntries(values.params);
    values.headers = values.headers && Object.fromEntries(values.headers);
    return values;
  };

  const onFinishFailed = (errorInfo) => {
    console.log(errorInfo);
  };

  const onFinish = (values: any) => {
    values = convertFormValues(values);
    console.log(values);
  };

  return (
    <Form
      form={form}
      onFinishFailed={onFinishFailed}
      onFinish={onFinish}
      initialValues={formValues}
    >
      <Card title="基础配置">
        <Form.Item label="host" name="host">
          <Input />
        </Form.Item>
        <Form.Item label="api" name="api">
          <Input />
        </Form.Item>
        <Form.Item label="method" name="method">
          <Select
            options={[
              { value: 'GET', label: 'GET' },
              { value: 'POST', label: 'POST' },
              { value: 'PUT', label: 'PUT' },
              { value: 'DELETE', label: 'DELETE' },
            ]}
          />
        </Form.Item>
      </Card>
      {/* params配置 */}
      <Form.List name="params">
        {(fields, { add, remove }) => (
          <>
            <Card title="params配置">
              {fields.map((field) => (
                <Space
                  key={field.key}
                  style={{ display: 'flex' }}
                  align="baseline"
                >
                  <Form.Item label="属性名" name={[field.name, 0]}>
                    <Input />
                  </Form.Item>
                  <Form.Item label="属性值" name={[field.name, 1]}>
                    <Input />
                  </Form.Item>
                  <CloseOutlined onClick={() => remove(field.name)} />
                </Space>
              ))}
              <Button onClick={() => add()} icon={<PlusOutlined />}>
                添加param
              </Button>
            </Card>
          </>
        )}
      </Form.List>
      {/* headers配置 */}
      <Form.List name="headers">
        {(fields, { add, remove }) => (
          <Card title="headers配置">
            {fields.map((field) => (
              <Space
                key={field.key}
                style={{ display: 'flex' }}
                align="baseline"
              >
                <Form.Item label="属性名" name={[field.name, 0]}>
                  <Input />
                </Form.Item>
                <Form.Item label="属性值" name={[field.name, 1]}>
                  <Input />
                </Form.Item>
                <CloseOutlined onClick={() => remove(field.name)} />
              </Space>
            ))}
            <Button onClick={() => add()}>添加header</Button>
          </Card>
        )}
      </Form.List>
      {/* body配置 */}
      <Card title="body配置">
        <Form.Item name="body">
          <TextArea />
        </Form.Item>
      </Card>
      <Form.Item>
        <Button type="primary" htmlType="submit">
          Submit
        </Button>
      </Form.Item>
    </Form>
  );
};

export default HttpConfigForm;

JSON编辑框

使用vanilla-jsoneditor包封装JSON编辑器

image.png

// https://www.npmjs.com/package/vanilla-jsoneditor
import { useEffect, useRef } from 'react';
import {
  createJSONEditor,
  type JSONEditorPropsOptional,
} from 'vanilla-jsoneditor';

const JSONEditor: React.FC<JSONEditorPropsOptional> = (props) => {
  const refContainer = useRef<HTMLDivElement>(null);
  const refEditor = useRef<JSONEditor | null>(null);

  useEffect(() => {
    // create editor
    refEditor.current = createJSONEditor({
      target: refContainer.current!,
      props: {},
    });

    return () => {
      // destroy editor
      if (refEditor.current) {
        refEditor.current.destroy();
        refEditor.current = null;
      }
    };
  }, []);

  useEffect(() => {
    // update props
    if (refEditor.current) {
      refEditor.current.updateProps(props);
    }
  }, [props]);

  return <div ref={refContainer}></div>;
};

export default JSONEditor;