Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
way-view-form
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
刘子康
way-view-form
Commits
f352f3c3
Commit
f352f3c3
authored
Jun 05, 2023
by
刘子康
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加demo/剔除业务定义代码改为更加通用的方式置入请求方法
parent
882fccf4
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
973 additions
and
82 deletions
+973
-82
README.md
README.md
+54
-30
App.vue
src/App.vue
+81
-20
index.vue
src/components/index.vue
+20
-26
form1.vue
src/demo/form1.vue
+99
-0
form2.vue
src/demo/form2.vue
+228
-3
form3.vue
src/demo/form3.vue
+219
-0
form5.vue
src/demo/form5.vue
+232
-0
index.js
src/index.js
+11
-1
main.js
src/main.js
+29
-2
No files found.
README.md
View file @
f352f3c3
# 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
src/App.vue
View file @
f352f3c3
<
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
src/components/index.vue
View file @
f352f3c3
...
@@ -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
;
...
...
src/demo/form1.vue
0 → 100644
View file @
f352f3c3
<
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
src/demo/form2.vue
View file @
f352f3c3
...
@@ -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
:
'
Search
Form'
,
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
:
1
0
0
,
labelWidth
:
1
2
0
,
},
},
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
:
{
...
...
src/demo/form3.vue
0 → 100644
View file @
f352f3c3
<
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
>
src/demo/form5.vue
0 → 100644
View file @
f352f3c3
<
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
>
src/index.js
View file @
f352f3c3
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
;
src/main.js
View file @
f352f3c3
...
@@ -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
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment