Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Hooke
/
custom_form
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Authored by
hookehuyr
2023-04-07 15:56:02 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
0155a4fa55c6552152ad8c1b6951327be885f27c
0155a4fa
1 parent
667cfa9c
✨ feat(选择日期控件): 样式和功能调整
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
108 additions
and
98 deletions
components.d.ts
src/components/DatePickerField/index.vue
src/hooks/useComponentType.js
src/pages/table/index.vue
components.d.ts
View file @
0155a4f
...
...
@@ -32,6 +32,7 @@ declare module '@vue/runtime-core' {
NutCheckbox
:
typeof
import
(
'@nutui/nutui-taro'
)[
'Checkbox'
]
NutCheckboxGroup
:
typeof
import
(
'@nutui/nutui-taro'
)[
'CheckboxGroup'
]
NutConfigProvider
:
typeof
import
(
'@nutui/nutui-taro'
)[
'ConfigProvider'
]
NutDatePicker
:
typeof
import
(
'@nutui/nutui-taro'
)[
'DatePicker'
]
NutDialog
:
typeof
import
(
'@nutui/nutui-taro'
)[
'Dialog'
]
NutDivider
:
typeof
import
(
'@nutui/nutui-taro'
)[
'Divider'
]
NutField
:
typeof
import
(
'@nutui/nutui-taro'
)[
'Field'
]
...
...
src/components/DatePickerField/index.vue
View file @
0155a4f
<!--
* @Date: 2022-08-31 11:45:30
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-0
2-10 10:07
:31
* @FilePath: /
data-table
/src/components/DatePickerField/index.vue
* @LastEditTime: 2023-0
4-07 15:51
:31
* @FilePath: /
custom_form
/src/components/DatePickerField/index.vue
* @Description: 日期选择组件
-->
<template>
<div v-if="HideShow" class="date-picker-field">
<div class="label">
<
span v-if="item.component_props.required"> *</span
>
<
text v-if="item.component_props.required"> *</text
>
{{ item.component_props.label }}
</div>
<van-field
v-model="item.value"
is-link
readonly
:name="item.key"
:required="item.component_props.required"
:disabled="item.component_props.readonly"
:placeholder="item.component_props.placeholder ? item.component_props.placeholder : '请选择日期'"
:rules="rules"
@click="onTap"
:border="false"
/>
<van-popup v-model:show="showPicker" position="bottom">
<van-date-picker
<nut-cell desc-text-align="left" :desc="popupDesc" @click="onTap" is-link style="border: 1px solid #eaeaea; border-radius: 0.25rem; padding: 0.25rem 0.5rem;"></nut-cell>
<div
v-if="show_error"
style="padding: 5px; color: red; font-size: 12px;"
>
{{ error_msg }}
</div>
<nut-popup position="bottom" v-model:visible="showPicker">
<nut-date-picker
v-model="currentDate"
title="日期选择"
:type="columns_type"
:min-date="minDate"
:max-date="maxDate"
:columns-type="columns_type"
@confirm="onConfirm"
@cancel="showPicker = false"
/>
</van-popup>
:is-show-chinese="true"
>
</nut-date-picker>
</nut-popup>
</div>
</template>
<script setup>
import { ref, computed, watch, onMounted, reactive } from "vue";
import dayjs from "dayjs";
const props = defineProps({
item: Object,
});
const emit = defineEmits(["active"]);
// 隐藏显示
const HideShow = computed(() => {
return !props.item.component_props.disabled
})
const showPicker = ref(false);
const currentDate = ref([]);
const popupDesc = ref('请选择');
let minDate = new Date(2020, 0, 1);
let maxDate = new Date(2035, 10, 1);
const currentDate = ref('');
const readonly = props.item.component_props.readonly;
const onTap = () => {
...
...
@@ -57,113 +61,98 @@ const onTap = () => {
showPicker.value = true
}
const onConfirm = ({ selectedValues, selectedOptions }) => {
props.item.value = selectedValues.join("-");
popupDesc.value = selectedOptions.map((val) => val.value).join('-');
props.item.value = {
key: "date",
filed_name: props.item.key,
value: selectedOptions.map((val) => val.value).join('-'),
};
emit("active", props.item.value);
showPicker.value = false;
validDate()
};
const columns_type = ref(
[]
);
const columns_type = ref(
'date'
);
const date_format = props.item.component_props.data_dateformat; // YYYY-MM=年月,YYYY-MM-DD=年月日
// 数字前面补位
const formatZero = (num, len) => {
if (String(num).length > len) {
return num;
}
return (Array(len).join(0) + num).slice(-len)
}
const minDate = ref()
const maxDate = ref()
onMounted(() => {
// 根据默认值时间调整显示
currentDate.value = props.item.component_props.default ? props.item.component_props.default.split("-") : props.item.value.split("-");
let Year = '';
let Month = '';
let Day = '';
if (!props.item.component_props.default) {
Year = String(dayjs().year());
Month = formatZero(dayjs().month(), 2);
Day = formatZero(dayjs().date(), 2);
} else {
Year = currentDate.value[0];
Month = formatZero(currentDate.value[1], 2);
Day = formatZero(currentDate.value[2], 2);
}
currentDate.value = new Date(props.item.component_props.default);
switch (date_format) {
case "YYYY-MM":
columns_type.value = ['year', 'month']
// 设置默认值
currentDate.value = [Year, Month];
columns_type.value = 'year-month'
break;
case "YYYY-MM-DD":
columns_type.value = ['year', 'month', 'day']
// 设置默认值
currentDate.value = [Year, Month, Day];
columns_type.value = 'date'
break;
}
// 设置默认最大最小日期
if (data_minvalue
.length
) {
const min = data_minvalue.split("-")
minDate
.value
= new Date(+min[0], +min[1] - 1, +min[2])
if (data_minvalue) {
const min = data_minvalue.split("-")
;
minDate = new Date(+min[0], +min[1] - 1, +min[2])
}
if (data_maxvalue
.length
) {
if (data_maxvalue) {
const max = data_maxvalue.split("-")
maxDate
.value
= new Date(+max[0], +max[1] - 1, +max[2])
maxDate = new Date(+max[0], +max[1] - 1, +max[2])
}
});
const required = props.item.component_props.required;
const data_minvalue = props.item.component_props.data_minvalue;
const data_maxvalue = props.item.component_props.data_maxvalue;
const validator = (val) => {
if (required && !val) {
return false;
} else if (val && data_minvalue && val < data_minvalue) {
return false;
} else if (val && data_maxvalue && val > data_maxvalue) {
return false;
// 错误提示
const show_error = ref(false);
const error_msg = ref('');
// 校验模块
const validDate = () => {
// 必填项
if (required && !popupDesc.value) {
show_error.value = true;
error_msg.value = '必填项不能为空'
} else if (required && popupDesc.value && data_minvalue && popupDesc.value < data_minvalue) {
show_error.value = true;
error_msg.value = "最小可选:" + data_minvalue;
} else if (required && popupDesc.value && data_maxvalue && popupDesc.value > data_maxvalue) {
show_error.value = true;
error_msg.value = "最大可选:" + data_maxvalue;
} else {
return true;
}
};
// 错误提示文案
const validatorMessage = (val, rule) => {
if (required && !val) {
return "必填项不能为空";
} else if (val && data_minvalue && val < data_minvalue) {
return "最小可选:" + data_minvalue;
} else if (val && data_maxvalue && val > data_maxvalue) {
return "最大可选:" + data_maxvalue;
show_error.value = false;
error_msg.value = ''
}
return !show_error.value;
};
const rules = [{ validator, message: validatorMessage }];
defineExpose({ validDate, id: props.item.key });
</script>
<style lang="less"
scoped
>
<style lang="less">
.date-picker-field {
margin: 1rem;
.label {
// padding: 1rem 1rem 0 1rem
;
font-size:
0.9rem
;
padding-bottom: 20px
;
font-size:
26px
;
font-weight: bold;
span
{
text
{
color: red;
}
}
:deep(.van-icon) { // 处理正式服务器上箭头上下位移问题
font-size: var(--van-cell-icon-size);
line-height: var(--van-cell-line-height);
}
}
//
:deep(.van-icon) { // 处理正式服务器上箭头上下位移问题
//
font-size: var(--van-cell-icon-size);
//
line-height: var(--van-cell-line-height);
//
}
.nut-cell {
:deep(.van-cell--clickable) {
border: 1px solid #eaeaea;
border-radius: 0.25rem;
padding: 0.25rem 0.5rem;
margin-top: 0.5rem;
input {
color: #323233;
}
}
// :deep(.van-cell--clickable) {
// border: 1px solid #eaeaea;
// border-radius: 0.25rem;
// padding: 0.25rem 0.5rem;
// margin-top: 0.5rem;
// input {
// color: #323233;
// }
// }
</style>
...
...
src/hooks/useComponentType.js
View file @
0155a4f
...
...
@@ -5,7 +5,7 @@ import RadioField from '@/components/RadioField/index.vue'
import
CheckboxField
from
'@/components/CheckboxField/index.vue'
import
PickerField
from
'@/components/PickerField/index.vue'
import
AreaPickerField
from
'@/components/AreaPickerField/index.vue'
//
import DatePickerField from '@/components/DatePickerField/index.vue'
import
DatePickerField
from
'@/components/DatePickerField/index.vue'
// import TimePickerField from '@/components/TimePickerField/index.vue'
// import DateTimePickerField from '@/components/DateTimePickerField/index.vue'
// import ImageUploaderField from '@/components/ImageUploaderField/index.vue'
...
...
@@ -60,7 +60,7 @@ import MultiRuleField from '@/components/MultiRuleField/index.vue'
*/
export
function
createComponentType
(
data
)
{
// 判断类型和使用组件
_
.
each
(
data
,
(
item
,
index
)
=>
{
_
.
each
(
data
,
(
item
)
=>
{
// 必填项规则添加
if
(
item
.
component_props
.
required
)
{
item
.
rules
=
[
...
...
@@ -96,9 +96,9 @@ export function createComponentType(data) {
if
(
item
.
component_props
.
tag
===
'address'
)
{
item
.
component
=
AreaPickerField
}
//
if (item.component_props.tag === 'date') {
//
item.component = DatePickerField
//
}
if
(
item
.
component_props
.
tag
===
'date'
)
{
item
.
component
=
DatePickerField
}
// if (item.component_props.tag === 'time') {
// item.component = TimePickerField
// }
...
...
src/pages/table/index.vue
View file @
0155a4f
<!--
* @Date: 2023-03-24 09:19:27
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-04-07 1
3:07:06
* @LastEditTime: 2023-04-07 1
4:30:33
* @FilePath: /custom_form/src/pages/table/index.vue
* @Description: 文件描述
-->
...
...
@@ -136,6 +136,7 @@ const number = ref([]);
const phone = ref([]);
const email = ref([]);
const address = ref([]);
const date = ref([]);
const area_picker = ref([]);
const image_uploader = ref([]);
const file_uploader = ref([]);
...
...
@@ -174,6 +175,9 @@ const setRefMap = (el, item) => {
if (item.component_props.tag === "address") {
address.value.push(el);
}
if (item.component_props.tag === "date") {
date.value.push(el);
}
if (item.component_props.tag === "area_picker") {
area_picker.value.push(el);
}
...
...
@@ -445,6 +449,9 @@ const onActive = (item) => {
if (item.key === "address") {
postData.value[item.filed_name] = item.value;
}
if (item.key === "date") {
postData.value[item.filed_name] = item.value;
}
if (item.key === "image_uploader") {
postData.value[item.filed_name] = item.value;
}
...
...
@@ -601,6 +608,19 @@ const validOther = () => {
}
});
}
if (date.value) {
// 日期选择器
date.value.forEach((item, index) => {
if (!date.value[index].validDate()) {
valid = {
status: date.value[index].validDate(),
key: "date",
id: date.value[index]?.id
};
return false;
}
});
}
if (area_picker.value) {
// 省市区地址
area_picker.value.forEach((item, index) => {
...
...
Please
register
or
login
to post a comment