Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
uni-app
提交
70941b8e
U
uni-app
项目概览
DCloud
/
uni-app
2 个月 前同步成功
通知
717
Star
38705
Fork
3642
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
7
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
7
Issue
7
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
70941b8e
编写于
10月 11, 2019
作者:
Q
qiang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor: 重构H5端picker
上级
e4c0e281
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
571 addition
and
758 deletion
+571
-758
src/core/helpers/tags.js
src/core/helpers/tags.js
+0
-1
src/core/view/components/picker/index.vue
src/core/view/components/picker/index.vue
+0
-229
src/platforms/h5/components/app/index.vue
src/platforms/h5/components/app/index.vue
+3
-7
src/platforms/h5/components/app/popup/index.js
src/platforms/h5/components/app/popup/index.js
+1
-3
src/platforms/h5/components/app/popup/mixins/picker.js
src/platforms/h5/components/app/popup/mixins/picker.js
+0
-50
src/platforms/h5/view/components/picker/index.vue
src/platforms/h5/view/components/picker/index.vue
+567
-468
未找到文件。
src/core/helpers/tags.js
浏览文件 @
70941b8e
...
...
@@ -8,7 +8,6 @@ module.exports = [
'
uni-page-refresh
'
,
'
uni-actionsheet
'
,
'
uni-modal
'
,
'
uni-picker
'
,
'
uni-toast
'
,
'
uni-resize-sensor
'
,
...
...
src/core/view/components/picker/index.vue
已删除
100644 → 0
浏览文件 @
e4c0e281
<
template
>
<uni-picker
@
click.stop=
"_click"
>
<div>
<slot/>
</div>
</uni-picker>
</
template
>
<
script
>
import
{
emitter
}
from
'
uni-mixins
'
const
{
subscribe
,
unsubscribe
,
publishHandler
}
=
UniViewJSBridge
const
mode
=
{
SELECTOR
:
'
selector
'
,
MULTISELECTOR
:
'
multiSelector
'
,
TIME
:
'
time
'
,
DATE
:
'
date
'
// 暂不支持城市选择
// REGION: 'region'
}
const
fields
=
{
YEAR
:
'
year
'
,
MONTH
:
'
month
'
,
DAY
:
'
day
'
}
export
default
{
name
:
'
Picker
'
,
mixins
:
[
emitter
],
props
:
{
name
:
{
type
:
String
,
default
:
''
},
range
:
{
type
:
Array
,
default
()
{
return
[]
}
},
rangeKey
:
{
type
:
String
,
default
:
''
},
value
:
{
type
:
[
Number
,
String
,
Array
],
default
:
0
},
mode
:
{
type
:
String
,
default
:
mode
.
SELECTOR
,
validator
(
val
)
{
return
Object
.
values
(
mode
).
indexOf
(
val
)
>=
0
}
},
fields
:
{
type
:
String
,
default
:
'
day
'
,
validator
(
val
)
{
return
Object
.
values
(
fields
).
indexOf
(
val
)
>=
0
}
},
start
:
{
type
:
String
,
default
()
{
if
(
this
.
mode
===
mode
.
TIME
)
{
return
'
00:00
'
}
if
(
this
.
mode
===
mode
.
DATE
)
{
let
year
=
(
new
Date
()).
getFullYear
()
-
100
switch
(
this
.
fields
)
{
case
fields
.
YEAR
:
return
year
case
fields
.
MONTH
:
return
year
+
'
-01
'
case
fields
.
DAY
:
return
year
+
'
-01-01
'
}
}
return
''
}
},
end
:
{
type
:
String
,
default
()
{
if
(
this
.
mode
===
mode
.
TIME
)
{
return
'
23:59
'
}
if
(
this
.
mode
===
mode
.
DATE
)
{
let
year
=
(
new
Date
()).
getFullYear
()
+
100
switch
(
this
.
fields
)
{
case
fields
.
YEAR
:
return
year
case
fields
.
MONTH
:
return
year
+
'
-12
'
case
fields
.
DAY
:
return
year
+
'
-12-31
'
}
}
return
''
}
},
disabled
:
{
type
:
[
Boolean
,
String
],
default
:
false
}
},
data
()
{
return
{
valueSync
:
this
.
value
||
0
,
visible
:
false
,
valueChangeSource
:
''
}
},
watch
:
{
value
(
val
)
{
if
(
Array
.
isArray
(
val
))
{
if
(
!
Array
.
isArray
(
this
.
valueSync
))
{
this
.
valueSync
=
[]
}
this
.
valueSync
.
length
=
val
.
length
val
.
forEach
((
val
,
index
)
=>
{
if
(
val
!==
this
.
valueSync
[
index
])
{
this
.
$set
(
this
.
valueSync
,
index
,
val
)
}
})
}
else
if
(
typeof
val
!==
'
object
'
)
{
this
.
valueSync
=
val
}
},
valueSync
(
val
)
{
if
(
!
this
.
valueChangeSource
)
{
this
.
_show
()
}
else
{
this
.
$emit
(
'
update:value
'
,
val
)
}
}
},
created
()
{
this
.
$dispatch
(
'
Form
'
,
'
uni-form-group-update
'
,
{
type
:
'
add
'
,
vm
:
this
})
Object
.
keys
(
this
.
$props
).
forEach
(
key
=>
{
if
(
key
!==
'
value
'
&&
key
!==
'
name
'
)
{
this
.
$watch
(
key
,
this
.
_show
)
}
})
},
beforeDestroy
()
{
this
.
$dispatch
(
'
Form
'
,
'
uni-form-group-update
'
,
{
type
:
'
remove
'
,
vm
:
this
})
},
destroyed
()
{
if
(
this
.
visible
)
{
const
id
=
this
.
$page
.
id
publishHandler
(
'
hidePicker
'
,
{},
id
)
}
},
methods
:
{
_click
()
{
if
(
this
.
disabled
)
{
return
}
const
id
=
this
.
$page
.
id
subscribe
(
`
${
id
}
-picker-change`
,
this
.
change
)
subscribe
(
`
${
id
}
-picker-columnchange`
,
this
.
columnchange
)
subscribe
(
`
${
id
}
-picker-cancel`
,
this
.
cancel
)
this
.
visible
=
true
this
.
_show
()
},
_show
()
{
if
(
this
.
visible
)
{
const
id
=
this
.
$page
.
id
let
options
=
Object
.
assign
({},
this
.
$props
)
options
.
value
=
this
.
valueSync
publishHandler
(
'
showPicker
'
,
options
,
id
)
}
},
change
(
args
)
{
this
.
visible
=
false
const
id
=
this
.
$page
.
id
unsubscribe
(
`
${
id
}
-picker-change`
)
unsubscribe
(
`
${
id
}
-picker-columnchange`
)
unsubscribe
(
`
${
id
}
-picker-cancel`
)
if
(
!
this
.
disabled
)
{
this
.
valueChangeSource
=
'
click
'
let
value
=
args
.
value
this
.
valueSync
=
Array
.
isArray
(
value
)
?
value
.
map
(
val
=>
val
)
:
value
this
.
$trigger
(
'
change
'
,
{},
{
value
})
}
},
columnchange
(
args
)
{
this
.
$trigger
(
'
columnchange
'
,
{},
args
)
},
cancel
(
args
)
{
this
.
visible
=
false
const
id
=
this
.
$page
.
id
unsubscribe
(
`
${
id
}
-picker-change`
)
unsubscribe
(
`
${
id
}
-picker-columnchange`
)
unsubscribe
(
`
${
id
}
-picker-cancel`
)
this
.
$trigger
(
'
cancel
'
,
{},
{})
},
_getFormData
()
{
return
{
value
:
this
.
valueSync
,
key
:
this
.
name
}
},
_resetFormData
()
{
this
.
valueSync
=
''
}
}
}
</
script
>
<
style
>
uni-picker
{
display
:
block
;
}
</
style
>
src/platforms/h5/components/app/index.vue
浏览文件 @
70941b8e
...
...
@@ -10,21 +10,17 @@
v-if=
"hasTabBar"
v-show=
"showTabBar"
v-bind=
"tabBar"
/>
<toast
<toast
v-if=
"$options.components.Toast"
v-bind=
"showToast"
/>
<action-sheet
<action-sheet
v-if=
"$options.components.ActionSheet"
v-bind=
"showActionSheet"
@
close=
"_onActionSheetClose"
/>
<modal
<modal
v-if=
"$options.components.Modal"
v-bind=
"showModal"
@
close=
"_onModalClose"
/>
<picker
v-if=
"$options.components.Picker"
v-bind=
"showPicker"
@
close=
"_onPickerClose"
/>
</uni-app>
</
template
>
<
script
>
...
...
src/platforms/h5/components/app/popup/index.js
浏览文件 @
70941b8e
import
Toast
from
'
./toast
'
import
Modal
from
'
./modal
'
import
Picker
from
'
./picker
'
import
ActionSheet
from
'
./actionSheet
'
export
default
{
Toast
,
Modal
,
Picker
,
ActionSheet
}
}
src/platforms/h5/components/app/popup/mixins/picker.js
已删除
100644 → 0
浏览文件 @
e4c0e281
const
defaultProps
=
{
visible
:
false
,
mode
:
''
,
range
:
[],
rangeKey
:
''
,
value
:
''
,
disabled
:
false
,
start
:
''
,
end
:
''
,
fields
:
'
day
'
,
customItem
:
''
}
export
default
{
data
()
{
return
{
showPicker
:
{
visible
:
false
}
}
},
created
()
{
// 订阅 View 层的 showPicker 事件
UniServiceJSBridge
.
subscribe
(
'
showPicker
'
,
(
args
,
pageId
)
=>
{
// 根据不同参数,渲染不同类型 picker(注意全局仅一个 picker 组件对象,每次 showPicker 需传入当前类型 picker 的完整参数)
this
.
showPicker
=
Object
.
assign
(
defaultProps
,
args
,
{
pageId
,
visible
:
true
})
})
// 订阅 View 层的 hidePicker 事件
UniServiceJSBridge
.
subscribe
(
'
hidePicker
'
,
()
=>
{
this
.
_onPickerClose
()
})
// 订阅页面返回跳转时触发的 uni.onHidePopup 事件,隐藏 picker
UniServiceJSBridge
.
on
(
'
onHidePopup
'
,
()
=>
{
this
.
_onPickerClose
()
})
},
methods
:
{
// 处理 Picker close 回调
_onPickerClose
()
{
// 隐藏 picker 重置数据
this
.
showPicker
.
visible
=
false
this
.
showPicker
.
mode
=
'
selector
'
this
.
showPicker
.
range
=
[]
this
.
showPicker
.
value
=
0
}
}
}
src/platforms/h5/
components/app/popup/picker
.vue
→
src/platforms/h5/
view/components/picker/index
.vue
浏览文件 @
70941b8e
<
template
>
<uni-picker
@
touchmove.prevent
>
<transition
name=
"uni-fade"
>
<div
v-show=
"visible"
class=
"uni-mask"
@
click=
"_cancel"
/>
</transition>
<div
:class=
"
{'uni-picker-toggle':visible}"
class="uni-picker">
<div
class=
"uni-picker-header"
@
click.stop
>
<div
class=
"uni-picker-action uni-picker-action-cancel"
@
click=
"_cancel"
>
取消
</div>
<div
class=
"uni-picker-action uni-picker-action-confirm"
@
click=
"_change"
>
确定
</div>
</div>
<v-uni-picker-view
v-if=
"visible"
:value.sync=
"valueArray"
class=
"uni-picker-content"
>
<v-uni-picker-view-column
v-for=
"(range,index0) in rangeArray"
:key=
"index0"
>
<div
v-for=
"(item,index) in range"
:key=
"index"
class=
"uni-picker-item"
>
{{
typeof
item
===
'
object
'
?
item
[
rangeKey
]
||
''
:
item
}}{{
units
[
index0
]
||
''
}}
</div>
</v-uni-picker-view-column>
</v-uni-picker-view>
<!-- 第二种时间单位展示方式-暂时不用这种 -->
<!--
<div
v-if=
"units.length"
class=
"uni-picker-units"
>
<div
v-for=
"(item,index) in units"
:key=
"index"
>
{{
item
}}
</div>
</div>
-->
</div>
</uni-picker>
</
template
>
<
script
>
import
{
formatDateTime
}
from
'
uni-shared
'
const
mode
=
{
SELECTOR
:
'
selector
'
,
MULTISELECTOR
:
'
multiSelector
'
,
TIME
:
'
time
'
,
DATE
:
'
date
'
,
REGION
:
'
region
'
}
const
fields
=
{
YEAR
:
'
year
'
,
MONTH
:
'
month
'
,
DAY
:
'
day
'
}
export
default
{
name
:
'
Picker
'
,
props
:
{
pageId
:
{
type
:
Number
,
default
:
0
},
range
:
{
type
:
Array
,
default
()
{
return
[]
}
},
rangeKey
:
{
type
:
String
,
default
:
''
},
value
:
{
type
:
[
Number
,
String
,
Array
],
default
:
0
},
mode
:
{
type
:
String
,
default
:
mode
.
SELECTOR
},
fields
:
{
type
:
String
,
default
:
fields
.
DAY
},
start
:
{
type
:
String
,
default
()
{
if
(
this
.
mode
===
mode
.
TIME
)
{
return
'
00:00
'
}
if
(
this
.
mode
===
mode
.
DATE
)
{
let
year
=
(
new
Date
()).
getFullYear
()
-
150
switch
(
this
.
fields
)
{
case
fields
.
YEAR
:
return
year
case
fields
.
MONTH
:
return
year
+
'
-01
'
case
fields
.
DAY
:
return
year
+
'
-01-01
'
}
}
return
''
}
},
end
:
{
type
:
String
,
default
()
{
if
(
this
.
mode
===
mode
.
TIME
)
{
return
'
23:59
'
}
if
(
this
.
mode
===
mode
.
DATE
)
{
let
year
=
(
new
Date
()).
getFullYear
()
+
150
switch
(
this
.
fields
)
{
case
fields
.
YEAR
:
return
year
case
fields
.
MONTH
:
return
year
+
'
-12
'
case
fields
.
DAY
:
return
year
+
'
-12-31
'
}
}
return
''
}
},
disabled
:
{
type
:
[
Boolean
,
String
],
default
:
false
},
visible
:
{
type
:
Boolean
,
default
:
false
}
},
data
()
{
return
{
timeArray
:
[],
dateArray
:
[],
valueArray
:
[],
oldValueArray
:
[]
}
},
computed
:
{
rangeArray
()
{
var
val
=
this
.
range
switch
(
this
.
mode
)
{
case
mode
.
SELECTOR
:
return
[
val
]
case
mode
.
MULTISELECTOR
:
return
val
case
mode
.
TIME
:
return
this
.
timeArray
case
mode
.
DATE
:
{
let
dateArray
=
this
.
dateArray
switch
(
this
.
fields
)
{
case
fields
.
YEAR
:
return
[
dateArray
[
0
]]
case
fields
.
MONTH
:
return
[
dateArray
[
0
],
dateArray
[
1
]]
case
fields
.
DAY
:
return
[
dateArray
[
0
],
dateArray
[
1
],
dateArray
[
2
]]
}
}
}
},
startArray
()
{
var
splitStr
=
this
.
mode
===
mode
.
DATE
?
'
-
'
:
'
:
'
var
array
=
this
.
mode
===
mode
.
DATE
?
this
.
dateArray
:
this
.
timeArray
var
val
=
this
.
start
.
split
(
splitStr
).
map
((
val
,
i
)
=>
array
[
i
].
indexOf
(
val
))
if
(
val
.
indexOf
(
-
1
)
>=
0
)
{
val
=
array
.
map
(()
=>
0
)
}
return
val
},
endArray
()
{
var
splitStr
=
this
.
mode
===
mode
.
DATE
?
'
-
'
:
'
:
'
var
array
=
this
.
mode
===
mode
.
DATE
?
this
.
dateArray
:
this
.
timeArray
var
val
=
this
.
end
.
split
(
splitStr
).
map
((
val
,
i
)
=>
array
[
i
].
indexOf
(
val
))
if
(
val
.
indexOf
(
-
1
)
>=
0
)
{
val
=
array
.
map
((
val
)
=>
val
.
length
-
1
)
}
return
val
},
units
()
{
switch
(
this
.
mode
)
{
case
mode
.
DATE
:
return
[
'
年
'
,
'
月
'
,
'
日
'
]
case
mode
.
TIME
:
return
[
'
时
'
,
'
分
'
]
default
:
return
[]
}
}
},
watch
:
{
valueArray
(
val
)
{
if
(
this
.
mode
===
mode
.
TIME
||
this
.
mode
===
mode
.
DATE
)
{
let
getValue
=
this
.
mode
===
mode
.
TIME
?
this
.
_getTimeValue
:
this
.
_getDateValue
let
valueArray
=
this
.
valueArray
let
startArray
=
this
.
startArray
let
endArray
=
this
.
endArray
if
(
this
.
mode
===
mode
.
DATE
)
{
const
dateArray
=
this
.
dateArray
let
max
=
dateArray
[
2
].
length
let
day
=
dateArray
[
2
][
valueArray
[
2
]]
let
realDay
=
new
Date
(
`
${
dateArray
[
0
][
valueArray
[
0
]]}
/
${
dateArray
[
1
][
valueArray
[
1
]]}
/
${
day
}
`
).
getDate
()
day
=
Number
(
day
)
if
(
realDay
<
day
)
{
valueArray
[
2
]
-=
realDay
+
max
-
day
}
}
if
(
getValue
(
valueArray
)
<
getValue
(
startArray
))
{
this
.
_cloneArray
(
valueArray
,
startArray
)
}
else
if
(
getValue
(
valueArray
)
>
getValue
(
endArray
))
{
this
.
_cloneArray
(
valueArray
,
endArray
)
}
}
val
.
forEach
((
value
,
column
)
=>
{
if
(
value
!==
this
.
oldValueArray
[
column
])
{
this
.
oldValueArray
[
column
]
=
value
if
(
this
.
mode
===
mode
.
MULTISELECTOR
)
{
// 触发 View 层 columnchange 事件
UniServiceJSBridge
.
publishHandler
(
this
.
pageId
+
'
-picker-columnchange
'
,
{
column
,
value
},
this
.
pageId
)
}
}
})
},
visible
(
val
)
{
if
(
!
val
)
{
this
.
$nextTick
(()
=>
this
.
_setValue
())
}
}
},
created
()
{
this
.
_createTime
()
this
.
_createDate
()
this
.
_setValue
()
this
.
$watch
(
'
value
'
,
this
.
_setValue
)
this
.
$watch
(
'
mode
'
,
this
.
_setValue
)
},
methods
:
{
_createTime
()
{
var
hours
=
[]
var
minutes
=
[]
hours
.
splice
(
0
,
hours
.
length
)
for
(
let
i
=
0
;
i
<
24
;
i
++
)
{
hours
.
push
((
i
<
10
?
'
0
'
:
''
)
+
i
)
}
minutes
.
splice
(
0
,
minutes
.
length
)
for
(
let
i
=
0
;
i
<
60
;
i
++
)
{
minutes
.
push
((
i
<
10
?
'
0
'
:
''
)
+
i
)
}
this
.
timeArray
.
push
(
hours
,
minutes
)
},
_createDate
()
{
var
years
=
[]
var
year
=
(
new
Date
()).
getFullYear
()
for
(
let
i
=
year
-
150
,
end
=
year
+
150
;
i
<=
end
;
i
++
)
{
years
.
push
(
String
(
i
))
}
var
months
=
[]
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
months
.
push
((
i
<
10
?
'
0
'
:
''
)
+
i
)
}
var
days
=
[]
for
(
let
i
=
1
;
i
<=
31
;
i
++
)
{
days
.
push
((
i
<
10
?
'
0
'
:
''
)
+
i
)
}
this
.
dateArray
.
push
(
years
,
months
,
days
)
},
_getTimeValue
(
val
)
{
return
val
[
0
]
*
60
+
val
[
1
]
},
_getDateValue
(
val
)
{
return
val
[
0
]
*
366
+
(
val
[
1
]
||
0
)
*
31
+
(
val
[
2
]
||
0
)
},
/**
* 将右侧数组值同步到左侧(交集部分)
*/
_cloneArray
(
val1
,
val2
)
{
for
(
let
i
=
0
;
i
<
val1
.
length
&&
i
<
val2
.
length
;
i
++
)
{
val1
[
i
]
=
val2
[
i
]
}
},
_setValue
()
{
var
val
=
this
.
value
var
valueArray
switch
(
this
.
mode
)
{
case
mode
.
SELECTOR
:
valueArray
=
[
val
]
break
case
mode
.
MULTISELECTOR
:
valueArray
=
[...
val
]
break
case
mode
.
TIME
:
// 处理默认值为当前时间
if
(
this
.
value
===
0
)
{
val
=
formatDateTime
({
mode
:
mode
.
TIME
})
}
valueArray
=
val
.
split
(
'
:
'
).
map
((
val
,
i
)
=>
this
.
timeArray
[
i
].
indexOf
(
val
))
break
case
mode
.
DATE
:
// 处理默认值为当前日期
if
(
this
.
value
===
0
)
{
val
=
formatDateTime
({
mode
:
mode
.
DATE
})
}
valueArray
=
val
.
split
(
'
-
'
).
map
((
val
,
i
)
=>
this
.
dateArray
[
i
].
indexOf
(
val
))
break
}
this
.
oldValueArray
=
[...
valueArray
]
this
.
valueArray
=
[...
valueArray
]
},
_getValue
()
{
var
val
=
this
.
valueArray
switch
(
this
.
mode
)
{
case
mode
.
SELECTOR
:
return
val
[
0
]
case
mode
.
MULTISELECTOR
:
return
val
.
map
(
val
=>
val
)
case
mode
.
TIME
:
return
this
.
valueArray
.
map
((
val
,
i
)
=>
this
.
timeArray
[
i
][
val
]).
join
(
'
:
'
)
case
mode
.
DATE
:
return
this
.
valueArray
.
map
((
val
,
i
)
=>
this
.
dateArray
[
i
][
val
]).
join
(
'
-
'
)
}
},
_change
()
{
this
.
$emit
(
'
close
'
)
// 触发 View 层 change 事件
UniServiceJSBridge
.
publishHandler
(
this
.
pageId
+
'
-picker-change
'
,
{
value
:
this
.
_getValue
()
},
this
.
pageId
)
},
_cancel
()
{
// 通知父组件修改 visible
this
.
$emit
(
'
close
'
)
// 触发 View 层 cancel 事件
UniServiceJSBridge
.
publishHandler
(
this
.
pageId
+
'
-picker-cancel
'
,
{},
this
.
pageId
)
}
}
}
</
script
>
<
style
>
uni-picker
{
display
:
block
;
box-sizing
:
border-box
;
}
uni-picker
.uni-picker
*
{
box-sizing
:
border-box
;
}
uni-picker
.uni-picker
{
position
:
fixed
;
left
:
0
;
bottom
:
0
;
transform
:
translate
(
0
,
100%
);
backface-visibility
:
hidden
;
z-index
:
999
;
width
:
100%
;
background-color
:
#efeff4
;
visibility
:
hidden
;
transition
:
transform
0.3s
,
visibility
0.3s
;
}
uni-picker
.uni-picker.uni-picker-toggle
{
visibility
:
visible
;
transform
:
translate
(
0
,
0
);
}
uni-picker
.uni-picker-content
{
position
:
relative
;
display
:
block
;
width
:
100%
;
height
:
238px
;
background-color
:
white
;
}
uni-picker
.uni-picker-item
{
padding
:
0
;
height
:
34px
;
line-height
:
34px
;
text-align
:
center
;
color
:
#000
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
overflow
:
hidden
;
}
uni-picker
.uni-picker-header
{
display
:
block
;
position
:
relative
;
text-align
:
center
;
width
:
100%
;
height
:
45px
;
background-color
:
#fff
;
}
uni-picker
.uni-picker-header
:after
{
content
:
""
;
position
:
absolute
;
left
:
0
;
bottom
:
0
;
right
:
0
;
height
:
1px
;
clear
:
both
;
border-bottom
:
1px
solid
#e5e5e5
;
color
:
#e5e5e5
;
transform-origin
:
0
100%
;
transform
:
scaleY
(
0.5
);
}
uni-picker
.uni-picker-action
{
display
:
block
;
max-width
:
50%
;
top
:
0
;
height
:
100%
;
box-sizing
:
border-box
;
padding
:
0
14px
;
font-size
:
17px
;
line-height
:
45px
;
overflow
:
hidden
;
}
uni-picker
.uni-picker-action.uni-picker-action-cancel
{
float
:
left
;
color
:
#888
;
}
uni-picker
.uni-picker-action.uni-picker-action-confirm
{
float
:
right
;
color
:
#007aff
;
}
/* .uni-picker {
position: relative;
}
.uni-picker-units {
position: absolute;
display: flex;
width: 100%;
line-height: 16px;
font-size: 14px;
top: 50%;
margin-top: 22.5px;
transform: translateY(-50%);
overflow: hidden;
color: #666666;
pointer-events: none;
}
.uni-picker-units > div {
flex: 1;
text-align: center;
transform: translateX(2em);
} */
</
style
>
<
template
>
<uni-picker
@
click.stop=
"_show"
>
<div
ref=
"picker"
class=
"uni-picker-container"
@
touchmove.prevent
>
<transition
name=
"uni-fade"
>
<div
v-show=
"visible"
class=
"uni-mask"
@
click=
"_cancel"
/>
</transition>
<div
:class=
"
{'uni-picker-toggle':visible}"
class="uni-picker">
<div
class=
"uni-picker-header"
@
click.stop
>
<div
class=
"uni-picker-action uni-picker-action-cancel"
@
click=
"_cancel"
>
取消
</div>
<div
class=
"uni-picker-action uni-picker-action-confirm"
@
click=
"_change"
>
确定
</div>
</div>
<v-uni-picker-view
v-if=
"visible"
:value.sync=
"valueArray"
class=
"uni-picker-content"
>
<v-uni-picker-view-column
v-for=
"(range,index0) in rangeArray"
:key=
"index0"
>
<div
v-for=
"(item,index) in range"
:key=
"index"
class=
"uni-picker-item"
>
{{
typeof
item
===
'
object
'
?
item
[
rangeKey
]
||
''
:
item
}}{{
units
[
index0
]
||
''
}}
</div>
</v-uni-picker-view-column>
</v-uni-picker-view>
<!-- 第二种时间单位展示方式-暂时不用这种 -->
<!--
<div
v-if=
"units.length"
class=
"uni-picker-units"
>
<div
v-for=
"(item,index) in units"
:key=
"index"
>
{{
item
}}
</div>
</div>
-->
</div>
</div>
<div>
<slot
/>
</div>
</uni-picker>
</
template
>
<
script
>
import
{
emitter
}
from
'
uni-mixins
'
import
{
formatDateTime
}
from
'
uni-shared
'
const
mode
=
{
SELECTOR
:
'
selector
'
,
MULTISELECTOR
:
'
multiSelector
'
,
TIME
:
'
time
'
,
DATE
:
'
date
'
// 暂不支持城市选择
// REGION: 'region'
}
const
fields
=
{
YEAR
:
'
year
'
,
MONTH
:
'
month
'
,
DAY
:
'
day
'
}
export
default
{
name
:
'
Picker
'
,
mixins
:
[
emitter
],
props
:
{
name
:
{
type
:
String
,
default
:
''
},
range
:
{
type
:
Array
,
default
()
{
return
[]
}
},
rangeKey
:
{
type
:
String
,
default
:
''
},
value
:
{
type
:
[
Number
,
String
,
Array
],
default
:
0
},
mode
:
{
type
:
String
,
default
:
mode
.
SELECTOR
,
validator
(
val
)
{
return
Object
.
values
(
mode
).
indexOf
(
val
)
>=
0
}
},
fields
:
{
type
:
String
,
default
:
'
day
'
,
validator
(
val
)
{
return
Object
.
values
(
fields
).
indexOf
(
val
)
>=
0
}
},
start
:
{
type
:
String
,
default
()
{
if
(
this
.
mode
===
mode
.
TIME
)
{
return
'
00:00
'
}
if
(
this
.
mode
===
mode
.
DATE
)
{
let
year
=
new
Date
().
getFullYear
()
-
100
switch
(
this
.
fields
)
{
case
fields
.
YEAR
:
return
year
case
fields
.
MONTH
:
return
year
+
'
-01
'
case
fields
.
DAY
:
return
year
+
'
-01-01
'
}
}
return
''
}
},
end
:
{
type
:
String
,
default
()
{
if
(
this
.
mode
===
mode
.
TIME
)
{
return
'
23:59
'
}
if
(
this
.
mode
===
mode
.
DATE
)
{
let
year
=
new
Date
().
getFullYear
()
+
100
switch
(
this
.
fields
)
{
case
fields
.
YEAR
:
return
year
case
fields
.
MONTH
:
return
year
+
'
-12
'
case
fields
.
DAY
:
return
year
+
'
-12-31
'
}
}
return
''
}
},
disabled
:
{
type
:
[
Boolean
,
String
],
default
:
false
}
},
data
()
{
return
{
valueSync
:
this
.
value
||
0
,
visible
:
false
,
valueChangeSource
:
''
,
timeArray
:
[],
dateArray
:
[],
valueArray
:
[],
oldValueArray
:
[]
}
},
computed
:
{
rangeArray
()
{
var
val
=
this
.
range
switch
(
this
.
mode
)
{
case
mode
.
SELECTOR
:
return
[
val
]
case
mode
.
MULTISELECTOR
:
return
val
case
mode
.
TIME
:
return
this
.
timeArray
case
mode
.
DATE
:
{
let
dateArray
=
this
.
dateArray
switch
(
this
.
fields
)
{
case
fields
.
YEAR
:
return
[
dateArray
[
0
]]
case
fields
.
MONTH
:
return
[
dateArray
[
0
],
dateArray
[
1
]]
case
fields
.
DAY
:
return
[
dateArray
[
0
],
dateArray
[
1
],
dateArray
[
2
]]
}
}
}
},
startArray
()
{
var
splitStr
=
this
.
mode
===
mode
.
DATE
?
'
-
'
:
'
:
'
var
array
=
this
.
mode
===
mode
.
DATE
?
this
.
dateArray
:
this
.
timeArray
var
val
=
this
.
start
.
split
(
splitStr
).
map
((
val
,
i
)
=>
array
[
i
].
indexOf
(
val
))
if
(
val
.
indexOf
(
-
1
)
>=
0
)
{
val
=
array
.
map
(()
=>
0
)
}
return
val
},
endArray
()
{
var
splitStr
=
this
.
mode
===
mode
.
DATE
?
'
-
'
:
'
:
'
var
array
=
this
.
mode
===
mode
.
DATE
?
this
.
dateArray
:
this
.
timeArray
var
val
=
this
.
end
.
split
(
splitStr
).
map
((
val
,
i
)
=>
array
[
i
].
indexOf
(
val
))
if
(
val
.
indexOf
(
-
1
)
>=
0
)
{
val
=
array
.
map
((
val
)
=>
val
.
length
-
1
)
}
return
val
},
units
()
{
switch
(
this
.
mode
)
{
case
mode
.
DATE
:
return
[
'
年
'
,
'
月
'
,
'
日
'
]
case
mode
.
TIME
:
return
[
'
时
'
,
'
分
'
]
default
:
return
[]
}
}
},
watch
:
{
value
(
val
)
{
if
(
Array
.
isArray
(
val
))
{
if
(
!
Array
.
isArray
(
this
.
valueSync
))
{
this
.
valueSync
=
[]
}
this
.
valueSync
.
length
=
val
.
length
val
.
forEach
((
val
,
index
)
=>
{
if
(
val
!==
this
.
valueSync
[
index
])
{
this
.
$set
(
this
.
valueSync
,
index
,
val
)
}
})
}
else
if
(
typeof
val
!==
'
object
'
)
{
this
.
valueSync
=
val
}
},
valueSync
(
value
)
{
if
(
this
.
valueChangeSource
)
{
this
.
$trigger
(
'
change
'
,
{},
{
value
}
)
}
},
valueArray
(
val
)
{
if
(
this
.
mode
===
mode
.
TIME
||
this
.
mode
===
mode
.
DATE
)
{
let
getValue
=
this
.
mode
===
mode
.
TIME
?
this
.
_getTimeValue
:
this
.
_getDateValue
let
valueArray
=
this
.
valueArray
let
startArray
=
this
.
startArray
let
endArray
=
this
.
endArray
if
(
this
.
mode
===
mode
.
DATE
)
{
const
dateArray
=
this
.
dateArray
let
max
=
dateArray
[
2
].
length
let
day
=
dateArray
[
2
][
valueArray
[
2
]]
let
realDay
=
new
Date
(
`
${
dateArray
[
0
][
valueArray
[
0
]]}
/
${
dateArray
[
1
][
valueArray
[
1
]]
}
/
${
day
}
`
).
getDate
()
day
=
Number
(
day
)
if
(
realDay
<
day
)
{
valueArray
[
2
]
-=
realDay
+
max
-
day
}
}
if
(
getValue
(
valueArray
)
<
getValue
(
startArray
))
{
this
.
_cloneArray
(
valueArray
,
startArray
)
}
else
if
(
getValue
(
valueArray
)
>
getValue
(
endArray
))
{
this
.
_cloneArray
(
valueArray
,
endArray
)
}
}
val
.
forEach
((
value
,
column
)
=>
{
if
(
value
!==
this
.
oldValueArray
[
column
])
{
this
.
oldValueArray
[
column
]
=
value
if
(
this
.
mode
===
mode
.
MULTISELECTOR
)
{
this
.
$trigger
(
'
columnchange
'
,
{},
{
column
,
value
}
)
}
}
})
}
},
created
()
{
this
.
$dispatch
(
'
Form
'
,
'
uni-form-group-update
'
,
{
type
:
'
add
'
,
vm
:
this
})
this
.
_createTime
()
this
.
_createDate
()
this
.
$watch
(
'
valueSync
'
,
this
.
_setValue
)
this
.
$watch
(
'
mode
'
,
this
.
_setValue
)
},
beforeDestroy
()
{
this
.
$dispatch
(
'
Form
'
,
'
uni-form-group-update
'
,
{
type
:
'
remove
'
,
vm
:
this
})
},
methods
:
{
_show
()
{
if
(
this
.
disabled
)
{
return
}
this
.
valueChangeSource
=
''
this
.
_setValue
()
var
$picker
=
this
.
$refs
.
picker
$picker
.
remove
();
(
document
.
querySelector
(
'
uni-app
'
)
||
document
.
body
).
append
(
$picker
)
$picker
.
style
.
display
=
'
block
'
setTimeout
(()
=>
{
this
.
visible
=
true
},
20
)
},
_getFormData
()
{
return
{
value
:
this
.
valueSync
,
key
:
this
.
name
}
},
_resetFormData
()
{
this
.
valueSync
=
''
},
_createTime
()
{
var
hours
=
[]
var
minutes
=
[]
hours
.
splice
(
0
,
hours
.
length
)
for
(
let
i
=
0
;
i
<
24
;
i
++
)
{
hours
.
push
((
i
<
10
?
'
0
'
:
''
)
+
i
)
}
minutes
.
splice
(
0
,
minutes
.
length
)
for
(
let
i
=
0
;
i
<
60
;
i
++
)
{
minutes
.
push
((
i
<
10
?
'
0
'
:
''
)
+
i
)
}
this
.
timeArray
.
push
(
hours
,
minutes
)
},
_createDate
()
{
var
years
=
[]
var
year
=
new
Date
().
getFullYear
()
for
(
let
i
=
year
-
150
,
end
=
year
+
150
;
i
<=
end
;
i
++
)
{
years
.
push
(
String
(
i
))
}
var
months
=
[]
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
months
.
push
((
i
<
10
?
'
0
'
:
''
)
+
i
)
}
var
days
=
[]
for
(
let
i
=
1
;
i
<=
31
;
i
++
)
{
days
.
push
((
i
<
10
?
'
0
'
:
''
)
+
i
)
}
this
.
dateArray
.
push
(
years
,
months
,
days
)
},
_getTimeValue
(
val
)
{
return
val
[
0
]
*
60
+
val
[
1
]
},
_getDateValue
(
val
)
{
return
val
[
0
]
*
366
+
(
val
[
1
]
||
0
)
*
31
+
(
val
[
2
]
||
0
)
},
/**
* 将右侧数组值同步到左侧(交集部分)
*/
_cloneArray
(
val1
,
val2
)
{
for
(
let
i
=
0
;
i
<
val1
.
length
&&
i
<
val2
.
length
;
i
++
)
{
val1
[
i
]
=
val2
[
i
]
}
},
_setValue
()
{
var
val
=
this
.
valueSync
var
valueArray
switch
(
this
.
mode
)
{
case
mode
.
SELECTOR
:
valueArray
=
[
val
]
break
case
mode
.
MULTISELECTOR
:
valueArray
=
[...
val
]
break
case
mode
.
TIME
:
// 处理默认值为当前时间
if
(
this
.
value
===
0
)
{
val
=
formatDateTime
({
mode
:
mode
.
TIME
})
}
valueArray
=
val
.
split
(
'
:
'
)
.
map
((
val
,
i
)
=>
this
.
timeArray
[
i
].
indexOf
(
val
))
break
case
mode
.
DATE
:
// 处理默认值为当前日期
if
(
this
.
value
===
0
)
{
val
=
formatDateTime
({
mode
:
mode
.
DATE
})
}
valueArray
=
val
.
split
(
'
-
'
)
.
map
((
val
,
i
)
=>
this
.
dateArray
[
i
].
indexOf
(
val
))
break
}
this
.
oldValueArray
=
[...
valueArray
]
this
.
valueArray
=
[...
valueArray
]
},
_getValue
()
{
var
val
=
this
.
valueArray
switch
(
this
.
mode
)
{
case
mode
.
SELECTOR
:
return
val
[
0
]
case
mode
.
MULTISELECTOR
:
return
val
.
map
(
val
=>
val
)
case
mode
.
TIME
:
return
this
.
valueArray
.
map
((
val
,
i
)
=>
this
.
timeArray
[
i
][
val
])
.
join
(
'
:
'
)
case
mode
.
DATE
:
return
this
.
valueArray
.
map
((
val
,
i
)
=>
this
.
dateArray
[
i
][
val
])
.
join
(
'
-
'
)
}
},
_change
()
{
this
.
_close
()
this
.
valueChangeSource
=
'
click
'
let
value
=
this
.
_getValue
()
this
.
valueSync
=
Array
.
isArray
(
value
)
?
value
.
map
(
val
=>
val
)
:
value
},
_cancel
()
{
this
.
_close
()
this
.
$trigger
(
'
cancel
'
,
{},
{})
},
_close
()
{
this
.
visible
=
false
setTimeout
(()
=>
{
var
$picker
=
this
.
$refs
.
picker
$picker
.
remove
()
this
.
$el
.
prepend
(
$picker
)
$picker
.
style
.
display
=
'
none
'
},
260
)
}
}
}
</
script
>
<
style
>
uni-picker
{
display
:
block
;
}
.uni-picker-container
{
display
:
none
;
position
:
fixed
;
left
:
0
;
right
:
0
;
top
:
0
;
bottom
:
0
;
box-sizing
:
border-box
;
z-index
:
999
;
font-size
:
16px
;
}
.uni-picker-container
.uni-picker
*
{
box-sizing
:
border-box
;
}
.uni-picker-container
.uni-picker
{
position
:
fixed
;
left
:
0
;
bottom
:
0
;
transform
:
translate
(
0
,
100%
);
backface-visibility
:
hidden
;
z-index
:
999
;
width
:
100%
;
background-color
:
#efeff4
;
visibility
:
hidden
;
transition
:
transform
0.3s
,
visibility
0.3s
;
}
.uni-picker-container
.uni-picker.uni-picker-toggle
{
visibility
:
visible
;
transform
:
translate
(
0
,
0
);
}
.uni-picker-container
.uni-picker-content
{
position
:
relative
;
display
:
block
;
width
:
100%
;
height
:
238px
;
background-color
:
white
;
}
.uni-picker-container
.uni-picker-item
{
padding
:
0
;
height
:
34px
;
line-height
:
34px
;
text-align
:
center
;
color
:
#000
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
overflow
:
hidden
;
}
.uni-picker-container
.uni-picker-header
{
display
:
block
;
position
:
relative
;
text-align
:
center
;
width
:
100%
;
height
:
45px
;
background-color
:
#fff
;
}
.uni-picker-container
.uni-picker-header
:after
{
content
:
""
;
position
:
absolute
;
left
:
0
;
bottom
:
0
;
right
:
0
;
height
:
1px
;
clear
:
both
;
border-bottom
:
1px
solid
#e5e5e5
;
color
:
#e5e5e5
;
transform-origin
:
0
100%
;
transform
:
scaleY
(
0.5
);
}
.uni-picker-container
.uni-picker-action
{
display
:
block
;
max-width
:
50%
;
top
:
0
;
height
:
100%
;
box-sizing
:
border-box
;
padding
:
0
14px
;
font-size
:
17px
;
line-height
:
45px
;
overflow
:
hidden
;
}
.uni-picker-container
.uni-picker-action.uni-picker-action-cancel
{
float
:
left
;
color
:
#888
;
}
.uni-picker-container
.uni-picker-action.uni-picker-action-confirm
{
float
:
right
;
color
:
#007aff
;
}
/* .uni-picker {
position: relative;
}
.uni-picker-units {
position: absolute;
display: flex;
width: 100%;
line-height: 16px;
font-size: 14px;
top: 50%;
margin-top: 22.5px;
transform: translateY(-50%);
overflow: hidden;
color: #666666;
pointer-events: none;
}
.uni-picker-units > div {
flex: 1;
text-align: center;
transform: translateX(2em);
} */
</
style
>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录