{"id":21735626,"url":"https://github.com/blryli/v-form-layer","last_synced_at":"2025-04-13T01:55:01.221Z","repository":{"id":35076180,"uuid":"203961944","full_name":"blryli/v-form-layer","owner":"blryli","description":"表单快速布局，表单/表格逻辑校验，焦点控制，图层化展示信息","archived":false,"fork":false,"pushed_at":"2023-01-04T07:56:16.000Z","size":7728,"stargazers_count":9,"open_issues_count":27,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-13T01:54:37.766Z","etag":null,"topics":["form","layer","layout","table","validate","vue","vuejs","vuejs2"],"latest_commit_sha":null,"homepage":"https://blryli.github.io/v-form-layer/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blryli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-23T08:55:24.000Z","updated_at":"2022-08-07T03:00:50.000Z","dependencies_parsed_at":"2023-01-15T13:30:20.400Z","dependency_job_id":null,"html_url":"https://github.com/blryli/v-form-layer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blryli%2Fv-form-layer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blryli%2Fv-form-layer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blryli%2Fv-form-layer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blryli%2Fv-form-layer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blryli","download_url":"https://codeload.github.com/blryli/v-form-layer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654051,"owners_count":21140235,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["form","layer","layout","table","validate","vue","vuejs","vuejs2"],"created_at":"2024-11-26T05:13:53.297Z","updated_at":"2025-04-13T01:55:01.202Z","avatar_url":"https://github.com/blryli.png","language":"JavaScript","readme":"## v-form-layer\r\n\r\n- 快速实现复杂布局\r\n- 轻松实现逻辑校验，多种展示效果\r\n- 支持多图层展示\r\n\r\n### 演示\r\n\r\n[github pages](https://blryli.github.io/v-form-layer/)\r\n\r\n#### npm 安装\r\n\r\n```js\r\nnpm i -S v-form-layer\r\n```\r\n\r\n#### 使用\r\n\r\n```js\r\nimport VFormLayer from 'v-form-layer'\r\nimport 'v-form-layer/dist/v-form-layer.css'\r\n\r\nVue.use(VFormLayer)\r\n\r\n// 或者直接使用script导入\r\n\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/v-form-layer/dist/v-form-layer.css\"\u003e\u003c/link\u003e\r\n\r\n\u003cscript src=\"https://unpkg.com/v-form-layer/dist/v-form-layer.min.js\"\u003e\u003c/script\u003e\r\n```\r\n\r\n#### 基本布局\r\n\r\n```html\r\n\u003cv-form\u003e\r\n  \u003cv-form-line :cols=\"[{ label: '名字' },{ label: '年龄' }]\"\u003e\r\n    \u003cinput v-model=\"form.name\" /\u003e\r\n    \u003cinput v-model=\"form.age\" /\u003e\r\n  \u003c/v-form-line\u003e\r\n\u003c/v-form\u003e\r\n```\r\n\r\n#### 增加图层\r\n\r\n```html\r\n\u003cv-form v-model=\"layer\"\u003e\r\n  \u003cv-form-line\r\n    :cols=\"[{ label: '名字', path: '/name' },{ label: '年龄', path: '/age'}]\"\u003e\r\n    \u003cinput v-model=\"form.name\" /\u003e\r\n    \u003cinput v-model=\"form.age\" /\u003e\r\n  \u003c/v-form-line\u003e\r\n\u003c/v-form\u003e\r\n\r\n\u003cv-layer\u003e\r\n  \u003cv-layer-group\r\n    :cols=\"[{ label: '名字', path: '/name' },{ label: '年龄', path: '/age'}]\"\u003e\r\n    \u003cinput v-model=\"form.name\" /\u003e\r\n    \u003cinput v-model=\"form.age\" /\u003e\r\n  \u003c/v-layer-group\u003e\r\n  \u003cv-layer-item :col=\"{ label: '名字', path: '/name' }\"\u003e\r\n    \u003cinput v-model=\"form.name\" /\u003e\r\n  \u003c/v-layer-item\u003e\r\n\u003c/v-layer\u003e\r\n```\r\n\r\n```js\r\n\u003cscript\u003e\r\nexport default {\r\n  data () {\r\n    return {\r\n      form: {},\r\n      layer: [\r\n        {\r\n          id: \"layer-1\",\r\n          show: true,\r\n          data: [\r\n            {\r\n              path: \"/name\",\r\n              message: \"测试message\"\r\n            },\r\n            {\r\n              path: \"/age\",\r\n              message: \"测试message\"\r\n            }\r\n          ]\r\n        },\r\n      ]\r\n    }\r\n  }\r\n}\r\n\u003c/script\u003e\r\n```\r\n\r\n#### 逻辑校验\r\n\r\n```html\r\n\u003cv-form ref=\"form\" :data=\"form\" v-model=\"layer\"\u003e\r\n  \u003cv-form-line\r\n    :cols=\"[{path: '/error', label: '名字', validator: rules.error},\r\n            {path: '/async', label: '年龄', validator: rules.async}]\"\u003e\r\n    \u003cinput v-model=\"form.error\" /\u003e\r\n    \u003cinput v-model=\"form.async\" /\u003e\r\n  \u003c/v-form-line\u003e\r\n\u003c/v-form\u003e\r\n\r\n\u003c-- 如果是表格校验，结构如下 !--\u003e\r\n\u003cv-form ref=\"form\" v-model=\"layer\" :data=\"data\" rowledge=\"0\"\u003e\r\n  \u003cel-table :data=\"data\"\u003e\r\n    \u003cel-table-column label=\"必填校验\"\u003e\r\n      \u003ctemplate slot-scope=\"scope\"\u003e\r\n        \u003cv-form-line :cols=\"[{path: `/${scope.$index}/error`, validator: rules.error}]\"\u003e\r\n            \u003cel-input slot=\"reference\" v-model=\"scope.row.error\"/\u003e\r\n        \u003c/v-form-line\u003e\r\n      \u003c/template\u003e\r\n    \u003c/el-table-column\u003e\r\n    \u003cel-table-column label=\"年龄\"\u003e\r\n      \u003ctemplate slot-scope=\"scope\"\u003e\r\n        \u003cv-form-line :cols=\"[{path: `/${scope.$index}/age`}]\"\u003e\r\n          \u003cel-input v-model=\"scope.row.age\"/\u003e\r\n        \u003c/v-form-line\u003e\r\n      \u003c/template\u003e\r\n    \u003c/el-table-column\u003e\r\n  \u003c/el-table\u003e\r\n\u003c/v-form\u003e\r\n\r\n\u003cel-button @click=\"validate\"\u003e校验\u003c/el-button\u003e\r\n\u003cel-button @click=\"clearValidate\"\u003e清除校验\u003c/el-button\u003e\r\n```\r\n\r\n```js\r\n\u003cscript\u003e\r\nimport { validateSuccess, validateError } from '@/utils/validate';\r\n\r\nexport default {\r\n  data () {\r\n    rules: {\r\n      error:val =\u003e {\r\n        if (!val) {\r\n          return validateError('必填字段测试文本')\r\n        } else {\r\n          return validateSuccess()\r\n        }\r\n      },\r\n      async:async val =\u003e {\r\n        if (await this.getDate()) {\r\n          return validateError('异步校验测试文本')\r\n        } else {\r\n          return validateSuccess()\r\n        }\r\n      }\r\n    }\r\n    return {\r\n      form: {},\r\n      data： [],\r\n      layer: [],\r\n      rules\r\n    }\r\n  },\r\n  methods: {\r\n    async getDate() {\r\n      const timeout = () =\u003e new Promise((resolve) =\u003e setTimeout(resolve, 500))\r\n      await timeout()\r\n      return true\r\n    },\r\n    validate() {\r\n      this.$refs['form'].validate((val, validators) =\u003e {\r\n        console.log(JSON.stringify(validators, null, 2)) // 所有校验结果数组\r\n        console.log(val, val ? '校验通过' : '校验不通过') \r\n      })\r\n    },\r\n    clearValidate() {\r\n      this.$refs['form'].clearValidate()\r\n    }\r\n  }\r\n}\r\n\u003c/script\u003e\r\n```\r\n\r\n@/utils/validate.js 定义全局校验结果样式\r\n\r\n```js\r\nexport const validateSuccess = message =\u003e {\r\n  return {\r\n    message,\r\n    effect: '#67c23a',\r\n    disabled: true,\r\n    referenceBorderColor: '#67c23a',\r\n    referenceBgColor: '#e1f3d8'\r\n  }\r\n}\r\n\r\nexport const validateError = message =\u003e {\r\n  return {\r\n    message,\r\n    effect: '#F56C6C',\r\n    referenceBorderColor: '#F56C6C',\r\n    referenceBgColor: '#fde2e2',\r\n    stop: true\r\n  }\r\n}\r\nexport const validateWarn = message =\u003e {\r\n  return {\r\n    message,\r\n    effect: '#E6A23C',\r\n    referenceBorderColor: '#E6A23C',\r\n    referenceBgColor: '#faecd8'\r\n  }\r\n}\r\n```\r\n\r\n### v-form Attributes\r\n\r\n| 参数                    | 说明                               | 类型         | 可选值         | 默认值 |\r\n| ----------------------- | ---------------------------------- | ------------ | -------------- | ------ |\r\n| layer                   | 图层数组                           | array        | -              | -      |\r\n| data                    | 数据对象，用于校验时获取字段的值   | object/array | -              | -      |\r\n| label-width             | 表单域标签的宽度                   | string       | -              | -      |\r\n| label-position           | label 的位置                       | string       | left/right/top | right  |\r\n| line-height             | form-item 内 label 及 content 行高 | string       | -              | '32px' |\r\n| rowledge                | form-item 行距                     | string       | -              | '24px' |\r\n| item-gutter             | form-item 之间的间隔               | number       | -              | 0      |\r\n| response                | 表单响应式，只在手机端生效         | boolean      | -              | true   |\r\n| focus-open                   | 是否开启聚焦模式                   | boolean      | -              | false  |\r\n| focus-stop            | 停止聚焦处理                       | boolean       | -              | false |\r\n| focus-pause            | 暂停聚焦处理，会抛出focus-prev/focus-next事件 | boolean       | -              | false |\r\n| focus-options            | 聚焦模式参数                       | object       | -              | 看下面 |\r\n| focus-text-all-selected | 聚焦文本全选                       | boolean      | -              | false   |\r\n\r\n```js\r\nfocusOptions: { // object\r\n  // 聚焦模式参数\r\n\r\n  prevKeys: 'shift+enter', // string\r\n  // 上一个聚焦快捷键设置\r\n\r\n  nextKeys: 'enter', // string\r\n  // 下一个聚焦快捷键设置\r\n\r\n  skips: ['/node2'], // string\r\n  // 跳过聚焦的字段集合\r\n\r\n  loop: false // boolean\r\n  // 聚焦循环\r\n}\r\n```\r\n\r\n### v-form Methods\r\n\r\n| 方法名        | 说明                                                                                                     | 参数                                             |\r\n| ------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |\r\n| validate      | 对整个表单进行重算的方法，参数是一个回调函数(第一个参数是校验是否通过，第二个参数是所有校验结果集合数组) | Function(boolean, array)                         |\r\n| validateField | 对单个字段进行重算的方法，参数是路径，规则， 数据对象                                                    | path: string, rule: function, data：object/array |\r\n| clearValidate | 移除表单校验结果。参数是要移除校验结果的路径数组，如不传则移除整个表单的重算结果)                        | paths: array                                     |\r\n| focus         | path 对应节点聚焦，不传参数则聚焦第一个可聚焦节点节点                                                              | path: string                                     |\r\n| blur          | path 对应节点失焦                                                              | path: string                                     |\r\n| select        | path 对应节点文本选中                                                     | path: string                                     |\r\n\r\n\r\n\r\n### v-form Events\r\n\r\n| 事件名称 | 说明                   | 回调参数                    |\r\n| -------- | ---------------------- | --------------------------- |\r\n| validate | 任一表单项被校验后触发 | {path,success,message,stop} |\r\n| focus-prev | 聚焦上一个节点   |        path            |\r\n| focus-next | 聚焦下一个节点   |        path            |\r\n| last-focused-node-next | 开启聚焦模式（focus-open 为 true），并且为非循环模式（loop 不为 true）下，在最后一个可聚焦的节点（最后一个节点，或是在它之后的所有节点均不可被聚焦的节点），执行下一个节点聚焦操作时触发 | path |\r\n| first-focused-node-prev | 开启聚焦模式（focus-open 为 true），并且为非循环模式（loop 不为 true）下，在第一个可聚焦的节点（第一个节点，或是在它之前的所有节点均不可被聚焦的节点），执行上一个节点聚焦操作时触发 | path |\r\n| show     | 图层显示时触发         | prop                        |\r\n| hide     | 图层隐藏时触发         | prop                        |\r\n| focus     | 节点聚焦时触发         | path                        |\r\n| blur     | 节点失焦时触发         | path                        |\r\n\r\n### layer 图层\r\n\r\n```js\r\n  layer: [ // array\r\n    {\r\n      id: 'layerId', // string\r\n\r\n      show: true, // boolean\r\n      // 图层是否展示\r\n\r\n      view: { // object\r\n      // 图层全局配置\r\n\r\n        type: 'popover', // string\r\n        // 类型\r\n\r\n        effect: 'dark', // string\r\n        // 主题或背景颜色，如果传入颜色值则主题颜色为该颜色值 可选主题 light/dark/warn/error\r\n\r\n        borderColor: '', // string\r\n        // 图层边框颜色\r\n\r\n        placement: 'top', // string\r\n        // 相对参考点展示位置 可选 top/right/bottom/left\r\n\r\n        disabled: false, // boolean\r\n        // 是否禁用\r\n\r\n        referenceBorderColor: '', // string\r\n        // 边框颜色\r\n\r\n        referenceBgColor: '', // string\r\n        // 背景颜色\r\n\r\n        // type 为 popover 时的样式\r\n          trigger: 'hover',  // string hover/change/validate(执行validate方法时才调用)\r\n          // 触发方式\r\n\r\n          hideDelay: 200,  // number\r\n          // 隐藏延时 \r\n\r\n          showAlways: false,  // boolean\r\n          // 是否总是显示 \r\n\r\n          enterable: false,  // boolean\r\n          // 鼠标是否可移入\r\n\r\n          visibleArrow: true,  // boolean\r\n          // 是否显示箭头\r\n      },\r\n\r\n      data: [\r\n        {\r\n          path: '', // string\r\n          // 使用图层路径，如不传或找不到路径，则以下配置不会作用于任何字段\r\n\r\n          message: '' | {} | [], // string/object/array\r\n          // 定义图层内容,如果是 object/array 类型则需要传模板 template，通过模板展示数据，\r\n\r\n          template: (message) =\u003e { return 模板/组件 }, // function\r\n          // 数据展示模板\r\n\r\n          stop: false, // boolean\r\n          // 校验后，是否阻止校验通过，需要声明为 true，才会阻止校验通过\r\n\r\n          // 可以添加局部图层配置，参数和 view 一致，会覆盖 view 配置\r\n          },\r\n        }\r\n      ]\r\n    }\r\n  ]\r\n```\r\n\r\n### v-form-line Attributes\r\n\r\n| 参数        | 说明                                                                     | 类型   | 默认值 |\r\n| ----------- | ------------------------------------------------------------------------ | ------ | ------ |\r\n| cols        | item 布局配置                                                            | array  | []     |\r\n| label       | 子节点并排展示时使用，form-line 设置 label 后，子节点设置的 label 将失效 | string | -      |\r\n| label-width | 表单域标签的宽度                                                         | string | -      |\r\n| required    | 是否在 label 文字前面显示必填 * 符号                                  | boolean | false     |\r\n| span        | form-line 在一行分成 24 份中所占的份数                                   | number | 24     |\r\n\r\n```js\r\ncols: [ // array\r\n  {\r\n    label: 'label', // string\r\n    // 标签文本\r\n\r\n    labelWidth: '80px', // string\r\n    // 表单域标签的宽度 该设置会覆盖 form-line 上的定义\r\n    \r\n    // 标签的宽度\r\n    span: 24, // number\r\n    // item 在 form-line 分成 24 份中所占的份数\r\n\r\n    path: '/path', // string\r\n    // 字段路径，在需要校验时是必须的\r\n    // 规则： 对象嵌套用 '/' 分割（如对象 object:{name: ''}，则 '/name'）\r\n    //       数组用 '/'+索引 分割（如数组 array:[{name: ''},{name: ''}]，则 '/0/name'，'/1/name' ）\r\n\r\n    validator: (value, path) =\u003e { * 对返回值进行处理 * }, // function\r\n    // 校验函数\r\n\r\n    trigger: 'blur', // string\r\n    // 触发校验的方式 可选 blur/change\r\n\r\n    required: false, // boolean/string\r\n    // boolean 是否在 label 文字前面显示必填 * 符号\r\n    // string 给 输入框 设置背景色标识必填  颜色值为传入的色值\r\n  }\r\n]\r\n```\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblryli%2Fv-form-layer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblryli%2Fv-form-layer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblryli%2Fv-form-layer/lists"}