1 Star 0 Fork 18

Alex314 / jformer

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

jformer

根据 vjform 的设计思路,扩展一个简化版的 json 定义方式

基于 vjform 二次开发,简化了 json 定义方式且支持 vjform 全部功能

起步

安装包

npm i jformer

项目运行

npm i
npm run dev

特性

支持 vjform 全部原有功能,除此之外加入属性名前缀转换解析,可以直接在属性名上加入特定前缀,实现绑定、计算、事件的转换

整合了组件部分属性,让组件使用更清晰简便

组件属性

整合了部分属性到 options

前缀 说明
v-model
params 输入的参数值,只会由组件外部更新
options 包含 fields datasource listeners,对应 vjform 相应属性
components 单独引用的组件,理论上 jformer 支持 vue 项目中引用的任何组件, 如果未在项目中 use 则可以传到这里实现组件支持

fields 组件定义规则

fields 属性定义内部组件,一个内部组件具有如下属性

属性 说明
component 组件名称,支持所有 html 标签和 vue 项目中引用的组件具有的名称
fieldOptions 组件的属性,是 vue 的 render 方法中 createElement 的第二个参数,具体参考 Vue 官方定义, 自定义组件 props 定义的属性均支持
children 组件的下级组件

json 定义示例

{
  "component": "div",
  "fieldOptions": {
    "class": "",
    "style": {
      "margin": "10px"
    },
    "domProps": {}
  },
  "children": []
}

组件支持属性的快捷定义,使用 vjform 注册的快捷定义均可支持,常用快捷定义如下

属性 说明
text 相当于 fieldOptions.domProps.innerText 属性
condition 根据条件决定组件是否存在,可配合 $ 前缀实现表达式和关联
events 定义组件的事件行为
model 具有交互行为的组件可将值关联到model里的某个属性,组件的交互行为会改变 model 里的属性值,例如:inputselect
[
  {
    "component": "p",
    "$:condition": "model.text.length > 4", // 条件显示
    "text": "文本"
  },
  {
    "component": "button",
    "events": [{ "name": "click", "@:handler": "alert('点击事件')" }]
  },
  {
    "component": "input",
    "model": "text" // 关联 model.text 属性
  }
]

fieldOptions 里的属性和组件的快捷定义均可以通过前缀定义实现程序逻辑

前缀定义

前缀定义实际上是简化了原来的转换定义,在属性名上加上相应前缀实现转换功能

前缀 说明
$ 表达式
# 文本模板
@ 事件
@<model 属性> 更新 model 属性的事件
^ 禁止转换

表达式

在属性前面加上 $ 前缀,实现将表达式的结果关联到属性上,直接支持 js 语法对属性进行处理

{
  "component": "div",
  "fieldOptions": {
    "props": {},
    "domProps": {
      "$:innerText": "model.text.length + 1" // 这里支持直接取 model,params,datasource 的属性进行计算关联到属性
    }
  }
}

文本模板

在属性前面加上 # 前缀,实现直接用 es6 的模板字符串输出内容

{
  "component": "div",
  "fieldOptions": {
    "props": {},
    "domProps": {
      "#:innerText": "输入了 ${model.text}"
    }
  }
}

事件

在属性前面加上 @ 前缀,可将表达式生成一个 function 关联到组件事件上

{
  "component": "button",
  // 同样支持 vjform 的快速定义事件
  "events": [
    {
      "name": "click",
      "@:handler": "alert('clicked!')"
    }
  ]
}

如果在 @ 后面加上 model 里的属性名,则可以实现触发事件后将表达式的结果直接更新到 model 属性上

{
  "component": "input",
  "fieldOptions": {
    "domProps": {
      "$:value": "model.text"
    },
    "on": {
      "@text:input": "arguments[0].target.value" // 将输入结果更新到 model.text
    }
  }
}

禁止转换

在属性上加入 ^ 前缀,则属性的值不做转换,保持原有的值

当出现 jformer 嵌套 jformer 或者自定义组件里使用了 jformer 的时候,嵌套的 jformer 属性需要在内部进行处理而不是由外层统一转换处理的时候,可以在组件相应属性上加入 ^ 标识

实现一个 Repeat 组件,内部使用 jformer 呈现动态视图

<template>
  <div v-if="!updating">
    <j-former
      :key="index"
      v-for="(item, index) in data"
      :value="item"
      :params="{ ...params, $index: index }"
      :options="options"
    ></j-former>
  </div>
</template>

<script>
  export default {
    props: {
      data: Array,
      params: Object,
      options: Object
    },
    watch: {
      'data.length': {
        handler() {
          this.updating = true
          this.$nextTick(() => {
            this.updating = false
          })
        }
      }
    },
    data() {
      return {
        updating: false
      }
    }
  }
</script>

在 jformer 中使用 Repeat 组件

{
  "fields": [
    {
      "component": "v-repeat", // 自定义组件,实现根据数组数据遍历生成界面,内部使用 jformer 呈现界面
      "fieldOptions": {
        "props": {
          "$:data": "model.listData",
          "params": {
            "$:listData": "model.listData" // 为了在组件内部实现删除功能,以 params 方式将原数组传递给内部
          },
          // 使用 ^ 前缀,外层 jformer 不对属性值进行转换,而是由内部处理
          "^:options": {
            "fields": [
              {
                "component": "div",
                "fieldOptions": {
                  "style": { "border": "1px solid black", "margin": "10px", "padding": "5px" }
                },
                "children": [
                  { "component": "p", "#:text": "第 ${params.$index + 1} 项" },
                  { "component": "input", "model": ["text"] },
                  {
                    "component": "button",
                    "text": "delete",
                    "fieldOptions": {
                      "on": { "@:click": "params.listData.splice(params.$index ,1)" }
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    },
    {
      "component": "button",
      "text": "add item",
      "fieldOptions": { "on": { "@:click": "model.listData.push({})" } }
    }
  ]
}

JSON 定义完整示例

{
  "datasource": {
    "list": {
      "type": "request",
      "method": "GET",
      "url": "http://localhost:8080/paths/data.json",
      "params": {}
    },
    "detail": {
      "type": "request",
      "method": "GET",
      "url": "http://localhost:8080/paths/detail.json",
      "params": {}
    }
  },
  "listeners": [
    {
      "watch": "model.text",
      "deep": false,
      "actions": [
        { "@:handler": "datasource.load()", "$:condition": "model.text.length >= 4" },
        { "@:handler": "detail.load()" },
        { "@text2:handler": "model.text + 'xxx'" }
      ]
    }
  ],
  "model": {
    "text": "",
    "text2": ""
  },
  "fields": [
    {
      "component": "input",
      "fieldOptions": {
        "domProps": {
          "$:value": "model.text"
        },
        "on": {
          "@text:input": "arguments[0].target.value"
        }
      }
    },
    {
      "component": "input",
      "model": "text2"
    },
    {
      "component": "div",
      "fieldOptions": {
        "props": {},
        "domProps": {
          "$:innerText": "model.text.length + 1"
        }
      }
    },
    {
      "component": "div",
      "fieldOptions": {
        "props": {},
        "domProps": {
          "#:innerText": "输入了 ${model.text}"
        }
      }
    },
    {
      "component": "button",
      "fieldOptions": {
        "props": {},
        "on": {
          "@:click": "datasource.load()"
        }
      }
    }
  ]
}
MIT License Copyright (c) 2020 yuanliang feng Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

基于vjform 二次开发,简化了 json 定义方式且支持 vjform 全部功能 展开 收起
JavaScript
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
JavaScript
1
https://gitee.com/fzwise/jformer.git
git@gitee.com:fzwise/jformer.git
fzwise
jformer
jformer
master

搜索帮助