Skip to content

Create a Module

Module Resource Loading

Use the load method to load module resources. The data parameter should be in array format.

js
ptah.$load(RESOURCE_TYPE.BLOCKS, data);

Module Data Structure

The module data structure defines the type, title, and items contained in the module. Here’s an example:

json
[
  {
    "title": "Web Module",
    "items": [
      {
        "title": "Common",
        "icon": "icon-detail",
        "items": [UiButton, UiBox]
      },
      {
        "title": "Layout",
        "icon": "icon-detail",
        "items": [UiGrid]
      }
    ]
  }
]

Create a Button Module

Steps

  1. Create UiButton Directory to store module-related code:

    UiButton
      ├─ index.js
      ├─ index.vue
      └─ schema.js
  2. Create index.js

    The index.js file exports the component and its configuration.

    js
    import Component from './index.vue';
    import Schema from './schema';
    
    export default {
        Component,
        Schema
    };
  3. Create schema.js

    The schema.js file defines the properties and configuration of the module. Below is an example of the configuration for a button module:

    js
    import {
        createSlot,
        createGroupProp,
        createObjectProp,
        createArrayProp,
        createStringProp,
        createNumberProp,
        createBooleanProp
    } from '@ptahjs/creative-vue';
    
    export default () => {
        return {
            type: 'UiButton',
            title: 'Button',
            // icon: "input-cursor-move",
            // image: "./path.png",
            props: [
                createStringProp({
                    component: 'PropString',
                    field: 'field1',
                    label: 'Box1'
                }),
                createNumberProp({
                    component: 'PropNumber',
                    field: 'field2',
                    label: 'Width',
                    defaultValue: 0
                }),
                createArrayProp({
                    field: 'field3',
                    label: 'Select',
                    defaultValue: '1',
                    options: [
                        { label: 'primary', value: '1' },
                        { label: 'secondary', value: '2' },
                        { label: 'dashed', value: '3' },
                        { label: 'outline', value: '4' },
                        { label: 'text', value: '5' }
                    ]
                }),
                createGroupProp({
                    label: 'Group',
                    props: [
                        createStringProp({
                            field: 'field4',
                            label: 'Box2'
                        }),
                        createNumberProp({
                            field: 'field5',
                            label: 'Width',
                            defaultValue: 0
                        })
                    ]
                }),
                createBooleanProp({
                    label: 'Toggle',
                    field: 'field6',
                    defaultValue: true
                }),
                createObjectProp({
                    field: 'field9',
                    label: 'Object',
                    defaultValue: {},
                    props: [
                        createStringProp({
                            field: 'field10',
                            label: 'Obj-1'
                        }),
                        createNumberProp({
                            field: 'field11',
                            label: 'Obj-2',
                            defaultValue: 0
                        })
                    ]
                })
            ],
            events: [
                {
                    type: 'click',
                    title: 'CLICK'
                },
                {
                    type: 'onload',
                    title: 'LOAD'
                }
            ],
            slots: [
                createSlot({
                    title: 'slot1',
                    props: []
                })
            ]
        };
    };

    The generated data structure for the above configuration looks like this:

    js
    {
      field1: '',
      field2: 0,
      field3: 1,
      field4: '',
      field5: 0,
      field6: true,
      field9: {
        field10: '',
        field11: 0
      }
    }

    Each method has a component property used for customizing parameter components. The next chapter will explain how to use these components.

    js
    createStringProp({
      component: "PropString"
    }),
  4. Create index.vue

    The index.vue file defines the UI component for the module. Below is an example of a button component:

    vue
    <template>
        <!-- ref binds the current module's ID. Complex interactions will use the component's ref function if necessary. -->
        <div :ref="id" class="ui-button">
            <button @click="onTestEventClick">Button</button>
        </div>
    </template>
    
    <script>
    import { defineComponent } from 'vue';
    import { useUI, useExecuteEvent } from '@ptahjs/creative-vue';
    
    export default defineComponent({
        name: 'UiButton',
        props: {
            id: {
                type: String,
                default: ''
            }
        },
        setup(props) {
            // Initialize the current UI module. This function must be called for the module.
            const { module } = useUI(props.id);
    
            const { execute } = useExecuteEvent(module);
    
            // Test click event
            const onTestEventClick = (e) => {
                execute('click', (res) => {
                    console.log('res', res);
                });
            };
    
            return { onTestEventClick };
        }
    });
    </script>

    Note

    The module development process for Web, Mobile, and Canvas is similar.

Create Flows Module

Steps

  1. Create UiAjax Directory to store module-related code:

    UiAjax
      ├─ action.js
      ├─ index.js
      ├─ index.vue
      └─ schema.js
  2. Create index.js

    The index.js file exports the component, schema, and action functions.

    js
    import Component from './index.vue';
    import Schema from './schema';
    import Action from './action';
    
    export default {
        Component,
        Schema,
        Action
    };
  3. Create action.js

    The action.js file defines the behavior logic of the module. Below is an example of an AJAX module:

    js
    export default (data) => {
        const { next } = data;
    
        setTimeout(() => {
            next(`<div>ajax</div>`);
        }, 2000);
    };
  4. Action Parameters

    ParameterDescription
    appptah instance
    nextPass the result to the next task
    itemCurrent module information
    paramsParameters
    previousResultResult from the previous task
    runRun a subprocess task
    terminateTerminate the entire process
    runCodeExecute JS code
    goToJump to a specified task
    countNumber of executions

Create 3D Module

Steps

  1. Create UiCube Directory to store module-related code:

    UiCube
      ├─ component.js
      ├─ index.js
      └─ schema.js
  2. Create index.js

    The index.js file exports the component and its configuration.

    js
    import Component from './component';
    import Schema from './schema';
    
    export default {
        Component,
        Schema
    };
  3. Create component.js

    The component.js file defines the 3D component template and its setup. Below is an example of a 3D cube:

    js
    import { BoxGeometry, MeshBasicMaterial, Mesh } from 'three';
    
    export default {
        // Module template
        template(engine, data) {
            const { props } = data;
            const geometry = new BoxGeometry(1, 1, 1);
            const material = new MeshBasicMaterial({ color: 0x00ff00 });
            const cube = new Mesh(geometry, material);
            return cube;
        },
        // Post-processing actions for the module
        setup(engine, entity) {
            engine.on('change', ({ type, data }) => {
                entity.position.x = data.value;
            });
        }
    };