Commit 0562c9f8 authored by hucy's avatar hucy

fix:修复bug

parent dd997f33
## 2023-01-10
- 表单优化
- 菜单目录变更
## 2022-12-28 ## 2022-12-28
- Ag Grid 表格扩展行学习 - Ag Grid 表格扩展行学习
......
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
// import { date } from 'quasar';
// import { isEmpty } from 'src/common/utils';
import ICON from 'src/config/icons';
interface Props {
modelValue: any;
dense?: boolean;
disable?: boolean;
readonly?: boolean;
config?: any;
}
const props = withDefaults(defineProps<Props>(), {
modelValue: null,
dense: false,
disable: false,
readonly: false,
config: () => {
return {};
},
});
const colorProxyDate = ref<any>(null);
onMounted(() => {
//
});
</script>
<template>
<q-input
v-model="colorProxyDate"
v-bind="config"
:dense="config.dense === undefined ? props.dense : config.dense"
:disable="config.disable === undefined ? props.disable : config.disable"
:readonly="config.readonly === undefined ? props.readonly : config.readonly"
>
<template v-slot:append>
<q-icon
:name="ICON.takeColor"
class="cursor-pointer"
:style="{ color: colorProxyDate }"
>
<q-popup-proxy
v-if="!props.readonly"
transition-show="scale"
transition-hide="scale"
class="row"
>
<q-color v-model="colorProxyDate" v-bind="config" />
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</template>
<style lang="scss" scoped></style>
...@@ -6,12 +6,16 @@ import { isEmpty } from 'src/common/utils'; ...@@ -6,12 +6,16 @@ import { isEmpty } from 'src/common/utils';
interface Props { interface Props {
modelValue: string[] | null; modelValue: string[] | null;
dense?: boolean; dense?: boolean;
disable?: boolean;
readonly?: boolean;
config?: any; config?: any;
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
// modelValue: date.formatDate(Date.now(), 'YYYY/MM/DD HH:mm'), // modelValue: date.formatDate(Date.now(), 'YYYY/MM/DD HH:mm'),
modelValue: null, modelValue: null,
dense: false, dense: false,
disable: false,
readonly: false,
config: () => { config: () => {
return {}; return {};
}, },
...@@ -60,9 +64,20 @@ const dateLocale = reactive({ ...@@ -60,9 +64,20 @@ const dateLocale = reactive({
pluralDay: 'dias', pluralDay: 'dias',
}); });
const toolTipData = computed(() => {
let str = '';
dates.value.map((item: string) => {
str += item + '<br />';
});
return str;
});
onMounted(() => { onMounted(() => {
console.log('999', props.config); const inputElement =
console.log('元素', myDateMultiple.value.$el.firstElementChild); myDateMultiple.value.$el.firstElementChild.firstElementChild
.firstElementChild.firstElementChild;
inputElement.setAttribute('unselectable', 'on');
inputElement.setAttribute('readonly', true);
}); });
function updateProxy() { function updateProxy() {
...@@ -80,10 +95,23 @@ function onClickDate() { ...@@ -80,10 +95,23 @@ function onClickDate() {
</script> </script>
<template> <template>
<div class="hcy-datetime-pick"> <div class="hcy-datetime-pick">
<q-input v-model="dates" v-bind="config" ref="myDateMultiple"> <q-input
v-model="dates"
v-bind="config"
ref="myDateMultiple"
:dense="config.dense === undefined ? props.dense : config.dense"
:disable="config.disable === undefined ? props.disable : config.disable"
:readonly="
config.readonly === undefined ? props.readonly : config.readonly
"
>
<q-tooltip v-if="!isEmpty(dates)">
<span v-html="toolTipData"></span
></q-tooltip>
<template v-slot:append> <template v-slot:append>
<q-icon name="event" class="cursor-pointer"> <q-icon name="event" class="cursor-pointer">
<q-popup-proxy <q-popup-proxy
v-if="!props.readonly"
@before-show="updateProxy" @before-show="updateProxy"
transition-show="scale" transition-show="scale"
transition-hide="scale" transition-hide="scale"
......
<script lang="ts" setup>
import { onMounted, ref, reactive, computed } from 'vue';
// import { date } from 'quasar';
import { isEmpty } from 'src/common/utils';
interface Props {
modelValue: any;
dense?: boolean;
disable?: boolean;
readonly?: boolean;
config?: any;
}
const props = withDefaults(defineProps<Props>(), {
// modelValue: date.formatDate(Date.now(), 'YYYY/MM/DD HH:mm'),
modelValue: null,
dense: false,
disable: false,
readonly: false,
config: () => {
return {};
},
});
const emit = defineEmits<{
(e: 'update:modelValue', value: any): void;
}>();
const myDateRange = ref<any>(null);
const dates = computed({
set(value: any) {
console.log('set', value);
emit('update:modelValue', value);
},
get() {
console.log('get', props.modelValue);
let res = null;
// 多选
if (props.config?.multiple) {
if (isEmpty(props.modelValue)) {
res = null;
} else {
const typeofs = Object.prototype.toString.call(props.modelValue);
if (typeofs === '[object Array]') {
const rangeList = props.modelValue.map((item: any) => {
const str = `${item.from}~${item.to}`;
return str;
});
res = rangeList.join(',');
} else {
res = null;
}
}
}
// 单选
else {
if (isEmpty(props.modelValue)) {
res = null;
} else {
const typeofs = Object.prototype.toString.call(props.modelValue);
if (typeofs === '[object Object]') {
const from = props.modelValue.from;
const to = props.modelValue.to;
if (!from || !to) {
console.warn('无效时间范围');
res = null;
} else {
const fromDate = new Date(from);
const toDate = new Date(to);
if (toDate <= fromDate) {
console.warn('结束时间不能大于开始时间');
res = null;
} else {
res = `${from}~${to}`;
}
}
} else if (typeofs === '[object String]') {
res = props.modelValue;
} else {
res = null;
}
}
}
return res;
},
});
const dateMask = computed(() => {
let obj = {
date: 'YYYY/MM/DD',
};
if (!isEmpty(props.config) && props.config.dateMask) {
const maskList = props.config.dateMask.split(' ');
obj.date = maskList[0];
}
return obj;
});
const dateProxyDate = ref<any>(null);
const dateLocale = reactive({
daysShort: '六_日_一_二_三_四_五'.split('_'),
months:
'一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
'_'
),
monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
firstDayOfWeek: 1,
format24h: true,
pluralDay: 'dias',
});
const toolTipData = computed(() => {
let str = '';
// 多选
if (props.config?.multiple) {
if (!isEmpty(dates.value)) {
str = dates.value.replace(new RegExp(',', 'g'), '<br />');
}
}
// 单选
else {
}
return str;
});
onMounted(() => {
const inputElement =
myDateRange.value.$el.firstElementChild.firstElementChild.firstElementChild
.firstElementChild;
inputElement.setAttribute('unselectable', 'on');
inputElement.setAttribute('readonly', true);
});
function updateProxy() {
const _dates = dates.value;
if (!isEmpty(_dates)) {
// 多选
if (props.config?.multiple) {
console.log('updateProxy', _dates);
const list1 = _dates.split(',');
const rangeList = list1.map((item: any) => {
const rangeArr = item.split('~');
return {
from: rangeArr[0],
to: rangeArr[1],
};
});
dateProxyDate.value = rangeList;
}
// 单选
else {
const dateList = _dates.split('~');
if (dateList.length === 2) {
dateProxyDate.value = {
from: dateList[0],
to: dateList[1],
};
} else if (dateList.length === 1) {
dateProxyDate.value = dateList[0];
} else {
dateProxyDate.value = null;
}
}
} else {
dateProxyDate.value = null;
}
}
function onClickDate() {
console.log('点击确定', dateProxyDate.value);
// 多选
if (props.config?.multiple) {
if (isEmpty(dateProxyDate.value)) {
dates.value = null;
} else {
dates.value = dateProxyDate.value;
}
}
// 单选
else {
if (isEmpty(dateProxyDate.value)) {
dates.value = null;
} else {
dates.value = dateProxyDate.value;
}
}
}
</script>
<template>
<div class="hcy-datetime-pick">
<q-input
v-model="dates"
v-bind="config"
ref="myDateRange"
:dense="config.dense === undefined ? props.dense : config.dense"
:disable="config.disable === undefined ? props.disable : config.disable"
:readonly="
config.readonly === undefined ? props.readonly : config.readonly
"
>
<q-tooltip v-if="!isEmpty(dates) && toolTipData">
<span v-html="toolTipData"></span
></q-tooltip>
<template v-slot:append>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy
v-if="!props.readonly"
@before-show="updateProxy"
transition-show="scale"
transition-hide="scale"
class="row"
>
<q-date
flat
square
minimal
range
:multiple="config.multiple"
v-model="dateProxyDate"
:locale="dateLocale"
:mask="dateMask.date"
class="my-date"
>
<div class="row items-center justify-end q-gutter-sm">
<q-btn
unelevated
label="确定"
size="sm"
color="primary"
@click="onClickDate"
v-close-popup
/>
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</div>
</template>
<style lang="scss" scoped>
.my-date {
:deep(.q-date__main .q-date__content .q-date__view .q-date__navigation) {
> .relative-position {
color: $primary;
}
}
}
.my-time {
:deep(.q-time__header) {
background-color: white;
}
:deep(.q-time__main
.q-time__content
.q-time__container-child
.q-time__clock
.q-time__clock-circle
.q-time__clock-position--active) {
color: white !important;
}
}
</style>
...@@ -7,6 +7,8 @@ interface Props { ...@@ -7,6 +7,8 @@ interface Props {
modelValue: string | null; modelValue: string | null;
format24h?: boolean; format24h?: boolean;
dense?: boolean; dense?: boolean;
disable?: boolean;
readonly?: boolean;
config?: any; config?: any;
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
...@@ -14,6 +16,8 @@ const props = withDefaults(defineProps<Props>(), { ...@@ -14,6 +16,8 @@ const props = withDefaults(defineProps<Props>(), {
modelValue: null, modelValue: null,
format24h: false, format24h: false,
dense: false, dense: false,
disable: false,
readonly: false,
config: () => { config: () => {
return {}; return {};
}, },
...@@ -76,7 +80,7 @@ const dateLocale = reactive({ ...@@ -76,7 +80,7 @@ const dateLocale = reactive({
}); });
onMounted(() => { onMounted(() => {
console.log('999', props.config); // console.log('999', props.config);
getNowDate(); getNowDate();
}); });
...@@ -109,10 +113,19 @@ function onClickDate() { ...@@ -109,10 +113,19 @@ function onClickDate() {
</script> </script>
<template> <template>
<div class="hcy-datetime-pick"> <div class="hcy-datetime-pick">
<q-input v-model="dates" v-bind="config"> <q-input
v-model="dates"
v-bind="config"
:dense="config.dense === undefined ? props.dense : config.dense"
:disable="config.disable === undefined ? props.disable : config.disable"
:readonly="
config.readonly === undefined ? props.readonly : config.readonly
"
>
<template v-slot:append> <template v-slot:append>
<q-icon name="event" class="cursor-pointer"> <q-icon name="event" class="cursor-pointer">
<q-popup-proxy <q-popup-proxy
v-if="!props.readonly"
@before-show="updateProxy" @before-show="updateProxy"
transition-show="scale" transition-show="scale"
transition-hide="scale" transition-hide="scale"
......
...@@ -6,21 +6,30 @@ ...@@ -6,21 +6,30 @@
:key="index" :key="index"
> >
<template v-if="item.solt"> <template v-if="item.solt">
<div> <div class="form-item-solt fit">
<slot :name="item.solt"></slot> <slot :name="item.solt"></slot>
</div> </div>
</template> </template>
<template v-else-if="item.type === 'password'"> <template v-else-if="item.type === 'password'">
<div class="item-content">
<div class="label-title" :class="{ 'text-required': item.required }">
{{ item.label }}
</div>
<q-input <q-input
:type="item.isPwd ? 'password' : 'text'" :type="item.isPwd ? 'password' : 'text'"
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
v-bind="item.bind" v-bind="item.bind"
:dense="
item.bind.dense === undefined ? props.dense : item.bind.dense
"
:disable=" :disable="
item.bind.disable === undefined ? state.disable : item.bind.disable item.bind.disable === undefined
? props.disable
: item.bind.disable
" "
:readonly=" :readonly="
item.bind.readonly === undefined item.bind.readonly === undefined
? state.readonly ? props.readonly
: item.bind.readonly : item.bind.readonly
" "
> >
...@@ -32,36 +41,153 @@ ...@@ -32,36 +41,153 @@
/> />
</template> </template>
</q-input> </q-input>
</div>
</template> </template>
<template v-else-if="item.type === 'date'"> <template v-else-if="item.type === 'date'">
<div class="item-content">
<div class="label-title" :class="{ 'text-required': item.required }">
{{ item.label }}
</div>
<date-time-pick <date-time-pick
:dense="
item.bind.dense === undefined ? props.dense : item.bind.dense
"
:disable="
item.bind.disable === undefined
? props.disable
: item.bind.disable
"
:readonly="
item.bind.readonly === undefined
? props.readonly
: item.bind.readonly
"
format24h format24h
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
:config="item.bind" :config="item.bind"
:label="item.label"
:label-required="item.required"
/> />
</div>
</template> </template>
<template v-else-if="item.type === 'time'"> <template v-else-if="item.type === 'time'">
<div class="item-content">
<div class="label-title" :class="{ 'text-required': item.required }">
{{ item.label }}
</div>
<time-pick <time-pick
format24h format24h
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
:config="item.bind" :config="item.bind"
:dense="
item.bind.dense === undefined ? props.dense : item.bind.dense
"
:disable="
item.bind.disable === undefined
? props.disable
: item.bind.disable
"
:readonly="
item.bind.readonly === undefined
? props.readonly
: item.bind.readonly
"
/> />
</div>
</template> </template>
<template v-else-if="item.type === 'dateMultiple'"> <template v-else-if="item.type === 'dateMultiple'">
<date-multiple v-model="formValue[item.fild]" :config="item.bind" /> <div class="item-content">
<div class="label-title" :class="{ 'text-required': item.required }">
{{ item.label }}
</div>
<date-multiple
v-model="formValue[item.fild]"
:config="item.bind"
:dense="
item.bind.dense === undefined ? props.dense : item.bind.dense
"
:disable="
item.bind.disable === undefined
? props.disable
: item.bind.disable
"
:readonly="
item.bind.readonly === undefined
? props.readonly
: item.bind.readonly
"
/>
</div>
</template>
<template v-else-if="item.type === 'dateRange'">
<div class="item-content">
<div class="label-title" :class="{ 'text-required': item.required }">
{{ item.label }}
</div>
<date-range
v-model="formValue[item.fild]"
:config="item.bind"
:dense="
item.bind.dense === undefined ? props.dense : item.bind.dense
"
:disable="
item.bind.disable === undefined
? props.disable
: item.bind.disable
"
:readonly="
item.bind.readonly === undefined
? props.readonly
: item.bind.readonly
"
/>
</div>
</template>
<template v-else-if="item.type === 'color'">
<div class="item-content">
<div class="label-title" :class="{ 'text-required': item.required }">
{{ item.label }}
</div>
<color-pick
v-model="formValue[item.fild]"
:config="item.bind"
:dense="
item.bind.dense === undefined ? props.dense : item.bind.dense
"
:disable="
item.bind.disable === undefined
? props.disable
: item.bind.disable
"
:readonly="
item.bind.readonly === undefined
? props.readonly
: item.bind.readonly
"
/>
</div>
</template> </template>
<template v-else> <template v-else>
<div class="item-content">
<div class="label-title" :class="{ 'text-required': item.required }">
{{ item.label }}
</div>
<q-input <q-input
v-if="item.type !== 'select'" v-if="item.type !== 'select'"
:type="item.type" :type="item.type"
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
v-bind="item.bind" v-bind="item.bind"
:dense="
item.bind.dense === undefined ? props.dense : item.bind.dense
"
:disable=" :disable="
item.bind.disable === undefined ? state.disable : item.bind.disable item.bind.disable === undefined
? props.disable
: item.bind.disable
" "
:readonly=" :readonly="
item.bind.readonly === undefined item.bind.readonly === undefined
? state.readonly ? props.readonly
: item.bind.readonly : item.bind.readonly
" "
/> />
...@@ -69,15 +195,21 @@ ...@@ -69,15 +195,21 @@
v-if="item.type === 'select'" v-if="item.type === 'select'"
v-bind="item.bind" v-bind="item.bind"
v-model="formValue[item.fild]" v-model="formValue[item.fild]"
:dense="
item.bind.dense === undefined ? props.dense : item.bind.dense
"
:disable=" :disable="
item.bind.disable === undefined ? state.disable : item.bind.disable item.bind.disable === undefined
? props.disable
: item.bind.disable
" "
:readonly=" :readonly="
item.bind.readonly === undefined item.bind.readonly === undefined
? state.readonly ? props.readonly
: item.bind.readonly : item.bind.readonly
" "
/> />
</div>
</template> </template>
</div> </div>
</q-form> </q-form>
...@@ -87,6 +219,8 @@ import { onMounted, reactive, ref, watch } from 'vue'; ...@@ -87,6 +219,8 @@ import { onMounted, reactive, ref, watch } from 'vue';
import DateTimePick from './DateTimePick.vue'; import DateTimePick from './DateTimePick.vue';
import TimePick from './TimePick.vue'; import TimePick from './TimePick.vue';
import DateMultiple from './DateMultiple.vue'; import DateMultiple from './DateMultiple.vue';
import DateRange from './DateRange.vue';
import ColorPick from './ColorPick.vue';
import { cloneDeep, isObjEqual } from 'src/common/utils'; import { cloneDeep, isObjEqual } from 'src/common/utils';
interface Props { interface Props {
...@@ -94,6 +228,7 @@ interface Props { ...@@ -94,6 +228,7 @@ interface Props {
modelValue: any; modelValue: any;
disable?: boolean; disable?: boolean;
readonly?: boolean; readonly?: boolean;
dense?: boolean;
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
config: () => { config: () => {
...@@ -104,6 +239,7 @@ const props = withDefaults(defineProps<Props>(), { ...@@ -104,6 +239,7 @@ const props = withDefaults(defineProps<Props>(), {
}, },
disable: false, disable: false,
readonly: false, readonly: false,
dense: false,
}); });
defineExpose({ defineExpose({
...@@ -119,8 +255,6 @@ const myForm = ref<any>(null); ...@@ -119,8 +255,6 @@ const myForm = ref<any>(null);
const state = reactive({ const state = reactive({
config: cloneDeep(props.config), config: cloneDeep(props.config),
disable: props.disable,
readonly: props.readonly,
}); });
const formValue = ref<any>(cloneDeep(props.modelValue)); const formValue = ref<any>(cloneDeep(props.modelValue));
...@@ -177,4 +311,19 @@ function reset() { ...@@ -177,4 +311,19 @@ function reset() {
.item { .item {
padding: $padding-sm; padding: $padding-sm;
} }
.item-content {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
.label-title {
height: 22px;
font-size: 14px;
line-height: 22px;
color: $gray-text;
margin-bottom: 2px;
display: inline-block;
}
</style> </style>
...@@ -7,6 +7,8 @@ interface Props { ...@@ -7,6 +7,8 @@ interface Props {
modelValue: string | null; modelValue: string | null;
format24h?: boolean; format24h?: boolean;
dense?: boolean; dense?: boolean;
disable?: boolean;
readonly?: boolean;
config?: any; config?: any;
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
...@@ -14,6 +16,8 @@ const props = withDefaults(defineProps<Props>(), { ...@@ -14,6 +16,8 @@ const props = withDefaults(defineProps<Props>(), {
modelValue: null, modelValue: null,
format24h: false, format24h: false,
dense: false, dense: false,
disable: false,
readonly: false,
config: () => { config: () => {
return {}; return {};
}, },
...@@ -66,10 +70,19 @@ function onClickDate() { ...@@ -66,10 +70,19 @@ function onClickDate() {
</script> </script>
<template> <template>
<div class="hcy-datetime-pick"> <div class="hcy-datetime-pick">
<q-input v-model="dates" v-bind="config"> <q-input
v-model="dates"
v-bind="config"
:dense="config.dense === undefined ? props.dense : config.dense"
:disable="config.disable === undefined ? props.disable : config.disable"
:readonly="
config.readonly === undefined ? props.readonly : config.readonly
"
>
<template v-slot:append> <template v-slot:append>
<q-icon name="access_time" class="cursor-pointer"> <q-icon name="access_time" class="cursor-pointer">
<q-popup-proxy <q-popup-proxy
v-if="!props.readonly"
@before-show="updateProxy" @before-show="updateProxy"
transition-show="scale" transition-show="scale"
transition-hide="scale" transition-hide="scale"
......
import DateTimePick from './DateTimePick.vue'; import DateTimePick from './DateTimePick.vue';
import TimePick from './TimePick.vue'; import TimePick from './TimePick.vue';
import DateMultiple from './DateMultiple.vue'; import DateMultiple from './DateMultiple.vue';
import DateRange from './DateRange.vue';
import ColorPick from './ColorPick.vue';
import BaiduMap from './BaiduMap.vue'; import BaiduMap from './BaiduMap.vue';
import MyForm from './MyForm.vue'; import MyForm from './MyForm.vue';
...@@ -17,6 +19,8 @@ export { ...@@ -17,6 +19,8 @@ export {
DateTimePick as ComDateTimePick, DateTimePick as ComDateTimePick,
TimePick as ComTimePick, TimePick as ComTimePick,
DateMultiple as ComDateMultiple, DateMultiple as ComDateMultiple,
DateRange as ComDateRange,
ColorPick as ComColorPick,
BaiduMap as ComBaiduMap, BaiduMap as ComBaiduMap,
MyForm as ComForm, MyForm as ComForm,
MyTooltip as ComTooltip, MyTooltip as ComTooltip,
...@@ -33,6 +37,8 @@ export default { ...@@ -33,6 +37,8 @@ export default {
DateTimePick, DateTimePick,
TimePick, TimePick,
DateMultiple, DateMultiple,
DateRange,
ColorPick,
BaiduMap, BaiduMap,
MyForm, MyForm,
MyTooltip, MyTooltip,
......
...@@ -34,6 +34,18 @@ a:hover { ...@@ -34,6 +34,18 @@ a:hover {
background: #df7861; background: #df7861;
} }
// 必填
.text-required::before {
content: '*';
display: inline-block;
height: 22px;
font-size: 14px;
color: $negative;
margin-right: 4px;
transform: scale(1.5) translateY(1px);
// transform: translateY(5px);
}
// tooltip样式 // tooltip样式
.com-tooltip-sty { .com-tooltip-sty {
border: 1px solid rgba(9, 30, 66, 0.13); border: 1px solid rgba(9, 30, 66, 0.13);
......
...@@ -13,13 +13,7 @@ export const MenuList = [ ...@@ -13,13 +13,7 @@ export const MenuList = [
link: '/page1', link: '/page1',
active: false, active: false,
}, },
{
title: '贰',
caption: '表单',
icon: require('./menuListIcons/page2.svg'),
link: '/page2',
active: false,
},
{ {
title: '四', title: '四',
caption: 'canvas小车动画', caption: 'canvas小车动画',
...@@ -48,6 +42,21 @@ export const MenuList = [ ...@@ -48,6 +42,21 @@ export const MenuList = [
link: '/page10', link: '/page10',
active: false, active: false,
}, },
{
title: '表单',
caption: '',
icon: '',
active: false,
children: [
{
title: '贰',
caption: '表单',
icon: require('./menuListIcons/page2.svg'),
link: '/page2',
active: false,
},
],
},
{ {
title: '学习', title: '学习',
caption: '杂七杂八', caption: '杂七杂八',
......
<template> <template>
<div class="container-height column no-wrap justify-center items-center"> <div class="page">
<div class="q-gutter-xs"> <div class="actions">
<q-toggle v-model="state.dense" label="Dense" />
<q-toggle v-model="state.disable" label="Disable" />
<q-toggle v-model="state.readonly" label="Readonly" />
<q-btn label="提交" color="primary" @click="onSubmit" /> <q-btn label="提交" color="primary" @click="onSubmit" />
<q-btn label="重置" color="primary" @click="onResetForm" /> <q-btn label="重置" color="primary" @click="onResetForm" />
<q-btn label="改变" color="primary" @click="onChange" /> <q-btn label="改变" color="primary" @click="onChange" />
...@@ -8,31 +11,44 @@ ...@@ -8,31 +11,44 @@
<div class="page2-form"> <div class="page2-form">
<Com.MyForm <Com.MyForm
ref="myForm" ref="myForm"
:dense="state.dense"
:disable="state.disable"
:readonly="state.readonly"
:config="formState.config" :config="formState.config"
v-model="formState.value" v-model="formState.value"
> >
<template #solt2>
<q-input filled v-model="formState.value.color" label="颜色">
<template v-slot:append>
<q-icon
class="cursor-pointer"
:name="ICON.takeColor"
:style="{ color: formState.value.color }"
>
<q-popup-proxy :breakpoint="600">
<q-color
v-model="formState.value.color"
default-view="palette"
:palette="colorPalette"
/>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</template>
<template #test> <template #test>
<div>测试</div> <div>测试</div>
</template> </template>
<template #class>
<div class="item-content">
<div class="label-title text-required">班级</div>
<div class="label-content">
<q-option-group
v-model="formState.value.class"
:options="classOpt"
color="primary"
inline
:disable="state.disable || state.readonly"
/>
</div>
</div>
</template>
<template #workingDay>
<div class="item-content">
<div class="label-title text-required">工作日</div>
<div class="label-content">
<q-option-group
v-model="formState.value.workingDay"
color="primary"
type="checkbox"
:options="workingDayOpt"
inline
:disable="state.disable || state.readonly"
/>
</div>
</div>
</template>
</Com.MyForm> </Com.MyForm>
</div> </div>
</div> </div>
...@@ -44,27 +60,102 @@ export default { ...@@ -44,27 +60,102 @@ export default {
</script> </script>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue'; import { onMounted, reactive, ref } from 'vue';
import { delEmptyObjkey } from 'src/common/utils'; import { useMessage } from 'src/common/hooks';
import ICON from 'src/config/icons'; import { delEmptyObjkey, isEmpty } from 'src/common/utils';
import Com from 'src/components'; import Com from 'src/components';
import { form } from './config'; import { form } from './config';
import COLORLIST from './colorList'; import COLORLIST from './colorList';
const { success, warn } = useMessage();
const myForm = ref<any>(null); const myForm = ref<any>(null);
const colorPalette = ref<any>([]); const colorPalette = ref<any>([]);
const classOpt = reactive([
{
label: 'A班',
value: 'a',
},
{
label: 'B班',
value: 'b',
},
{
label: 'C班',
value: 'c',
},
]);
const workingDayOpt = reactive([
{
label: '周一',
value: 'mon',
},
{
label: '周二',
value: 'tue',
},
{
label: '周三',
value: 'wed',
},
{
label: '周四',
value: 'thu',
},
{
label: '周五',
value: 'fri',
},
]);
const formState = reactive({ const formState = reactive({
config: form, config: [] as any[],
value: { value: {
name: '法外狂徒张三',
date1: '2022-12-31 12:30:30', date1: '2022-12-31 12:30:30',
dateMultiple: ['2023/01/23', '2023/01/24'],
dateRange: {
from: '2023-01-16',
to: '2023-01-19',
},
dateRangeMultiple: [
{
from: '2023/01/16',
to: '2023/01/19',
},
{
from: '2023/01/23',
to: '2023/01/31',
},
],
class: 'a',
workingDay: [] as any[],
} as any, } as any,
}); });
const state = reactive({
dense: false,
disable: false,
readonly: false,
});
onMounted(() => { onMounted(() => {
getColorList(); getColorList();
initFormConfig();
}); });
function initFormConfig() {
formState.config = form.map((item: any) => {
let obj: any = { ...item };
if (obj.fild === 'colorPick2') {
obj.bind.palette = colorPalette.value;
}
return obj;
});
}
function getColorList() { function getColorList() {
let arr: any[] = []; let arr: any[] = [];
const length = 7; const length = 7;
...@@ -114,8 +205,12 @@ function onChange() { ...@@ -114,8 +205,12 @@ function onChange() {
} }
function onSubmit() { function onSubmit() {
myForm.value.validate().then((success: any) => { myForm.value.validate().then((suc: any) => {
if (!success) return; if (!suc) return;
if (isEmpty(formState.value.workingDay)) {
return warn('工作日必填');
}
success('校验通过');
console.log('formValue', delEmptyObjkey(formState.value)); console.log('formValue', delEmptyObjkey(formState.value));
}); });
} }
...@@ -126,10 +221,47 @@ function onResetForm() { ...@@ -126,10 +221,47 @@ function onResetForm() {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.page {
display: flex;
flex-direction: column;
align-items: center;
}
.actions {
display: flex;
column-gap: 10px;
padding: 8px;
margin-top: 20px;
height: 56px;
}
.page2-form { .page2-form {
margin-top: $padding-sm; margin-top: $padding-sm;
margin-bottom: 20px;
width: 800px; width: 800px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid $border-color; border: 1px solid $border-color;
} }
.item-content {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
.label-title {
height: 22px;
font-size: 14px;
line-height: 22px;
color: rgba(0, 0, 0, 0.871);
margin-bottom: 2px;
display: inline-block;
}
.label-content {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
// padding: 0 12px;
background-color: rgba(0, 0, 0, 0.05);
border-radius: 4px 4px 0 0;
}
</style> </style>
export const form = [ export const form = [
{ {
fild: 'name', fild: 'name',
label: '姓名',
col: 'col-6', col: 'col-6',
type: 'text', type: 'text',
required: true,
bind: { bind: {
readonly: true,
filled: true, filled: true,
label: '姓名*',
lazyRules: true, lazyRules: true,
hideBottomSpace: true, hideBottomSpace: true,
rules: [(val: any) => (val && val.length > 0) || '必填'], rules: [(val: any) => (val && val.length > 0) || '必填'],
...@@ -13,32 +15,32 @@ export const form = [ ...@@ -13,32 +15,32 @@ export const form = [
}, },
{ {
fild: 'password', fild: 'password',
label: '密码',
col: 'col-6', col: 'col-6',
type: 'password', type: 'password',
isPwd: true, isPwd: true,
bind: { bind: {
filled: true, filled: true,
label: '密码*', // lazyRules: true,
lazyRules: true, // hideBottomSpace: true,
hideBottomSpace: true, // rules: [(val: any) => (val && val.length > 0) || '必填'],
rules: [(val: any) => (val && val.length > 0) || '必填'],
}, },
}, },
{ {
fild: 'age', fild: 'age',
col: 'col-6', col: 'col-6',
label: '年龄',
type: 'number', type: 'number',
bind: { bind: {
filled: true, filled: true,
label: '年龄',
}, },
}, },
{ {
fild: 'country', fild: 'country',
label: '国家',
col: 'col-6', col: 'col-6',
type: 'select', type: 'select',
bind: { bind: {
label: '国家*',
filled: true, filled: true,
emitValue: true, emitValue: true,
mapOptions: true, mapOptions: true,
...@@ -56,52 +58,44 @@ export const form = [ ...@@ -56,52 +58,44 @@ export const form = [
value: 'france', value: 'france',
}, },
], ],
lazyRules: true, // lazyRules: true,
hideBottomSpace: true, // hideBottomSpace: true,
rules: [(val: any) => (val && val.length > 0) || '必填'], // rules: [(val: any) => (val && val.length > 0) || '必填'],
clearable: true, clearable: true,
}, },
}, },
{ {
fild: 'quantity', fild: 'quantity',
label: '数量',
col: 'col-6', col: 'col-6',
type: 'number', type: 'number',
bind: { bind: {
filled: true, filled: true,
label: '数量',
}, },
}, },
{ {
solt: 'solt2', solt: 'class',
col: 'col-6', col: 'col-6',
}, },
{ {
fild: 'remark', fild: 'remark',
label: '备注',
col: 'col-12', col: 'col-12',
type: 'textarea', type: 'textarea',
bind: { bind: {
filled: true, filled: true,
label: '备注',
},
}, },
{
solt: 'test',
col: 'col-6',
}, },
{ {
fild: 'aaa', solt: 'workingDay',
col: 'col-6', col: 'col-6',
type: 'text',
bind: {
label: '测试',
},
}, },
{ {
fild: 'date1', fild: 'date1',
col: 'col-6', col: 'col-6',
type: 'date', type: 'date',
bind: {
label: '日期1', label: '日期1',
bind: {
filled: true, filled: true,
clearable: true, clearable: true,
dateMask: 'YYYY-MM-DD HH:mm:ss', dateMask: 'YYYY-MM-DD HH:mm:ss',
...@@ -109,10 +103,10 @@ export const form = [ ...@@ -109,10 +103,10 @@ export const form = [
}, },
{ {
fild: 'date2', fild: 'date2',
label: '日期2',
col: 'col-6', col: 'col-6',
type: 'date', type: 'date',
bind: { bind: {
label: '日期2',
filled: true, filled: true,
clearable: true, clearable: true,
dateMask: 'YYYY-MM-DD', dateMask: 'YYYY-MM-DD',
...@@ -120,10 +114,10 @@ export const form = [ ...@@ -120,10 +114,10 @@ export const form = [
}, },
{ {
fild: 'dateMultiple', fild: 'dateMultiple',
label: '日期多选',
col: 'col-6', col: 'col-6',
type: 'dateMultiple', type: 'dateMultiple',
bind: { bind: {
label: '日期多选',
filled: true, filled: true,
clearable: true, clearable: true,
dateMask: 'YYYY/MM/DD', dateMask: 'YYYY/MM/DD',
...@@ -131,10 +125,22 @@ export const form = [ ...@@ -131,10 +125,22 @@ export const form = [
}, },
{ {
fild: 'dateRange', fild: 'dateRange',
label: '日期范围',
col: 'col-6', col: 'col-6',
type: 'dateRange', type: 'dateRange',
bind: { bind: {
label: '日期范围', filled: true,
clearable: true,
dateMask: 'YYYY-MM-DD',
},
},
{
fild: 'dateRangeMultiple',
label: '日期范围多选',
col: 'col-6',
type: 'dateRange',
bind: {
multiple: true,
filled: true, filled: true,
clearable: true, clearable: true,
dateMask: 'YYYY/MM/DD', dateMask: 'YYYY/MM/DD',
...@@ -142,13 +148,35 @@ export const form = [ ...@@ -142,13 +148,35 @@ export const form = [
}, },
{ {
fild: 'time1', fild: 'time1',
label: '时间1',
col: 'col-6', col: 'col-6',
type: 'time', type: 'time',
bind: { bind: {
label: '时间1',
filled: true, filled: true,
clearable: true, clearable: true,
timeMask: 'HH:mm', timeMask: 'HH:mm:ss',
},
},
{
fild: 'colorPick',
label: '选取颜色',
col: 'col-6',
type: 'color',
bind: {
filled: true,
clearable: true,
},
},
{
fild: 'colorPick2',
label: '选取颜色2',
col: 'col-6',
type: 'color',
bind: {
filled: true,
clearable: true,
defaultView: 'palette',
palette: [],
}, },
}, },
]; ];
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment