Commit f352f3c3 authored by 刘子康's avatar 刘子康

增加demo/剔除业务定义代码改为更加通用的方式置入请求方法

parent 882fccf4
# way-view-form # way-view-form
基于 iview 封装的 JSON To Form 表单组件,支持 Search 和 Form 两种模式 基于 iview 封装的 JSON To Form 表单组件,支持 Search 和 Form 两种模式
## Install ## Install
```bash ```bash
# 请先配置内网 npm 源 http://192.168.9.197:4873/ # 请先配置内网 npm 源 http://192.168.9.197:4873/
npm install way-view-form --save npm install way-view-form --save
``` ```
## Usage ## Usage
```js ```js
// main.js // main.js
// ...引入vue和iview之后 // ...引入vue和iview之后
// 引入组件库 // 引入组件库
import WayViewForm from 'way-view-form' import WayViewForm from "way-view-form";
import 'way-view-form/dist/way-view-form.css' import "way-view-form/dist/way-view-form.css";
Vue.use(WayViewForm) Vue.use(WayViewForm);
``` ```
## 参数说明 ## 参数说明
### Props ### Props
...@@ -42,20 +43,44 @@ Vue.use(WayViewForm) ...@@ -42,20 +43,44 @@ Vue.use(WayViewForm)
#### form <Array> #### form <Array>
| 参数名称 | 类型 | 是否必选 | 说明 | | 参数名称 | 类型 | 是否必选 | 说明 |
| :--------------- | :------ | :------- | :----------------------------------------------------- | | :--------------- | :------ | :------- | :--------------------------------------------------------- |
| name | string | true | 显示在表单的 label 名称 | | name | string | true | 显示在表单的 label 名称 |
| placeholder | string | | 占位提示符 一般会根据 name 和类型自动生成 | | placeholder | string | | 占位提示符 一般会根据 name 和类型自动生成 |
| type | string | true | 表单的类型,如 'Select'、'Input' 等 | | type | string | true | 表单的类型,如 'Select'、'Input' 等 |
| key | string | true | 表单提交时的键名,对应表单数据对象的属性名 | | key | string | true | 表单提交时的键名,对应表单数据对象的属性名 |
| value | any | | 表单的默认值 | | value | any | | 表单的默认值 |
| rules | array | | 表单的校验规则 | | rules | array | | 表单的校验规则 |
| required | boolean | | 表单是否必填 rules 的快捷设置 | | required | boolean | | 表单是否必填 rules 的快捷设置 |
| componentsProps | object | | 表单组件的 props 配置,如 'filterable'、'clearable' 等 | | componentsProps | object | | 表单组件的 props 配置,如 'filterable'、'clearable' 等 |
| componentsEvents | object | | 表单组件的事件,如 'on-change'、'on-input' 等 | | componentsEvents | object | | 表单组件的事件,如 'on-change'、'on-input' 等 |
| source | object | | 表单项的数据源,包含 API 接口、接口参数、处理函数 | | source | object | | 表单项的数据源,包含 API 接口、接口参数、处理函数 |
| showName | object | | 显示在选项中的名称的键名 | | showName | object | | 显示在选项中的名称的键名 |
| showValue | object | | 选项值的键名 | | showValue | object | | 选项值的键名 |
| colProps | object | | 在 type=='Row'作为根节点时有效,用于设置表单项外层的 props |
#### type 可选类型
理论上末级组件都可以作为表单项(通过props设置的均可,slot配置的暂不支持)Title为特殊组件,用于分组;
!> 理论上其他框架的组件也可以作为表单项,只要支持v-model即可
| 参数名称 | 类型 | 是否必选 | 说明 |
| :------------- | :----- | :------- | :------------------- |
| Input | string | true | 输入框 |
| Select | string | true | 选择器 |
| DatePicker | string | true | 日期选择器 |
| TimePicker | string | true | 时间选择器 |
| InputNumber | string | true | 数字输入框 |
| Switch | string | true | 开关 |
| Checkbox | string | true | 多选框 |
| CheckkboxGroup | string | true | 多选框组 |
| Radio | string | true | 单选框 |
| RadioGroup | string | true | 单选框组 |
| Cascader | string | true | 级联选择器 |
| Rate | string | true | 评分 |
| Row | string | true | 行 |
| Title | string | true | 自定义 Title,类似行 |
##### rules <Array> ##### rules <Array>
...@@ -107,14 +132,14 @@ Vue.use(WayViewForm) ...@@ -107,14 +132,14 @@ Vue.use(WayViewForm)
```js ```js
//默认使用label和value也可以通过设置showValue和showName修改keyName //默认使用label和value也可以通过设置showValue和showName修改keyName
[ [
({ ({
label: '是', label: "是",
value: true, value: true,
}, },
{ {
label: '否', label: "否",
value: false, value: false,
}), }),
]; ];
``` ```
...@@ -303,5 +328,5 @@ getDevices() { ...@@ -303,5 +328,5 @@ getDevices() {
## Feature ## Feature
- [x] 抽离请求方法,支持配置source的getMethod/移除getMapData、getBusinessData内置依赖; - [x] 抽离请求方法,支持配置 source 的 getMethod/移除 getMapData、getBusinessData 内置依赖;
- [x] 剔除老旧项目中的css fix样式移到项目中; - [x] 剔除老旧项目中的 css fix 样式移到项目中;
\ No newline at end of file
<template> <template>
<div class="SearchForm"> <div class="SearchForm">
<div class="demo-title demo-big">
way-view-form
</div>
<div class="demo-desc demo-big-desc">
基于 View UI(iview) 封装的 JSON To Form 表单组件,支持 Search 和 Form 两种模式
</div>
<div class="demo-title">
查询模式
</div>
<div class="demo-desc">
查询模式用户table的表头查询,或者页面的查询
</div>
<div class="demo-box">
<SearchForm />
</div>
<div class="demo-title"> <div class="demo-title">
查询模式 查询模式-单项反馈
</div> </div>
<div class="demo-box"> <div class="demo-desc">
<SearchForm /> 如果不希望错误的选项框标红可以通过css修改覆盖,这里提供了一个简单的示例
</div> </div>
<div class="demo-box">
<div class="demo-title"> <StepForm />
表单模式 </div>
</div> <div class="demo-title">
<div class="demo-box"> 表单模式
<BaseForm /> </div>
</div> <div class="demo-desc">
通用表单模式,常用于业务表单
</div>
<div class="demo-box">
<BaseForm />
</div>
<div class="demo-title">
表单模式-分栏
</div>
<div class="demo-desc">
分栏模式下,label最好隐藏或者设置为顶部,否则会出现错位;分栏模式可以自定义表单项的分栏宽度
</div>
<div class="demo-box">
<ColForm />
</div>
<div class="demo-title">
配置异步请求数据
</div>
<div class="demo-desc">
在main.js注册组件时同步配置全局请求方法,配合formItem的source(api/params/handle)属性可以实现异步数据的获取
</div>
<div class="demo-box">
<AsyncForm />
</div>
</div> </div>
</template> </template>
<script> <script>
import SearchForm from './demo/form.vue'; import SearchForm from './demo/form.vue';
import BaseForm from './demo/form2.vue'; import BaseForm from './demo/form2.vue';
import ColForm from './demo/form3.vue';
import StepForm from './demo/form1.vue';
import AsyncForm from './demo/form5.vue';
export default { export default {
data() { data() {
return { return {
...@@ -83,7 +124,10 @@ export default { ...@@ -83,7 +124,10 @@ export default {
}, },
components: { components: {
SearchForm, SearchForm,
BaseForm BaseForm,
ColForm,
StepForm,
AsyncForm
}, },
methods: { methods: {
...@@ -98,9 +142,21 @@ export default { ...@@ -98,9 +142,21 @@ export default {
.SearchForm { .SearchForm {
padding: 24px; padding: 24px;
margin: 0 auto; margin: 0 auto;
max-width: 900px; max-width: 1000px;
}
.demo-big-desc {
font-size: 18px;
}
.demo-big-title {
font-size: 24px;
font-weight: 600;
margin-bottom: 20px;
margin-top: 25px;
} }
.demo-title { .demo-title {
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
...@@ -108,6 +164,15 @@ export default { ...@@ -108,6 +164,15 @@ export default {
margin-top: 25px; margin-top: 25px;
} }
.demo-big {
font-size: 30px;
}
.demo-desc {
margin-bottom: 20px;
color: #999;
}
.demo-box { .demo-box {
margin-bottom: 20px; margin-bottom: 20px;
padding: 20px; padding: 20px;
...@@ -124,9 +189,6 @@ export default { ...@@ -124,9 +189,6 @@ export default {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
/* 元素换行 */ /* 元素换行 */
margin-bottom: 20px; margin-bottom: 20px;
} }
</style> </style>
\ No newline at end of file
...@@ -26,13 +26,6 @@ const hasOwnPropertySafely = (obj, key) => { ...@@ -26,13 +26,6 @@ const hasOwnPropertySafely = (obj, key) => {
export default { export default {
name: 'way-view-form', name: 'way-view-form',
props: { props: {
requestMethods: {
type: Object,
default: () => {
return {
}
}
},
// 模式 默认form表单模式 search为搜索条模式 // 模式 默认form表单模式 search为搜索条模式
model: { model: {
type: String, type: String,
...@@ -132,7 +125,6 @@ export default { ...@@ -132,7 +125,6 @@ export default {
}, },
render(h) { render(h) {
const self = this const self = this
if (Object.keys(this.formValues).length == 0 && this.enableSpin) return h('Spin', { if (Object.keys(this.formValues).length == 0 && this.enableSpin) return h('Spin', {
props: { props: {
...@@ -216,6 +208,7 @@ export default { ...@@ -216,6 +208,7 @@ export default {
*/ */
collectFormContent(data = []) { collectFormContent(data = []) {
console.log('data')
let res = { let res = {
formContent: [], formContent: [],
formData: {}, formData: {},
...@@ -252,8 +245,8 @@ export default { ...@@ -252,8 +245,8 @@ export default {
} }
// 如果设置了source自动生成请求 // 如果设置了source自动生成请求
if (hasOwnPropertySafely(item, 'source') && hasOwnPropertySafely(item, 'api') && hasOwnPropertySafely(item, 'key') && hasOwnPropertySafely(this.requestMethods, 'getMapData') && hasOwnPropertySafely(this.requestMethods, 'getBusinessData')) { if (hasOwnPropertySafely(item, 'source') && hasOwnPropertySafely(item.source, 'api') && hasOwnPropertySafely(item, 'key')) {
res.requests[item.key] = this.generatorRequestFunc(item, item.source.type) res.requests[item.key] = this.generatorRequestFunc(item)
} }
// 如果设置了source自动设置传入静态数据源 // 如果设置了source自动设置传入静态数据源
...@@ -267,19 +260,17 @@ export default { ...@@ -267,19 +260,17 @@ export default {
item.placeholder = (inputTips.includes(item.type) ? '请填写' : '请选择') + item.name item.placeholder = (inputTips.includes(item.type) ? '请填写' : '请选择') + item.name
} }
// 剪除source属性,初始化之后不再允许通过修改source属性来修改数据源,因为source属性是用来生成请求的且只能生成一次,如需调整指定数据源,可以通过修改source.data属性来实现或者通过内部方法changeSource手动实现
let mItem = Object.assign({}, item)
if (hasOwnPropertySafely(mItem, 'source')) {
delete mItem.source
}
if (item.type == 'Row' && hasOwnPropertySafely(item, 'children') && item.children.length > 0) { if (item.type == 'Row' && hasOwnPropertySafely(item, 'children') && item.children.length > 0) {
let cRes = this.collectFormContent(item.children) let cRes = this.collectFormContent(item.children)
res.rules = Object.assign(res.rules, cRes.rules) res.rules = Object.assign(res.rules, cRes.rules)
res.formData = Object.assign(res.formData, cRes.formData) res.formData = Object.assign(res.formData, cRes.formData)
res.requests = Object.assign(res.requests, cRes.requests) res.requests = Object.assign(res.requests, cRes.requests)
res.formContent = Object.assign(res.formContent, cRes.formContent) mItem.children = cRes.formContent
}
// 剪除source属性,初始化之后不再允许通过修改source属性来修改数据源,因为source属性是用来生成请求的且只能生成一次,如需调整指定数据源,可以通过修改source.data属性来实现或者通过内部方法changeSource手动实现
let mItem = Object.assign({}, item)
if (hasOwnPropertySafely(mItem, 'source')) {
delete mItem.source
} }
res.formContent.push(mItem) res.formContent.push(mItem)
}) })
...@@ -381,7 +372,7 @@ export default { ...@@ -381,7 +372,7 @@ export default {
}, },
generatorCol(h, item) { generatorCol(h, item) {
const colProps = item.layout && item.layout.col ? item.layout.col : {} const colProps = item.colProps ? item.colProps : {}
let layout = h( let layout = h(
'Col', 'Col',
{ {
...@@ -391,7 +382,7 @@ export default { ...@@ -391,7 +382,7 @@ export default {
xs: 12, xs: 12,
sm: 12, sm: 12,
md: 12, md: 12,
lg: 4, lg: 6,
...colProps ...colProps
}, },
}, },
...@@ -441,17 +432,16 @@ export default { ...@@ -441,17 +432,16 @@ export default {
res.push(this.generatorRow(h, item)) res.push(this.generatorRow(h, item))
break; break;
case 'Title': case 'Title':
// let title =
res.push(this.generatorTitle(h, item)) res.push(this.generatorTitle(h, item))
break; break;
default: default:
break; break;
} }
} else { // 理论不会走到这里,默认传入的表单配置根节点类型必须为Row,如果要兼容不穿Row节点的情况,需要在这里处理,包装一个Row节点 } else { //默认传入的表单配置根节点类型必须为Row,如果要兼容不穿Row节点的情况,需要在这里处理,包装一个Row节点
if ((hasOwnPropertySafely(item, 'visitable') && item.visitable(this.status, this.formValues)) || !hasOwnPropertySafely(item, 'visitable')) { if ((hasOwnPropertySafely(item, 'visitable') && item.visitable(this.status, this.formValues)) || !hasOwnPropertySafely(item, 'visitable')) {
let formItem = this.inlineBlock ? this.generatorInlineBlock(h, item) : this.generatorBlock(h, item) let formItem = this.inlineBlock ? this.generatorInlineBlock(h, item) : this.generatorBlock(h, item)
res.push(formItem) res.push(formItem)
// this.generatorCol(h, item)
} }
} }
...@@ -687,15 +677,19 @@ export default { ...@@ -687,15 +677,19 @@ export default {
} }
} }
}, },
generatorRequestFunc(item, funcType = 'business') { generatorRequestFunc(item) {
const { getBusinessData, getMapData } = this.requestMethods const requestType = item.source.requestType || 'request'
if (!this.$wayViewForm) return console.error('请在Vue实例上挂载$wayViewForm对象,并配置request方法')
if (!this.$wayViewForm[requestType]) return console.error(`请在$wayViewForm对象上配置‘${requestType}’方法`)
const request = this.$wayViewForm[requestType]
const $this = this; const $this = this;
let source = item.source; let source = item.source;
// 返回一个函数,这个函数将作为网络请求函数 // 返回一个函数,这个函数将作为网络请求函数
return async function () { return async function () {
try { try {
const { api, params, handle } = source; const { api, params, handle } = source;
const res = await (funcType === 'business' ? getBusinessData($this.$store.getters.ServiceUrls[api], params) : getMapData(api)); const res = await request(api, params);
// 将请求到的数据赋值给sourceData // 将请求到的数据赋值给sourceData
$this.sourceData[item.key] = handle ? handle(res) : res.page.list; $this.sourceData[item.key] = handle ? handle(res) : res.page.list;
return res; return res;
......
<template>
<way-view-form singleStepErrorTip model="search" inlineBlock :formProps="formProps" ref="queryForm" :form="originData"
@submit="handleSubmit" :enableSpin="false" :action="['submit', 'reset']" @reset="handleReset"
:actionProps="actionProps" :showFooter="false" />
</template>
<script>
export default {
name: 'SearchForm',
data() {
return {
formProps: {
hideLabel: true,
inline: true,
},
originData: [
{
name: '姓名',
required: true,
type: 'Input',
key: 'name',
value: '',
},
{
name: '工种',
type: 'Select',
key: 'type',
required: true,
componentsProps: {
clearable: true
},
source: {
data: [
{
name: '1',
id: '1'
},
{
name: '2',
id: '2'
},
{
name: '3',
id: '3'
},
],
},
showName: 'name',
showValue: 'id',
},
],
actionProps: {
submit: {
componentsProps: {
type: 'primary',
icon: 'md-search',
},
text: '查询'
},
reset: {
componentsProps: {
type: 'default',
icon: 'md-refresh',
},
text: '重置'
},
},
};
},
methods: {
handleSubmit(formData) {
if (!formData.formValues.name && !formData.formValues.type) return
this.$emit('handleSearch', formData.formValues)
},
handleReset() {
this.$emit('handleSearch', {})
},
},
watch: {
}
}
</script>
<style lang='less' scoped>
.SearchForm {
padding: 24px;
}
.demo-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 20px;
}
</style>
\ No newline at end of file
...@@ -46,8 +46,10 @@ ...@@ -46,8 +46,10 @@
<script> <script>
import LabelItem from './label-item.vue' import LabelItem from './label-item.vue'
let data1 = []
let targetKeys1 = []
export default { export default {
name: 'SearchForm', name: 'page-Form',
components: { components: {
LabelItem LabelItem
}, },
...@@ -63,7 +65,7 @@ export default { ...@@ -63,7 +65,7 @@ export default {
hideRequiredMark: false, hideRequiredMark: false,
labelColon: true, labelColon: true,
labelPosition: 'left', labelPosition: 'left',
labelWidth: 100, labelWidth: 120,
}, },
originData: [ originData: [
...@@ -141,6 +143,191 @@ export default { ...@@ -141,6 +143,191 @@ export default {
pattern: /^[1-9]\d*$/ pattern: /^[1-9]\d*$/
}] }]
}, },
{
name: '复选框',
type: 'CheckboxGroup',
key: 'visable2',
required: true,
source: {
data: [
{
label: '1',
value: '1'
},
{
label: '2',
value: '2'
},
{
label: '3',
value: '3'
},
],
},
},
{
name: '单选框',
type: 'RadioGroup',
required: true,
key: 'visable2RadioGroup',
source: {
data: [
{
label: '1',
value: '1'
},
{
label: '2',
value: '2'
},
{
label: '3',
value: '3'
},
],
},
},
{
name: '下拉菜单分组',
type: 'Select',
key: 'type2',
required: true,
componentsProps: {
clearable: true
},
custom: { group: true },
source: {
data: {
'分组1': [
{
name: '1',
id: '1'
},
{
name: '2',
id: '2'
},
{
name: '3',
id: '3'
},
],
'分组2': [
{
name: '4',
id: '4'
},
{
name: '5',
id: '5'
},
{
name: '6',
id: '6'
},
],
}
},
showName: 'name',
showValue: 'id',
},
{
name: 'datetime',
required: true,
type: 'DatePicker',
key: 'datetime',
componentsProps: {
type: "datetime"
},
},
{
name: 'datetimerange',
required: true,
requiredType: 'array',
type: 'DatePicker',
key: 'datetimerange',
componentsProps: {
type: "datetimerange"
},
},
{
name: 'TimePicker',
required: true,
type: 'TimePicker',
key: 'TimePicker',
componentsProps: {
type: "time"
},
},
{
name: 'Cascader',
required: true,
type: 'Cascader',
key: 'Cascader',
componentsProps: {
data: [{
value: 'beijing',
label: '北京',
children: [
{
value: 'gugong',
label: '故宫'
},
{
value: 'tiantan',
label: '天坛'
},
{
value: 'wangfujing',
label: '王府井'
}
]
}, {
value: 'jiangsu',
label: '江苏',
children: [
{
value: 'nanjing',
label: '南京',
children: [
{
value: 'fuzimiao',
label: '夫子庙',
}
]
},
{
value: 'suzhou',
label: '苏州',
children: [
{
value: 'zhuozhengyuan',
label: '拙政园',
},
{
value: 'shizilin',
label: '狮子林',
}
]
}
],
}]
},
},
{
name: 'Transfer',
required: true,
type: 'Transfer',
key: 'Transfer',
componentsProps: {
data: data1,
renderFormat: this.render1,
targetKeys: targetKeys1
},
componentEvents: {
'on-change': this.handleChange1
}
},
], ],
actionProps: { actionProps: {
submit: { submit: {
...@@ -158,13 +345,25 @@ export default { ...@@ -158,13 +345,25 @@ export default {
text: '重置' text: '重置'
}, },
}, },
// 测试数据
data1: this.getMockData(),
targetKeys1: this.getTargetKeys()
}; };
}, },
beforeMount() {
console.log(this.getTargetKeys())
},
created() {
console.log()
},
mounted() {
},
methods: { methods: {
handleSubmit(formData) { handleSubmit(formData) {
console.log(formData) console.log(formData)
if (!formData.formValues.name && !formData.formValues.type) return this.$Message.warning('请输入搜索项,再搜索!') if (!formData.formValues.name && !formData.formValues.type) return this.$Message.error('请完善表单')
this.$emit('handleSearch', formData.formValues) this.$emit('handleSearch', formData.formValues)
}, },
handleReset() { handleReset() {
...@@ -185,6 +384,32 @@ export default { ...@@ -185,6 +384,32 @@ export default {
id: '6' id: '6'
}, },
] ]
},
getMockData() {
let mockData = [];
for (let i = 1; i <= 20; i++) {
mockData.push({
key: i.toString(),
label: 'Content ' + i,
description: 'The desc of content ' + i,
disabled: Math.random() * 3 < 1
});
}
return mockData;
},
getTargetKeys() {
return this.getMockData()
.filter(() => Math.random() * 2 > 1)
.map(item => item.key);
},
render1(item) {
return item.label;
},
handleChange1(newTargetKeys, direction, moveKeys) {
console.log(newTargetKeys);
console.log(direction);
console.log(moveKeys);
this.targetKeys1 = newTargetKeys;
} }
}, },
watch: { watch: {
......
<template>
<div>
<!-- <div class="opation">
<label-item title="行内换行模式">
<i-switch v-model="formProps.inline" />
</label-item>
<label-item title="隐藏标签" tips="隐藏标签时默认标签位置为顶部">
<i-switch v-model="formProps.hideLabel" />
</label-item>
<label-item title="禁用">
<i-switch v-model="formProps.disabled" />
</label-item>
<label-item title="隐藏必填标记">
<i-switch v-model="formProps.hideRequiredMark" />
</label-item>
<label-item title="标签后冒号">
<i-switch v-model="formProps.labelColon" />
</label-item>
<label-item title="标签位置">
<i-select v-model="formProps.labelPosition" style="width: 120px">
<i-option value="left"></i-option>
<i-option value="right"></i-option>
<i-option value="top"></i-option>
</i-select>
</label-item>
<label-item title="spin">
<i-switch v-model="spin" />
</label-item>
<label-item title="展示底部" tips="隐藏之后可以通过自定义操作按钮通过ref手动调用方法">
<i-switch v-model="showFooter" />
</label-item>
<label-item title="inlineBlock"
tips="该属性用于定义行内换行模式。如果设置为 true,则表单控件会在同一行中显示,并根据内容自动换行。如果设置为 false,则表单控件会分行显示。 ">
<i-switch v-model="inlineBlock" />
</label-item>
<label-item title="动态修改工种数据源"
tips="静态数据可以通过更改form数据来完成,如果是使用source配置的请求方法,可以通过 this.$refs.queryForm.updateSources('key')来重新获取">
<Button @click="changeSource">修改数据源</Button>
</label-item>
</div> -->
<way-view-form model="form" :inlineBlock="inlineBlock" :formProps="formProps" ref="queryForm" :form="originData"
@submit="handleSubmit" :enableSpin="spin" :action="['submit', 'reset']" @reset="handleReset"
:actionProps="actionProps" :showFooter="showFooter" />
</div>
</template>
<script>
// import LabelItem from './label-item.vue'
export default {
name: 'col-Form',
components: {
// LabelItem
},
data() {
return {
spin: false,
showFooter: true,
inlineBlock: true,
formProps: {
hideLabel: false,
inline: false,
disabled: false,
hideRequiredMark: false,
labelColon: true,
labelPosition: 'top',
labelWidth: 100,
},
originData: [
{
type: 'Title',
name: '查询条件',
},
{
type: 'Row',
props: {
gutter: 20,
},
children: [
{
name: '姓名',
required: true,
type: 'Input',
key: 'name',
value: '',
},
{
name: '隐藏字段',
hidden: true,
key: 'id',
value: '',
},
{
name: '年龄',
required: true,
type: 'InputNumber',
key: 'age',
value: 1,// 初始
},
{
name: '工种',
type: 'Select',
key: 'type',
required: true,
componentsProps: {
clearable: true
},
source: {
data: [
{
name: '1',
id: '1'
},
{
name: '2',
id: '2'
},
{
name: '3',
id: '3'
},
],
},
showName: 'name',
showValue: 'id',
},
{
name: '条件显隐字段',
type: 'i-switch',
key: 'visable',
value: false,// 初始
},
{
name: '自定义校验',
required: true,
placeholder: '请输入正整数',
type: 'InputNumber',
key: 'batchCount',
componentsProps: {
min: 1,
},
colProps: {
xs: 24,
sm: 24,
md: 24,
lg: 24,
},
value: 1,// 初始
visitable: (status, form) => {
// form 为表单数据
return form.visable
},
rules: [{
required: true,
message: '请输入正整数',
trigger: ['change'],
pattern: /^[1-9]\d*$/
}]
},]
},
],
actionProps: {
submit: {
componentsProps: {
type: 'primary',
icon: 'md-search',
},
text: '查询'
},
reset: {
componentsProps: {
type: 'default',
icon: 'md-refresh',
},
text: '重置'
},
},
};
},
methods: {
handleSubmit(formData) {
console.log(formData)
if (!formData.formValues.name && !formData.formValues.type) return this.$Message.error('请完善表单')
this.$emit('handleSearch', formData.formValues)
},
handleReset() {
this.$emit('handleSearch', {})
},
changeSource() {
this.originData[3].source.data = [
{
name: '4',
id: '4'
},
{
name: '5',
id: '5'
},
{
name: '6',
id: '6'
},
]
}
},
watch: {
}
}
</script>
<template>
<div>
<!-- <div class="opation">
<label-item title="行内换行模式">
<i-switch v-model="formProps.inline" />
</label-item>
<label-item title="隐藏标签" tips="隐藏标签时默认标签位置为顶部">
<i-switch v-model="formProps.hideLabel" />
</label-item>
<label-item title="禁用">
<i-switch v-model="formProps.disabled" />
</label-item>
<label-item title="隐藏必填标记">
<i-switch v-model="formProps.hideRequiredMark" />
</label-item>
<label-item title="标签后冒号">
<i-switch v-model="formProps.labelColon" />
</label-item>
<label-item title="标签位置">
<i-select v-model="formProps.labelPosition" style="width: 120px">
<i-option value="left"></i-option>
<i-option value="right"></i-option>
<i-option value="top"></i-option>
</i-select>
</label-item>
<label-item title="spin">
<i-switch v-model="spin" />
</label-item>
<label-item title="展示底部" tips="隐藏之后可以通过自定义操作按钮通过ref手动调用方法">
<i-switch v-model="showFooter" />
</label-item>
<label-item title="inlineBlock"
tips="该属性用于定义行内换行模式。如果设置为 true,则表单控件会在同一行中显示,并根据内容自动换行。如果设置为 false,则表单控件会分行显示。 ">
<i-switch v-model="inlineBlock" />
</label-item>
<label-item title="动态修改工种数据源"
tips="静态数据可以通过更改form数据来完成,如果是使用source配置的请求方法,可以通过 this.$refs.queryForm.updateSources('key')来重新获取">
<Button @click="changeSource">修改数据源</Button>
</label-item>
</div> -->
<way-view-form model="form" :inlineBlock="inlineBlock" :formProps="formProps" ref="queryForm" :form="originData"
@submit="handleSubmit" :enableSpin="spin" :action="['submit', 'reset']" @reset="handleReset"
:actionProps="actionProps" :showFooter="showFooter" />
</div>
</template>
<script>
// import LabelItem from './label-item.vue'
export default {
name: 'col-Form',
components: {
// LabelItem
},
data() {
return {
spin: false,
showFooter: true,
inlineBlock: true,
formProps: {
hideLabel: false,
inline: false,
disabled: false,
hideRequiredMark: false,
labelColon: true,
labelPosition: 'top',
labelWidth: 100,
},
originData: [
{
type: 'Title',
name: '查询条件',
},
{
type: 'Row',
props: {
gutter: 20,
},
children: [
{
name: '姓名',
required: true,
type: 'Input',
key: 'name',
value: '',
},
{
name: '隐藏字段',
hidden: true,
key: 'id',
value: '',
},
{
name: '年龄',
required: true,
type: 'InputNumber',
key: 'age',
value: 1,// 初始
},
{
name: '工种',
type: 'Select',
key: 'type',
required: true,
requiredType: 'number',//设置校验类型
componentsProps: {
clearable: true
},
source: {
api: '/api/waybill/waybillTypeList', // 模拟
params: {
type: '1',
limit: 100,
},
handle: (res) => {
return res
}
},
showName: 'name',
showValue: 'id',
},
{
name: '条件显隐字段',
type: 'i-switch',
key: 'visable',
value: false,// 初始
},
{
name: '自定义校验',
required: true,
placeholder: '请输入正整数',
type: 'InputNumber',
key: 'batchCount',
componentsProps: {
min: 1,
},
colProps: {
xs: 24,
sm: 24,
md: 24,
lg: 24,
},
value: 1,// 初始
visitable: (status, form) => {
// form 为表单数据
return form.visable
},
rules: [{
required: true,
message: '请输入正整数',
trigger: ['change'],
pattern: /^[1-9]\d*$/
}]
},]
},
],
actionProps: {
submit: {
componentsProps: {
type: 'primary',
icon: 'md-search',
},
text: '查询'
},
reset: {
componentsProps: {
type: 'default',
icon: 'md-refresh',
},
text: '重置'
},
},
};
},
methods: {
handleSubmit(formData) {
if (!formData.formValues.name && !formData.formValues.type) return this.$Message.error('请完善表单')
this.$emit('handleSearch', formData.formValues)
},
handleReset() {
this.$emit('handleSearch', {})
},
changeSource() {
this.originData[3].source.data = [
{
name: '4',
id: '4'
},
{
name: '5',
id: '5'
},
{
name: '6',
id: '6'
},
]
},
simulateAPIRequest() {
return new Promise((resolve) => {
setTimeout(() => {
const response = [{
name: '4',
id: '4'
},
{
name: '5',
id: '5'
},
{
name: '6',
id: '6'
},];
resolve(response);
}, 2000); // 模拟异步请求延迟,2秒后返回数据
});
}
},
watch: {
}
}
</script>
import WayViewForm from "./components/index.vue"; import WayViewForm from "./components/index.vue";
// 导出组件 // 导出组件
WayViewForm.install = (Vue) => { WayViewForm.install = (Vue, func) => {
if (typeof window !== "undefined" && window.Vue) {
Vue = window.Vue;
}
if (func && typeof func === "function") {
Vue.prototype.$wayViewForm = {
request: func,
};
} else if (func && typeof func === "object") {
Vue.prototype.$wayViewForm = func;
}
Vue.component(WayViewForm.name, WayViewForm); Vue.component(WayViewForm.name, WayViewForm);
}; };
export default WayViewForm; export default WayViewForm;
...@@ -4,9 +4,36 @@ import WayViewForm from "./index"; ...@@ -4,9 +4,36 @@ import WayViewForm from "./index";
import ViewUI from "view-design"; import ViewUI from "view-design";
import "view-design/dist/styles/iview.css"; import "view-design/dist/styles/iview.css";
Vue.use(ViewUI); Vue.use(ViewUI);
Vue.use(WayViewForm); // eslint-disable-next-line no-unused-vars
function request(url, params) {
return new Promise((resolve) => {
setTimeout(() => {
resolve([
{
name: "张三",
age: 18,
id: 1,
},
{
name: "李四",
age: 19,
id: 2,
},
{
name: "王五",
age: 20,
id: 3,
},
]);
}, 1000);
});
}
// 注入请求方法
// request方法必须返回一个Promise对象 request(url, params) url为请求地址,params为请求参数
// key值'request'作为默认请求方法,如果需要额外的请求方法,可以在这里新增key例如 get:func 在formItem source配置requestType:'get'
Vue.use(WayViewForm, { request: request });
Vue.config.productionTip = false; Vue.config.productionTip = false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment