Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
飞
飞鹤小程序
Project
Project
Details
Activity
Releases
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
FH
飞鹤小程序
Commits
72625f61
Commit
72625f61
authored
Jun 04, 2025
by
tao.huang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: form
parent
3ef04c4e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
236 additions
and
40 deletions
+236
-40
PickerCustom.vue
components/PickerCustom.vue
+119
-19
person.vue
pages/person/person.vue
+117
-21
No files found.
components/PickerCustom.vue
View file @
72625f61
...
...
@@ -17,7 +17,7 @@
<view
class=
"picker-layer-view-mask-top"
></view>
<view
class=
"picker-layer-view-mask-bottom"
></view>
<!--
半屏
picker-view -->
<!--
多列
picker-view -->
<picker-view
class=
"picker-layer-view"
mask-style=
"background: rgb(246, 248, 250); z-index: 0;"
...
...
@@ -25,29 +25,49 @@
:value=
"pickerValue"
@
change=
"onChange"
>
<picker-view-column>
<view
v-for=
"(item, idx) in range"
:key=
"idx"
class=
"picker-layer-item"
>
{{
item
}}
</view>
</picker-view-column>
<template
v-if=
"mode === 'date'"
>
<picker-view-column>
<view
v-for=
"(item, idx) in years"
:key=
"idx"
class=
"picker-layer-item"
>
{{
item
}}
年
</view>
</picker-view-column>
<picker-view-column>
<view
v-for=
"(item, idx) in months"
:key=
"idx"
class=
"picker-layer-item"
>
{{
item
}}
月
</view>
</picker-view-column>
<picker-view-column>
<view
v-for=
"(item, idx) in days"
:key=
"idx"
class=
"picker-layer-item"
>
{{
item
}}
日
</view>
</picker-view-column>
</
template
>
<
template
v-else
>
<picker-view-column
v-for=
"(col, colIdx) in columns"
:key=
"colIdx"
>
<view
v-for=
"(item, idx) in col"
:key=
"idx"
class=
"picker-layer-item"
>
{{
item
}}
</view>
</picker-view-column>
</
template
>
</picker-view>
</view>
</view>
</view>
</template>
<
script
setup
>
import
{
ref
}
from
"vue"
;
import
{
ref
,
computed
,
watch
}
from
"vue"
;
const
props
=
defineProps
({
mode
:
{
type
:
String
,
default
:
'custom'
,
// 'date' | 'custom'
},
range
:
{
type
:
Array
,
default
:
()
=>
[],
},
value
:
{
type
:
[
Number
,
Array
],
default
:
0
,
},
onPickerChange
:
{
...
...
@@ -62,12 +82,72 @@ const props = defineProps({
const
show
=
ref
(
false
);
const
pickerValue
=
ref
(
props
.
value
);
// date模式相关
const
currentYear
=
new
Date
().
getFullYear
();
const
years
=
computed
(()
=>
{
const
arr
=
[];
for
(
let
i
=
1970
;
i
<=
currentYear
;
i
++
)
{
arr
.
push
(
i
);
}
return
arr
;
});
const
months
=
computed
(()
=>
{
const
arr
=
[];
for
(
let
i
=
1
;
i
<=
12
;
i
++
)
{
arr
.
push
(
i
);
}
return
arr
;
});
const
days
=
computed
(()
=>
{
const
[
yearIdx
,
monthIdx
]
=
pickerValue
.
value
;
const
year
=
years
.
value
[
yearIdx
]
||
years
.
value
[
0
];
const
month
=
months
.
value
[
monthIdx
]
||
months
.
value
[
0
];
const
dayCount
=
new
Date
(
year
,
month
,
0
).
getDate
();
const
arr
=
[];
for
(
let
i
=
1
;
i
<=
dayCount
;
i
++
)
{
arr
.
push
(
i
);
}
return
arr
;
});
// custom模式相关
const
columns
=
computed
(()
=>
{
if
(
Array
.
isArray
(
props
.
range
[
0
]))
{
return
props
.
range
;
}
else
{
return
[
props
.
range
];
}
});
const
defaultValue
=
computed
(()
=>
{
if
(
props
.
mode
===
'date'
)
{
// 默认选中今年1月1日
return
[
years
.
value
.
length
-
1
,
0
,
0
];
}
else
if
(
Array
.
isArray
(
props
.
value
))
{
return
props
.
value
;
}
else
{
return
[
props
.
value
];
}
});
const
pickerValue
=
ref
([...
defaultValue
.
value
]);
watch
(
()
=>
props
.
value
,
(
val
)
=>
{
if
(
props
.
mode
===
'date'
)
{
pickerValue
.
value
=
[...
val
];
}
else
if
(
Array
.
isArray
(
val
))
{
pickerValue
.
value
=
[...
val
];
}
else
{
pickerValue
.
value
=
[
val
];
}
}
);
function
open
()
{
pickerValue
.
value
=
props
.
value
;
pickerValue
.
value
=
[...
defaultValue
.
value
]
;
show
.
value
=
true
;
props
.
onLayerVisibleChange
(
true
);
}
function
close
()
{
...
...
@@ -75,13 +155,33 @@ function close() {
props
.
onLayerVisibleChange
(
false
);
}
function
confirm
()
{
/* 处理选中逻辑 */
close
();
props
.
onPickerChange
(
pickerValue
.
value
);
close
();
if
(
props
.
mode
===
'date'
)
{
const
[
yIdx
,
mIdx
,
dIdx
]
=
pickerValue
.
value
;
const
year
=
years
.
value
[
yIdx
];
const
month
=
months
.
value
[
mIdx
];
const
day
=
days
.
value
[
dIdx
];
const
dateStr
=
`
${
year
}
-
${
String
(
month
).
padStart
(
2
,
'0'
)}
-
${
String
(
day
).
padStart
(
2
,
'0'
)}
`
;
props
.
onPickerChange
(
dateStr
);
}
else
{
// 单列时只返回索引,否则返回数组
if
(
columns
.
value
.
length
===
1
)
{
props
.
onPickerChange
(
pickerValue
.
value
[
0
]);
}
else
{
props
.
onPickerChange
([...
pickerValue
.
value
]);
}
}
}
function
onChange
(
e
)
{
console
.
log
(
"onPcikChange"
,
e
);
pickerValue
.
value
=
e
.
detail
.
value
;
let
val
=
e
.
detail
.
value
;
if
(
props
.
mode
===
'date'
)
{
// 如果天数溢出,自动修正到最大天数
const
maxDay
=
days
.
value
.
length
;
if
(
val
[
2
]
>=
maxDay
)
val
[
2
]
=
maxDay
-
1
;
pickerValue
.
value
=
val
;
}
else
{
pickerValue
.
value
=
val
;
}
}
</
script
>
<
style
lang=
"less"
scoped
>
...
...
pages/person/person.vue
View file @
72625f61
...
...
@@ -51,17 +51,22 @@
<form
@
submit=
"onSubmit"
>
<view
class=
"person-info"
>
<block
v-for=
"(item, index) in formItems.slice(
0,
pageStatus.formStatus == 1 ? formItems.length : 6
)"
v-for=
"(item, index) in formItems
.filter(formItemFilter)
.slice(
0,
formData.currentBaby == '已出生' && pageStatus.formStatus == 2
? 6
: formItems.length
)"
:key=
"item.name"
>
<view
class=
"form-row"
:style=
"
{
'border-bottom':
pageStatus.formStatus == 0
&&
index == formItems.length - 1
pageStatus.formStatus == 0
&&
index == formItems.filter(formItemFilter).length - 1
? 'none'
: '1rpx solid #f2f2f2',
}"
...
...
@@ -81,6 +86,7 @@
<!-- 选择器类型 -->
<PickerCustom
v-else-if=
"item.type === 'picker'"
:mode=
"item.mode"
:range=
"item.range"
:value=
"getPickerIndex(item)"
:onPickerChange=
"(e) => onPickerChange(e, item.name)"
...
...
@@ -141,23 +147,23 @@
<view
class=
"form-bottom"
></view>
<button
v-if=
"pageStatus.btnStatus"
form-type=
"submit"
class=
"form-btn"
>
提交
保存
</button>
</form>
</view>
</
template
>
<
script
setup
>
import
{
ref
}
from
"vue"
;
import
{
ref
,
watch
}
from
"vue"
;
import
PickerCustom
from
"../../components/PickerCustom.vue"
;
const
pageStatus
=
ref
({
formStatus
:
2
,
// 0: 隐藏 1: 展开, 2: 收起
formStatus
:
0
,
// 0: 隐藏 1: 展开, 2: 收起
btnStatus
:
true
,
// 是否显示提交按钮
});
const
formData
=
ref
({
currentBaby
:
""
,
currentBaby
:
"
备孕
"
,
nickName
:
""
,
dateOfBirth
:
""
,
gender
:
""
,
...
...
@@ -167,9 +173,37 @@ const formData = ref({
productLike
:
""
,
specialAttention
:
""
,
channel
:
""
,
avatarUrl
:
""
avatarUrl
:
""
,
});
const
FormMap
=
{
备孕
:
[
"currentBaby"
,
"dateOfBirth"
,
"specialAttention"
],
孕中
:
[
"currentBaby"
,
"dateOfBirth2"
,
"yz"
,
"babyIndex"
,
"contentLike"
,
"specialAttention"
,
],
已出生
:
[
"currentBaby"
,
"nickName"
,
"dateOfBirth"
,
"babyIndex"
,
"gender"
,
"eatFunc"
,
"contentLike"
,
"productLike"
,
"specialAttention"
,
"channel"
,
],
};
const
formItemFilter
=
(
item
)
=>
{
return
FormMap
[
formData
.
value
.
currentBaby
].
includes
(
item
.
name
);
};
const
formItems
=
[
{
label
:
"当前状态"
,
...
...
@@ -177,7 +211,7 @@ const formItems = [
required
:
true
,
placeholder
:
"请选择当前状态"
,
type
:
"picker"
,
range
:
[
"已出生"
,
"
未出生
"
],
range
:
[
"已出生"
,
"
孕中"
,
"备孕
"
],
},
{
label
:
"宝宝昵称"
,
...
...
@@ -191,7 +225,16 @@ const formItems = [
name
:
"dateOfBirth"
,
required
:
true
,
placeholder
:
"请选择出生日期"
,
type
:
"input"
,
type
:
"picker"
,
mode
:
"date"
,
},
{
label
:
"预产日期"
,
name
:
"dateOfBirth2"
,
required
:
true
,
placeholder
:
"请选择预产日期"
,
type
:
"picker"
,
mode
:
"date"
,
},
{
label
:
"宝宝胎数"
,
...
...
@@ -200,6 +243,7 @@ const formItems = [
placeholder
:
"请选择胎数"
,
type
:
"picker"
,
range
:
[
"单胎"
,
"二胎"
,
"多胎"
],
mode
:
"custom"
,
},
{
label
:
"性别"
,
...
...
@@ -208,6 +252,7 @@ const formItems = [
placeholder
:
"请选择性别"
,
type
:
"picker"
,
range
:
[
"男"
,
"女"
],
mode
:
"custom"
,
},
{
label
:
"喂养方式"
,
...
...
@@ -216,6 +261,14 @@ const formItems = [
placeholder
:
"请选择喂养方式"
,
type
:
"picker"
,
range
:
[
"纯母乳"
,
"混合"
,
"奶粉"
],
mode
:
"custom"
,
},
{
label
:
"孕周"
,
name
:
"yz"
,
required
:
false
,
placeholder
:
"请选择"
,
type
:
"input"
,
},
{
label
:
"内容偏好"
,
...
...
@@ -245,19 +298,51 @@ const formItems = [
placeholder
:
"请选择常购买渠道"
,
type
:
"picker"
,
range
:
[
"电商"
,
"母婴店"
,
"超市"
],
mode
:
"custom"
,
},
];
const
getPickerIndex
=
(
item
)
=>
{
const
val
=
formData
.
value
[
item
.
name
];
return
val
?
item
.
range
.
indexOf
(
val
)
:
0
;
if
(
item
.
mode
===
"date"
)
{
// val 形如 '2024-06-01'
if
(
typeof
val
===
"string"
&&
val
.
match
(
/^
\d{4}
-
\d{2}
-
\d{2}
$/
))
{
const
[
year
,
month
,
day
]
=
val
.
split
(
"-"
).
map
(
Number
);
const
currentYear
=
new
Date
().
getFullYear
();
const
yearIdx
=
year
-
1970
;
const
monthIdx
=
month
-
1
;
const
dayIdx
=
day
-
1
;
return
[
yearIdx
,
monthIdx
,
dayIdx
];
}
// 默认选中今年1月1日
const
currentYear
=
new
Date
().
getFullYear
();
return
[
currentYear
-
1970
,
0
,
0
];
}
else
if
(
Array
.
isArray
(
item
.
range
?.[
0
]))
{
// 多列自定义选择
if
(
Array
.
isArray
(
val
))
{
return
val
.
map
((
v
,
col
)
=>
item
.
range
[
col
].
indexOf
(
v
));
}
// 默认选中每列第一个
return
item
.
range
.
map
(()
=>
0
);
}
else
{
// 单列自定义选择
return
val
?
item
.
range
.
indexOf
(
val
)
:
0
;
}
};
const
onPickerChange
=
(
e
,
name
)
=>
{
const
item
=
formItems
.
find
((
i
)
=>
i
.
name
===
name
);
console
.
log
(
item
.
range
,
item
,
e
);
formData
.
value
[
name
]
=
item
.
range
[
e
];
// 日期选择(mode="date"),e 为字符串
if
(
item
.
mode
===
"date"
)
{
formData
.
value
[
name
]
=
e
;
}
else
if
(
Array
.
isArray
(
e
))
{
// 多列自定义选择
formData
.
value
[
name
]
=
e
.
map
((
idx
,
col
)
=>
item
.
range
[
col
][
idx
]).
join
(
" "
);
}
else
{
// 单列自定义选择
formData
.
value
[
name
]
=
item
.
range
[
e
];
}
};
const
onRadioChange
=
(
e
,
name
)
=>
{
formData
.
value
[
name
]
=
e
.
detail
.
value
;
...
...
@@ -277,6 +362,17 @@ const handleFormBottomBtn = () => {
const
onChooseAvatar
=
(
e
)
=>
{
formData
.
value
.
avatarUrl
=
e
.
detail
.
avatarUrl
;
};
watch
(
()
=>
formData
.
value
.
currentBaby
,
(
newVal
)
=>
{
if
(
newVal
===
"已出生"
)
{
pageStatus
.
value
.
formStatus
=
2
;
}
else
{
pageStatus
.
value
.
formStatus
=
0
;
}
}
);
</
script
>
<
style
lang=
"less"
scoped
>
...
...
@@ -343,12 +439,12 @@ const onChooseAvatar = (e) => {
align-items: center;
justify-content: center;
.avatar-wrapper {
display: flex;
align-items: center;
justify-content: center;
padding: 0;
}
.avatar-wrapper {
display: flex;
align-items: center;
justify-content: center;
padding: 0;
}
.person-avatar-img {
width: 126rpx;
...
...
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