Variant Form 3

repository·master·Indexed 23 days ago

https://github.com/vform666/variant-form3-vite

A high-efficiency low-code form solution for Vue 3.x featuring a visual drag-and-drop designer (<v-form-designer>) and a runtime renderer (<v-form-render>). It includes a programmatic designer controller via createDesigner() for managing widget lists, form configurations, and undo/redo history, as well as specialized tools for manipulating complex Table widgets.

Tokens
10.8K
Snippets
25
Records
68
Agent score
79%

What's inside variant-form3

  1. Overview of vuedraggable features

    master

    vuedraggable is a Vue 3.0 component that provides drag-and-drop functionality by wrapping Sortable.js. Key features include:

    • Synchronization: Automatically keeps the HTML list and your Vue view model array in sync.
    • Sortable.js Parity: Supports touch devices, drag handles, selectable text, smart auto-scrolling, and drag-and-drop between different lists.
    • Vue 3 Compatibility: Works with Vue.js 3.0 transition-group.
    • UI Library Integration: You can make existing UI components (like Vuetify, Element, or Vue Material) draggable using the tag and componentData props.
    • No jQuery: Zero dependency on jQuery.
    • Event Reporting: Provides events to report changes for full manual control.
  2. Use header and footer slots in vuedraggable

    master

    You can add non-draggable elements inside the draggable component using the header and footer slots. These elements will appear at the top or bottom of the draggable list but will not be part of the sortable items.

    <draggable v-model="myArray" item-key="id">
      <template #item="{element}">
        <div> {{element.name}} </div>
      </template>
      <template #header>
        <button @click="addPeople">Add to Top</button>
      </template>
      <template #footer>
        <button @click="addPeople">Add to Bottom</button>
      </template>
    </draggable>
  3. Use vuedraggable with transition-group

    master

    To add animations to your list, use the tag prop to specify transition-group. If you need to pass specific props to the transition component (like the animation name), use the component-data prop.

    <!-- Basic transition -->
    <draggable v-model="myArray" tag="transition-group" item-key="id">
      <template #item="{element}">
          <div> {{element.name}} </div>
      </template>
    </draggable>
    
    <!-- Transition with specific name -->
    <draggable v-model="myArray" tag="transition-group" :component-data="{name:'fade'}" item-key="id">
      <template #item="{element}">
        <div>{{element.name}}</div>
      </template>
    </draggable>
  4. Migrate from Vue 2 to Vue 3 version of vuedraggable

    master

    When upgrading from the Vue 2 version, note these breaking changes:

    1. Slots: Use the item slot instead of the default slot. You can no longer use v-for directly inside the component.
    2. Keys: Use the item-key prop to provide a key for items.
    3. Transitions: Use the tag prop and component-data prop to implement transitions instead of wrapping the component in a <transition-group>.
    <!-- Vue 2 (Old) -->
    <draggable v-model="myArray">
       <div v-for="element in myArray" :key="element.id">{{element.name}}</div>
    </draggable>
    
    <!-- Vue 3 (New) -->
    <draggable v-model="myArray" item-key="id">
      <template #item="{element}">
        <div>{{element.name}}</div>
      </template>
    </draggable>
  5. Install vuedraggable via CDN direct links

    master

    If you are not using a package manager, you can include the dependencies directly via CDN. Note that vuedraggable requires both vue and sortablejs to be present in the environment.

    <script src="//cdnjs.cloudflare.com/ajax/libs/vue/3.0.2/vue.min.js"></script>
    <!-- CDNJS :: Sortable (https://cdnjs.com/) -->
    <script src="//cdn.jsdelivr.net/npm/sortablejs@1.10.2/Sortable.min.js"></script>
    <!-- CDNJS :: Vue.Draggable (https://cdnjs.com/) -->
    <script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/4.0.0/vuedraggable.umd.min.js"></script>
  6. Register VForm 3 components globally

    master

    After installation, import VForm3 and its required CSS. VForm 3 requires element-plus to be installed and registered. Registering VForm3 globally provides both the <v-form-designer> and <v-form-render> components.

    import { createApp } from 'vue'
    import App from './App.vue'
    
    import ElementPlus from 'element-plus'  //引入element-plus库
    import 'element-plus/dist/index.css'  //引入element-plus样式
    
    import VForm3 from 'vform3-builds'  //引入VForm 3库
    import 'vform3-builds/dist/designer.style.css'  //引入VForm3样式
    
    const app = createApp(App)
    app.use(ElementPlus)  //全局注册element-plus
    app.use(VForm3)  //全局注册VForm 3(同时注册了v-form-designer和v-form-render组件)
    
    app.mount('#app')
  7. Integrate vuedraggable with Vuex

    master

    To use vuedraggable with Vuex, use a computed property with a getter and setter for the v-model. The getter retrieves the state, and the setter commits a mutation to update the list.

    <draggable v-model='myList' item-key="id">
      <template #item="{element}">
        <div>{{element.name}}</div>
      </template>
    </draggable>
    computed: {
        myList: {
            get() {
                return this.$store.state.myList
            },
            set(value) {
                this.$store.commit('updateList', value)
            }
        }
    }
  8. Build VForm as a Library for CDN/External Use

    master

    To ensure the library can be used via CDN or as an external dependency, the build.lib and build.rollupOptions must be configured as follows:

    1. Library Entry: Set build.lib.entry to your entry file (e.g., install-render.js) and define a name (e.g., VFormRender).
    2. External Dependencies: Use rollupOptions.external to prevent bundling dependencies like vue and element-plus into the library.
    3. Global Variables: Use rollupOptions.output.globals to map external dependencies to their global variable names (e.g., vue: 'Vue').
    4. CDN Support: Set rollupOptions.output.exports to 'default' to support CDN-based imports.
    build: {
      lib: {
        entry: resolve(__dirname, 'install-render.js'),
        name: 'VFormRender',
        fileName: (format) => `render.${format}.js`
      },
      rollupOptions: {
        external: ['vue', 'element-plus'],
        output: {
          exports: 'default', 
          globals: {
            vue: 'Vue',
            'element-plus': 'ElementPlus',
          },
          assetFileNames: `render.style.css`
        }
      }
    }
  9. Extend Variant Form 3 with Custom Extensions

    master

    To add custom components (widgets) to the Variant Form 3 designer and renderer, you must implement a loading sequence that registers the component's schema, the Vue components themselves, their property editors, and their code generators.

    There are two types of components to consider:

    1. Container Components: These require two Vue components—one for the design-time interface (Designer) and one for the run-time rendering (Renderer). They also require a Container Widget Code Generator (registerCWGenerator).
    2. Field Components: These typically use a single Vue component for both design-time and run-time. They require a Field Widget Code Generator (registerFWGenerator).

    Loading Workflow

    For Container Components:

    1. Load Schema: Use addContainerWidgetSchema(schema) to register the JSON schema.
    2. Register Components: Use app.component() to register both the design-time component and the run-time component.
    3. Register Property Editors: Use PERegister.registerCPEditor(app, componentId, editorId, editorInstance) to map component properties to UI editors (e.g., Boolean, InputText, or Select editors).
    4. Register Code Generator: Use registerCWGenerator(componentName, generatorFunction) to enable code generation for the container.

    For Field Components:

    1. Load Schema: Use addCustomWidgetSchema(schema) to register the JSON schema.
    2. Register Component: Use app.component() to register the single component used for both design and runtime.
    3. Register Property Editors: Use PERegister.registerCPEditor() for standard properties and PERegister.registerEPEditor() for event handlers (e.g., onClose).
    4. Register Code Generator: Use registerFWGenerator(componentName, generatorFunction) to enable code generation for the field.
  10. Fetch backend field lists for the designer

    master

    You can configure the designer to automatically fetch field lists from your backend API using the fieldListApi prop. The designer will use the provided URL and map the response data using labelKey and nameKey.

    Example configuration:

    {
      fieldListApi: {
        URL: 'https://api.example.com/fields',
        headers: { 'Authorization': 'Bearer token' },
        labelKey: 'display_name',
        nameKey: 'field_id'
      }
    }