Vjdesign is a dynamic form designer with high scalability. This example implements a custom attribute editor example

instructions

Custom Components

Start by making a VUE custom component

Vue.component("custom-number", {
  template: `<div><button type="button" @click="mut">-</button> {{value}} <button type="button" @click="plus">+</button></div>`.props: { value: Number.default: 0 },
  methods: {
    plus() {
      this.$emit("input", (this.value || 0) + 1);
    },
    mut() {
      this.$emit("input".Math.max((this.value || 0) - 1.0)); }}});Copy the code

The editor method is used to register the property editor, and the first parameter is the value to be set by editor in the designer configuration file

And then you define a property editor, which is a method that returns an object, and the method that defines that object is the same as the method in JFormer that defines the dynamic form component, component is the name of the component that you just defined, and you pass a path, This path is the name of the property that the component is editing at the time the designer is editing it. Set this path to the component data model to update the corresponding properties of the component

 window.vjdesign.default.use(({ editor }) = > {
  editor("customNumber".(path) = > {
    return {
      component: "custom-number".model: [path]
    };
  });
});
Copy the code

Use custom property editors on component properties in configuration files

{
  name: "el-row",
  label: "Line",
  group: "element",
  properties: [
    {
      name: "fieldOptions.props.gutter",
      label: "Interval",
      group: "Component".// Here is the registered property editor name
      editor: "customNumber"
    }
  ],
  designer: "classContainer"
}
Copy the code

To use a custom or third-party component as a property editor, reference the component in your VUE project

Use existing components and pass parameters

The implementation uses el-Silder as the property editor and passes the range and step size of the parameter limit values

First define and register a component property editor. In addition to the path parameter, options are additional configuration information defined in the configuration file, usually as editor component properties

window.vjdesign.default.use(({ editor }) = > {
  editor("elSilder".(path, options) = > {
    return {
      component: "el-slider".model: [path],
      fieldOptions: { props: options }
    };
  });
});
Copy the code

The property editor is used in the designer configuration file

{
  name: "el-col",
  label: "Column",
  group: "element",
  properties: [
    {
      name: "fieldOptions.props.span",
      label: "Column width",
      group: "Component",
      default: 12,
      editor: {
        // Property editor name
        name: "elSilder".// Properties editor properties
        options: { step: 1, min: 1, max: 24 }
      }
    }
  ],
  designer: "classContainer"
}
Copy the code

Complete sample

HTML page

Save the following implementation directly as HTML to see the effect

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Static Template</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="https://cdn.jsdelivr.net/npm/vjdesign"></script>
    <script src="https://cdn.jsdelivr.net/npm/element-ui/lib/index.js"></script>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/vjdesign/dist/vjdesign.css"
    />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/element-ui/lib/theme-chalk/index.css"
    />
    <style>
      html {
        font-size: 14px;
      }

      #app {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <v-jdesign v-model="config" v-bind:profile="profile"></v-jdesign>
    </div>

    <script>
      const Vue = window.Vue;

      Vue.component("custom-number", {
        template: `<div><button type="button" @click="mut">-</button> {{value}} <button type="button" @click="plus">+</button></div>`.props: { value: Number.default: 0 },
        methods: {
          plus() {
            this.$emit("input", (this.value || 0) + 1);
          },
          mut() {
            this.$emit("input".Math.max((this.value || 0) - 1.0)); }}});window.vjdesign.default.use(({ editor }) = > {
        editor("customNumber".(path) = > {
          return {
            component: "custom-number".model: [path]
          };
        });

        editor("elSilder".(path, options) = > {
          return {
            component: "el-slider".model: [path],
            fieldOptions: { props: options }
          };
        });
      });

      new Vue({
        data() {
          return {
            config: {
              datasource: {},
              listeners: [].fields: [{component: "div".children: [{component: "el-row".children: [{component: "el-col".fieldOptions: {
                            props: {
                              span: 10}}}, {component: "el-col".fieldOptions: {
                            props: {
                              span: 12}}}, {component: "el-col".fieldOptions: {
                            props: {
                              span: 12}}}, {component: "el-col".fieldOptions: {
                            props: {
                              span: 16}}}]}],model: {}},profile: {
              components: [{name: "el-row".label: "Line".group: "element".properties: [{name: "fieldOptions.props.gutter".label: "Interval".group: "Component".editor: "customNumber"}].designer: "classContainer"
                },
                {
                  name: "el-col".label: "Column".group: "element".properties: [{name: "fieldOptions.props.span".label: "Column width".group: "Component".default: 12.editor: {
                        name: "elSilder".options: { step: 1.min: 1.max: 24}}}].designer: "classContainer"}}}; } }).$mount("#app");
    </script>
  </body>
</html>
Copy the code

A link to the

Designer: Github Gitee