Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
U
uview-ui
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
李晖
uview-ui
Commits
21a28559
Commit
21a28559
authored
May 27, 2020
by
wlxuqu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
基本完成form表单组件
parent
c33b937d
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
295 additions
and
30 deletions
+295
-30
pages.json
pages.json
+15
-8
index.vue
pages/componentsA/field/index.vue
+1
-1
index.vue
pages/componentsA/form/index.vue
+60
-0
u-form-item.vue
uview-ui/components/u-form-item/u-form-item.vue
+120
-9
u-form.vue
uview-ui/components/u-form/u-form.vue
+39
-9
u-icon.vue
uview-ui/components/u-icon/u-icon.vue
+1
-1
u-input.vue
uview-ui/components/u-input/u-input.vue
+57
-0
u-message-input.vue
uview-ui/components/u-message-input/u-message-input.vue
+2
-2
No files found.
pages.json
View file @
21a28559
...
@@ -2,14 +2,14 @@
...
@@ -2,14 +2,14 @@
"easycom"
:
{
"easycom"
:
{
"^u-(.*)"
:
"@/uview-ui/components/u-$1/u-$1.vue"
"^u-(.*)"
:
"@/uview-ui/components/u-$1/u-$1.vue"
},
},
//
"condition"
:
{
//模式配置,仅开发期间生效
"condition"
:
{
//模式配置,仅开发期间生效
//
"current"
:
0
,
//当前激活的模式(list
的索引项)
"current"
:
0
,
//当前激活的模式(list
的索引项)
//
"list"
:
[{
"list"
:
[{
//
"name"
:
"test"
,
//模式名称
"name"
:
"test"
,
//模式名称
//
"path"
:
"pages/componentsC/grid
/index"
,
//启动页面,必选
"path"
:
"pages/componentsA/form
/index"
,
//启动页面,必选
//
"query"
:
"id=1&name=2"
//启动参数,在页面的-+
onLoad函数里面得到
"query"
:
"id=1&name=2"
//启动参数,在页面的
onLoad函数里面得到
//
}]
}]
//
},
},
"pages"
:
[
"pages"
:
[
//
演示-组件
//
演示-组件
{
{
...
@@ -450,6 +450,13 @@
...
@@ -450,6 +450,13 @@
{
{
"root"
:
"pages/componentsA"
,
"root"
:
"pages/componentsA"
,
"pages"
:
[
"pages"
:
[
//
form-表单
{
"path"
:
"form/index"
,
"style"
:
{
"navigationBarTitleText"
:
"form-表单"
}
},
//
slider-滑动选择器
//
slider-滑动选择器
{
{
"path"
:
"slider/index"
,
"path"
:
"slider/index"
,
...
...
pages/componentsA/field/index.vue
View file @
21a28559
...
@@ -21,7 +21,7 @@
...
@@ -21,7 +21,7 @@
:required=
"required"
:required=
"required"
:icon=
"icon2"
:icon=
"icon2"
>
>
<u-button
v-if=
"showBtn"
slot=
"
button
"
size=
"mini"
type=
"success"
>
发送验证码
</u-button>
<u-button
v-if=
"showBtn"
slot=
"
right
"
size=
"mini"
type=
"success"
>
发送验证码
</u-button>
</u-field>
</u-field>
</u-cell-group>
</u-cell-group>
</view>
</view>
...
...
pages/componentsA/form/index.vue
0 → 100644
View file @
21a28559
<
template
>
<view
class=
""
>
<u-form
:model=
"model"
:rules=
"rules"
>
<u-form-item
:label=
"label"
prop=
"name"
>
<u-input
v-model=
"model.name"
/>
</u-form-item>
</u-form>
</view>
</
template
>
<
script
>
export
default
{
data
()
{
return
{
model
:
{
name
:
''
},
rules
:
{
name
:
[
{
required
:
true
,
message
:
'
请输入活动名称
'
,
trigger
:
'
change
'
},
{
min
:
3
,
max
:
5
,
message
:
'
长度在 3 到 5 个字符
'
,
trigger
:
'
change
'
}
]
},
label
:
'
name
'
};
},
computed
:
{
current
()
{
return
this
.
show
?
0
:
1
;
}
},
methods
:
{
showChange
(
index
)
{
this
.
show
=
!
index
;
},
titleChange
(
index
)
{
this
.
showTitle
=
!
index
;
this
.
show
=
true
;
},
contentChange
(
index
)
{
this
.
contentSlot
=
!
index
;
this
.
content
=
!
index
;
this
.
show
=
true
;
},
asyncChange
(
index
)
{
this
.
show
=
true
;
this
.
asyncClose
=
!
index
;
},
confirm
()
{
setTimeout
(()
=>
{
this
.
show
=
false
;
},
2000
)
}
}
};
</
script
>
<
style
scoped
lang=
"scss"
>
</
style
>
uview-ui/components/u-form-item/u-form-item.vue
View file @
21a28559
<
template
>
<
template
>
<view
class=
"u-form-item"
>
<view
class=
"u-form-item"
>
<view>
{{
label
}}
</view>
<view
class=
""
>
<slot
/>
<slot
/>
<view
:class=
"isRequired?'ai-form-item-label-required':''"
class=
"ai-form-item-message"
v-if=
"validateState==='error'"
>
{{
validateMessage
}}
</view>
</view>
</view>
</view>
</
template
>
</
template
>
<
script
>
<
script
>
export
default
{
import
Emitter
from
'
../../libs/util/emitter.js
'
;
import
schema
from
'
../../libs/util/async-validator
'
;
export
default
{
name
:
'
u-form-item
'
,
mixins
:
[
Emitter
],
inject
:
[
'
uForm
'
],
props
:
{
// input的label提示语
label
:
{
type
:
String
,
default
:
''
},
// 绑定的值
prop
:
{
type
:
String
,
default
:
''
}
},
data
()
{
data
()
{
return
{
return
{
initialValue
:
''
,
// 存储的默认值
isRequired
:
false
,
// 是否必填
validateState
:
''
,
// 是否校验成功
validateMessage
:
''
// 校验失败的提示语
};
},
computed
:
{
fieldValue
()
{
return
this
.
uForm
.
model
[
this
.
prop
];
}
}
},
},
methods
:
{
methods
:
{
// 判断是否需要required校验
setRules
()
{
let
that
=
this
;
// 从父组件u-form拿到当前u-form-item需要验证 的规则
let
rules
=
this
.
getRules
();
if
(
rules
.
length
)
{
this
.
isRequired
=
rules
.
some
(
rule
=>
{
// 如果有必填项,就返回,没有的话,就是undefined
return
rule
.
required
;
});
}
// blur事件
this
.
$on
(
'
on-form-blur
'
,
that
.
onFieldBlur
);
// change事件
this
.
$on
(
'
on-form-change
'
,
that
.
onFieldChange
);
},
// 从u-form的rules属性中,取出当前u-form-item的校验规则
getRules
()
{
// 父组件的所有规则
let
rules
=
this
.
uForm
.
rules
;
rules
=
rules
?
rules
[
this
.
prop
]
:
[];
// 保证返回的是一个数组形式
return
[].
concat
(
rules
||
[]);
},
// blur事件时进行表单校验
onFieldBlur
()
{
this
.
validation
(
'
blur
'
);
},
// change事件进行表单校验
onFieldChange
()
{
this
.
validation
(
'
change
'
);
},
// 过滤出符合要求的rule规则
getFilteredRule
(
trigger
)
{
let
rules
=
this
.
getRules
();
// 历遍判断规则是否有对应的事件,比如blur,change触发等的事件
return
rules
.
filter
(
res
=>
!
res
.
trigger
||
trigger
.
indexOf
(
trigger
)
!==
-
1
);
},
// 校验数据
validation
(
trigger
,
callback
=
()
=>
{})
{
// blur和change是否有当前方式的校验规则
let
rules
=
this
.
getFilteredRule
(
trigger
);
// 判断是否有验证规则
if
(
!
rules
||
rules
.
length
===
0
)
return
;
// 设置当前的装填,标识为校验中
this
.
validateState
=
'
validating
'
;
// 调用async-validator的方法
let
validator
=
new
schema
({
[
this
.
prop
]:
rules
});
validator
.
validate
({
[
this
.
prop
]:
this
.
fieldValue
},
{
firstFields
:
true
},
(
errors
,
fields
)
=>
{
// 记录状态和报错信息
this
.
validateState
=
!
errors
?
'
success
'
:
'
error
'
;
this
.
validateMessage
=
errors
?
errors
[
0
].
message
:
''
;
// 调用回调方法
callback
(
this
.
validateMessage
);
});
},
// 清空当前的u-form-item
resetField
()
{
this
.
uForm
.
model
[
this
.
prop
]
=
this
.
initialValue
;
}
}
},
// 组件创建完成时,将当前实例保存到u-form中
mounted
()
{
// 如果没有传入prop,就不进行校验
if
(
!
this
.
prop
)
return
;
// 发出事件,让父组件将本实例加入到管理数组中
this
.
dispatch
(
'
u-form
'
,
'
on-form-item-add
'
,
this
);
// 设置初始值
this
.
initialValue
=
this
.
fieldValue
;
// 添加表单校验
this
.
setRules
();
},
// 组件销毁前,将实例从 Form 的缓存中移除
beforeDestroy
()
{
this
.
dispatch
(
'
u-form
'
,
'
on-form-item-remove
'
,
this
);
}
}
};
</
script
>
</
script
>
<
style
>
<
style
></
style
>
</
style
>
uview-ui/components/u-form/u-form.vue
View file @
21a28559
...
@@ -10,14 +10,14 @@ export default {
...
@@ -10,14 +10,14 @@ export default {
model
:
{
model
:
{
type
:
Object
,
type
:
Object
,
default
()
{
default
()
{
return
{}
return
{}
;
}
}
},
},
// 验证规则
// 验证规则
rules
:
{
rules
:
{
type
:
Object
,
type
:
Object
,
default
()
{
default
()
{
return
{}
return
{}
;
}
}
}
}
},
},
...
@@ -28,28 +28,58 @@ export default {
...
@@ -28,28 +28,58 @@ export default {
},
},
data
()
{
data
()
{
return
{
return
{
// 存储当前form下的所有u-form的示例
fields
:
[]
};
};
},
},
created
()
{
created
()
{
// 存储当前form下的所有u-form-item的实例
// 不能定义在data中,否则微信小程序会造成循环引用而报错
this
.
fields
=
[];
// 存当前实例
// 存当前实例
let
that
=
this
;
let
that
=
this
;
// 监听on-form-item-add事件,将子组件添加到fields中
// 监听on-form-item-add事件,将子组件添加到fields中
this
.
$on
(
'
on-form-item-add
'
,
item
=>
{
this
.
$on
(
'
on-form-item-add
'
,
item
=>
{
if
(
item
)
{
if
(
item
)
{
that
.
fields
.
push
(
item
);
that
.
fields
.
push
(
item
);
}
}
});
});
// 删除当前有的实例
// 删除当前有的实例
this
.
$on
(
'
on-form-item-remove
'
,
item
=>
{
this
.
$on
(
'
on-form-item-remove
'
,
item
=>
{
// 如果当前没有prop的话表示当前不要进行删除(因为没有注入)
// 如果当前没有prop的话表示当前不要进行删除(因为没有注入)
if
(
item
.
prop
)
{
if
(
item
.
prop
)
{
that
.
fields
.
splice
(
that
.
fields
.
indexOf
(
item
),
1
);
that
.
fields
.
splice
(
that
.
fields
.
indexOf
(
item
),
1
);
}
}
});
},
methods
:
{
// 清空所有u-form-item组件的内容,本质上是调用了u-form-item组件中的resetField()方法
resetFields
()
{
this
.
fields
.
map
(
field
=>
{
field
.
resetField
();
})
})
},
},
methods
:
{}
// 校验全部数据
validate
(
callback
)
{
return
new
Promise
(
resolve
=>
{
// 对所有的u-form-item进行校验
let
valid
=
true
;
// 默认通过
let
count
=
0
;
// 用于标记是否检查完毕
this
.
fields
.
map
(
field
=>
{
// 调用每一个u-form-item实例的validation的校验方法
field
.
validation
(
''
,
error
=>
{
// 如果任意一个u-form-item校验不通过,就意味着整个表单不通过
if
(
error
)
valid
=
false
;
// 当历遍了所有的u-form-item时,调用promise的then方法
if
(
++
count
===
this
.
fields
.
length
)
{
resolve
(
valid
);
// 进入promise的then方法
// 调用回调方法
if
(
typeof
callback
==
'
function
'
)
callback
(
valid
);
}
})
})
})
}
}
};
};
</
script
>
</
script
>
...
...
uview-ui/components/u-icon/u-icon.vue
View file @
21a28559
<
template
>
<
template
>
<view
class=
"u-icon"
:class=
"[labelPos == 'bottom' ? 'u-flex-col u-row-center' : 'u-flex u-col-center']"
>
<view
class=
"u-icon"
:class=
"[labelPos == 'bottom' ? 'u-flex-col u-row-center' : 'u-flex u-col-center']"
>
<text
class=
"u-icon__icon"
:class=
"customClass"
:style=
"[iconStyle]"
@
tap.stop
=
"click"
:hover-class=
"hoverClass"
@
touchstart.stop
=
"touchstart"
></text>
<text
class=
"u-icon__icon"
:class=
"customClass"
:style=
"[iconStyle]"
@
tap.stop
.prevent=
"click"
:hover-class=
"hoverClass"
@
touchstart.stop.prevent
=
"touchstart"
></text>
<text
v-if=
"label"
class=
"u-icon__label"
:style=
"
{
<text
v-if=
"label"
class=
"u-icon__label"
:style=
"
{
color: labelColor,
color: labelColor,
fontSize: labelSize + 'rpx',
fontSize: labelSize + 'rpx',
...
...
uview-ui/components/u-input/u-input.vue
0 → 100644
View file @
21a28559
<
template
>
<input
type=
"text"
@
input=
"handleInput"
@
blur=
"handleBlur"
:value=
"defaultValue"
/>
</
template
>
<
script
>
import
Emitter
from
'
../../libs/util/emitter.js
'
;
export
default
{
name
:
'
u-input
'
,
mixins
:
[
Emitter
],
props
:
{
value
:
{
type
:
String
,
default
:
'
1234
'
}
},
data
()
{
return
{
defaultValue
:
this
.
value
};
},
watch
:
{
value
(
val
)
{
this
.
defaultValue
=
val
;
}
},
methods
:
{
/**
* change 事件
* @param event
*/
handleInput
(
event
)
{
// 当前model 赋值
this
.
defaultValue
=
event
.
detail
.
value
;
// vue 原生的方法 return 出去
this
.
$emit
(
'
input
'
,
event
.
detail
.
value
);
// 过一个生命周期再发送事件给u-form-item,否则this.$emit('input')更新了父组件的值,但是微信小程序上
// 尚未更新到u-form-item,导致获取的值为空,从而校验混论
this
.
$nextTick
(()
=>
{
// 将当前的值发送到 u-form-item 进行校验
this
.
dispatch
(
'
u-form-item
'
,
'
on-form-change
'
,
event
.
detail
.
value
);
})
},
/**
* blur 事件
* @param event
*/
handleBlur
(
event
)
{
// vue 原生的方法 return 出去
this
.
$emit
(
'
blur
'
,
event
.
detail
.
value
);
this
.
$nextTick
(()
=>
{
// 将当前的值发送到 u-form-item 进行校验
this
.
dispatch
(
'
u-form-item
'
,
'
on-form-blur
'
,
event
.
detail
.
value
);
})
}
}
};
</
script
>
uview-ui/components/u-message-input/u-message-input.vue
View file @
21a28559
...
@@ -203,8 +203,8 @@
...
@@ -203,8 +203,8 @@
.u-input
{
.u-input
{
position
:
absolute
;
position
:
absolute
;
top
:
0
;
top
:
0
;
left
:
0
;
left
:
-100%
;
width
:
1
00%
;
width
:
2
00%
;
height
:
100%
;
height
:
100%
;
text-align
:
left
;
text-align
:
left
;
z-index
:
9
;
z-index
:
9
;
...
...
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