Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
V
vue3-quasar-ts-study01
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
hucy
vue3-quasar-ts-study01
Commits
0562c9f8
Commit
0562c9f8
authored
Jan 10, 2023
by
hucy
☘
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:修复bug
parent
dd997f33
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
848 additions
and
129 deletions
+848
-129
CHANGELOG.md
CHANGELOG.md
+5
-0
ColorPick.vue
src/components/ColorPick.vue
+57
-0
DateMultiple.vue
src/components/DateMultiple.vue
+31
-3
DateRange.vue
src/components/DateRange.vue
+267
-0
DateTimePick.vue
src/components/DateTimePick.vue
+15
-2
MyForm.vue
src/components/MyForm.vue
+211
-62
TimePick.vue
src/components/TimePick.vue
+14
-1
index.ts
src/components/index.ts
+6
-0
app.scss
src/css/app.scss
+12
-0
config.ts
src/layouts/config.ts
+16
-7
IndexPage.vue
src/modules/page2/IndexPage.vue
+158
-26
config.ts
src/modules/page2/config.ts
+56
-28
No files found.
CHANGELOG.md
View file @
0562c9f8
## 2023-01-10
-
表单优化
-
菜单目录变更
## 2022-12-28
-
Ag Grid 表格扩展行学习
...
...
src/components/ColorPick.vue
0 → 100644
View file @
0562c9f8
<
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
>
src/components/DateMultiple.vue
View file @
0562c9f8
...
...
@@ -6,12 +6,16 @@ import { isEmpty } from 'src/common/utils';
interface
Props
{
modelValue
:
string
[]
|
null
;
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
{};
},
...
...
@@ -60,9 +64,20 @@ const dateLocale = reactive({
pluralDay
:
'dias'
,
});
const
toolTipData
=
computed
(()
=>
{
let
str
=
''
;
dates
.
value
.
map
((
item
:
string
)
=>
{
str
+=
item
+
'<br />'
;
});
return
str
;
});
onMounted
(()
=>
{
console
.
log
(
'999'
,
props
.
config
);
console
.
log
(
'元素'
,
myDateMultiple
.
value
.
$el
.
firstElementChild
);
const
inputElement
=
myDateMultiple
.
value
.
$el
.
firstElementChild
.
firstElementChild
.
firstElementChild
.
firstElementChild
;
inputElement
.
setAttribute
(
'unselectable'
,
'on'
);
inputElement
.
setAttribute
(
'readonly'
,
true
);
});
function
updateProxy
()
{
...
...
@@ -80,10 +95,23 @@ function onClickDate() {
</
script
>
<
template
>
<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
>
<q-icon
name=
"event"
class=
"cursor-pointer"
>
<q-popup-proxy
v-if=
"!props.readonly"
@
before-show=
"updateProxy"
transition-show=
"scale"
transition-hide=
"scale"
...
...
src/components/DateRange.vue
0 → 100644
View file @
0562c9f8
<
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
>
src/components/DateTimePick.vue
View file @
0562c9f8
...
...
@@ -7,6 +7,8 @@ interface Props {
modelValue
:
string
|
null
;
format24h
?:
boolean
;
dense
?:
boolean
;
disable
?:
boolean
;
readonly
?:
boolean
;
config
?:
any
;
}
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
...
...
@@ -14,6 +16,8 @@ const props = withDefaults(defineProps<Props>(), {
modelValue
:
null
,
format24h
:
false
,
dense
:
false
,
disable
:
false
,
readonly
:
false
,
config
:
()
=>
{
return
{};
},
...
...
@@ -76,7 +80,7 @@ const dateLocale = reactive({
});
onMounted
(()
=>
{
console
.
log
(
'999'
,
props
.
config
);
//
console.log('999', props.config);
getNowDate
();
});
...
...
@@ -109,10 +113,19 @@ function onClickDate() {
</
script
>
<
template
>
<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
>
<q-icon
name=
"event"
class=
"cursor-pointer"
>
<q-popup-proxy
v-if=
"!props.readonly"
@
before-show=
"updateProxy"
transition-show=
"scale"
transition-hide=
"scale"
...
...
src/components/MyForm.vue
View file @
0562c9f8
...
...
@@ -6,78 +6,210 @@
:key=
"index"
>
<template
v-if=
"item.solt"
>
<div>
<div
class=
"form-item-solt fit"
>
<slot
:name=
"item.solt"
></slot>
</div>
</
template
>
<
template
v-else-if=
"item.type === 'password'"
>
<q-input
:type=
"item.isPwd ? 'password' : 'text'"
v-model=
"formValue[item.fild]"
v-bind=
"item.bind"
:disable=
"
item.bind.disable === undefined ? state.disable : item.bind.disable
"
:readonly=
"
item.bind.readonly === undefined
? state.readonly
: item.bind.readonly
"
>
<template
v-slot:append
>
<q-icon
:name=
"item.isPwd ? 'visibility_off' : 'visibility'"
class=
"cursor-pointer"
@
click=
"item.isPwd = !item.isPwd"
/>
</
template
>
</q-input>
<div
class=
"item-content"
>
<div
class=
"label-title"
:class=
"
{ 'text-required': item.required }">
{{
item
.
label
}}
</div>
<q-input
:type=
"item.isPwd ? 'password' : 'text'"
v-model=
"formValue[item.fild]"
v-bind=
"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
"
>
<template
v-slot:append
>
<q-icon
:name=
"item.isPwd ? 'visibility_off' : 'visibility'"
class=
"cursor-pointer"
@
click=
"item.isPwd = !item.isPwd"
/>
</
template
>
</q-input>
</div>
</template>
<
template
v-else-if=
"item.type === 'date'"
>
<date-time-pick
format24h
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-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
v-model=
"formValue[item.fild]"
:config=
"item.bind"
:label=
"item.label"
:label-required=
"item.required"
/>
</div>
</
template
>
<
template
v-else-if=
"item.type === 'time'"
>
<time-pick
format24h
v-model=
"formValue[item.fild]"
:config=
"item.bind"
/>
<div
class=
"item-content"
>
<div
class=
"label-title"
:class=
"
{ 'text-required': item.required }">
{{
item
.
label
}}
</div>
<time-pick
format24h
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 === '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
v-else
>
<q-input
v-if=
"item.type !== 'select'"
:type=
"item.type"
v-model=
"formValue[item.fild]"
v-bind=
"item.bind"
:disable=
"
item.bind.disable === undefined ? state.disable : item.bind.disable
"
:readonly=
"
item.bind.readonly === undefined
? state.readonly
: item.bind.readonly
"
/>
<q-select
v-if=
"item.type === 'select'"
v-bind=
"item.bind"
v-model=
"formValue[item.fild]"
:disable=
"
item.bind.disable === undefined ? state.disable : item.bind.disable
"
:readonly=
"
item.bind.readonly === undefined
? state.readonly
: item.bind.readonly
"
/>
<div
class=
"item-content"
>
<div
class=
"label-title"
:class=
"
{ 'text-required': item.required }">
{{
item
.
label
}}
</div>
<q-input
v-if=
"item.type !== 'select'"
:type=
"item.type"
v-model=
"formValue[item.fild]"
v-bind=
"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
"
/>
<q-select
v-if=
"item.type === 'select'"
v-bind=
"item.bind"
v-model=
"formValue[item.fild]"
: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
>
</div>
</q-form>
...
...
@@ -87,6 +219,8 @@ import { onMounted, reactive, ref, watch } from 'vue';
import
DateTimePick
from
'./DateTimePick.vue'
;
import
TimePick
from
'./TimePick.vue'
;
import
DateMultiple
from
'./DateMultiple.vue'
;
import
DateRange
from
'./DateRange.vue'
;
import
ColorPick
from
'./ColorPick.vue'
;
import
{
cloneDeep
,
isObjEqual
}
from
'src/common/utils'
;
interface
Props
{
...
...
@@ -94,6 +228,7 @@ interface Props {
modelValue
:
any
;
disable
?:
boolean
;
readonly
?:
boolean
;
dense
?:
boolean
;
}
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
config
:
()
=>
{
...
...
@@ -104,6 +239,7 @@ const props = withDefaults(defineProps<Props>(), {
},
disable
:
false
,
readonly
:
false
,
dense
:
false
,
});
defineExpose
({
...
...
@@ -119,8 +255,6 @@ const myForm = ref<any>(null);
const
state
=
reactive
({
config
:
cloneDeep
(
props
.
config
),
disable
:
props
.
disable
,
readonly
:
props
.
readonly
,
});
const
formValue
=
ref
<
any
>
(
cloneDeep
(
props
.
modelValue
));
...
...
@@ -177,4 +311,19 @@ function reset() {
.item
{
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
>
src/components/TimePick.vue
View file @
0562c9f8
...
...
@@ -7,6 +7,8 @@ interface Props {
modelValue
:
string
|
null
;
format24h
?:
boolean
;
dense
?:
boolean
;
disable
?:
boolean
;
readonly
?:
boolean
;
config
?:
any
;
}
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
...
...
@@ -14,6 +16,8 @@ const props = withDefaults(defineProps<Props>(), {
modelValue
:
null
,
format24h
:
false
,
dense
:
false
,
disable
:
false
,
readonly
:
false
,
config
:
()
=>
{
return
{};
},
...
...
@@ -66,10 +70,19 @@ function onClickDate() {
</
script
>
<
template
>
<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
>
<q-icon
name=
"access_time"
class=
"cursor-pointer"
>
<q-popup-proxy
v-if=
"!props.readonly"
@
before-show=
"updateProxy"
transition-show=
"scale"
transition-hide=
"scale"
...
...
src/components/index.ts
View file @
0562c9f8
import
DateTimePick
from
'./DateTimePick.vue'
;
import
TimePick
from
'./TimePick.vue'
;
import
DateMultiple
from
'./DateMultiple.vue'
;
import
DateRange
from
'./DateRange.vue'
;
import
ColorPick
from
'./ColorPick.vue'
;
import
BaiduMap
from
'./BaiduMap.vue'
;
import
MyForm
from
'./MyForm.vue'
;
...
...
@@ -17,6 +19,8 @@ export {
DateTimePick
as
ComDateTimePick
,
TimePick
as
ComTimePick
,
DateMultiple
as
ComDateMultiple
,
DateRange
as
ComDateRange
,
ColorPick
as
ComColorPick
,
BaiduMap
as
ComBaiduMap
,
MyForm
as
ComForm
,
MyTooltip
as
ComTooltip
,
...
...
@@ -33,6 +37,8 @@ export default {
DateTimePick
,
TimePick
,
DateMultiple
,
DateRange
,
ColorPick
,
BaiduMap
,
MyForm
,
MyTooltip
,
...
...
src/css/app.scss
View file @
0562c9f8
...
...
@@ -34,6 +34,18 @@ a:hover {
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样式
.com-tooltip-sty
{
border
:
1px
solid
rgba
(
9
,
30
,
66
,
0
.13
);
...
...
src/layouts/config.ts
View file @
0562c9f8
...
...
@@ -13,13 +13,7 @@ export const MenuList = [
link
:
'/page1'
,
active
:
false
,
},
{
title
:
'贰'
,
caption
:
'表单'
,
icon
:
require
(
'./menuListIcons/page2.svg'
),
link
:
'/page2'
,
active
:
false
,
},
{
title
:
'四'
,
caption
:
'canvas小车动画'
,
...
...
@@ -48,6 +42,21 @@ export const MenuList = [
link
:
'/page10'
,
active
:
false
,
},
{
title
:
'表单'
,
caption
:
''
,
icon
:
''
,
active
:
false
,
children
:
[
{
title
:
'贰'
,
caption
:
'表单'
,
icon
:
require
(
'./menuListIcons/page2.svg'
),
link
:
'/page2'
,
active
:
false
,
},
],
},
{
title
:
'学习'
,
caption
:
'杂七杂八'
,
...
...
src/modules/page2/IndexPage.vue
View file @
0562c9f8
<
template
>
<div
class=
"container-height column no-wrap justify-center items-center"
>
<div
class=
"q-gutter-xs"
>
<div
class=
"page"
>
<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=
"onResetForm"
/>
<q-btn
label=
"改变"
color=
"primary"
@
click=
"onChange"
/>
...
...
@@ -8,31 +11,44 @@
<div
class=
"page2-form"
>
<Com
.
MyForm
ref=
"myForm"
:dense=
"state.dense"
:disable=
"state.disable"
:readonly=
"state.readonly"
:config=
"formState.config"
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
>
<div>
测试
</div>
</
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
>
</div>
</div>
...
...
@@ -44,27 +60,102 @@ export default {
</
script
>
<
script
lang=
"ts"
setup
>
import
{
onMounted
,
reactive
,
ref
}
from
'vue'
;
import
{
delEmptyObjkey
}
from
'src/common/util
s'
;
import
ICON
from
'src/config/icon
s'
;
import
{
useMessage
}
from
'src/common/hook
s'
;
import
{
delEmptyObjkey
,
isEmpty
}
from
'src/common/util
s'
;
import
Com
from
'src/components'
;
import
{
form
}
from
'./config'
;
import
COLORLIST
from
'./colorList'
;
const
{
success
,
warn
}
=
useMessage
();
const
myForm
=
ref
<
any
>
(
null
);
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
({
config
:
form
,
config
:
[]
as
any
[]
,
value
:
{
name
:
'法外狂徒张三'
,
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
,
});
const
state
=
reactive
({
dense
:
false
,
disable
:
false
,
readonly
:
false
,
});
onMounted
(()
=>
{
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
()
{
let
arr
:
any
[]
=
[];
const
length
=
7
;
...
...
@@ -114,8 +205,12 @@ function onChange() {
}
function
onSubmit
()
{
myForm
.
value
.
validate
().
then
((
success
:
any
)
=>
{
if
(
!
success
)
return
;
myForm
.
value
.
validate
().
then
((
suc
:
any
)
=>
{
if
(
!
suc
)
return
;
if
(
isEmpty
(
formState
.
value
.
workingDay
))
{
return
warn
(
'工作日必填'
);
}
success
(
'校验通过'
);
console
.
log
(
'formValue'
,
delEmptyObjkey
(
formState
.
value
));
});
}
...
...
@@ -126,10 +221,47 @@ function onResetForm() {
</
script
>
<
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
{
margin-top
:
$padding-sm
;
margin-bottom
:
20px
;
width
:
800px
;
box-sizing
:
border-box
;
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
>
src/modules/page2/config.ts
View file @
0562c9f8
export
const
form
=
[
{
fild
:
'name'
,
label
:
'姓名'
,
col
:
'col-6'
,
type
:
'text'
,
required
:
true
,
bind
:
{
readonly
:
true
,
filled
:
true
,
label
:
'姓名*'
,
lazyRules
:
true
,
hideBottomSpace
:
true
,
rules
:
[(
val
:
any
)
=>
(
val
&&
val
.
length
>
0
)
||
'必填'
],
...
...
@@ -13,32 +15,32 @@ export const form = [
},
{
fild
:
'password'
,
label
:
'密码'
,
col
:
'col-6'
,
type
:
'password'
,
isPwd
:
true
,
bind
:
{
filled
:
true
,
label
:
'密码*'
,
lazyRules
:
true
,
hideBottomSpace
:
true
,
rules
:
[(
val
:
any
)
=>
(
val
&&
val
.
length
>
0
)
||
'必填'
],
// lazyRules: true,
// hideBottomSpace: true,
// rules: [(val: any) => (val && val.length > 0) || '必填'],
},
},
{
fild
:
'age'
,
col
:
'col-6'
,
label
:
'年龄'
,
type
:
'number'
,
bind
:
{
filled
:
true
,
label
:
'年龄'
,
},
},
{
fild
:
'country'
,
label
:
'国家'
,
col
:
'col-6'
,
type
:
'select'
,
bind
:
{
label
:
'国家*'
,
filled
:
true
,
emitValue
:
true
,
mapOptions
:
true
,
...
...
@@ -56,52 +58,44 @@ export const form = [
value
:
'france'
,
},
],
lazyRules
:
true
,
hideBottomSpace
:
true
,
rules
:
[(
val
:
any
)
=>
(
val
&&
val
.
length
>
0
)
||
'必填'
],
//
lazyRules: true,
//
hideBottomSpace: true,
//
rules: [(val: any) => (val && val.length > 0) || '必填'],
clearable
:
true
,
},
},
{
fild
:
'quantity'
,
label
:
'数量'
,
col
:
'col-6'
,
type
:
'number'
,
bind
:
{
filled
:
true
,
label
:
'数量'
,
},
},
{
solt
:
'
solt2
'
,
solt
:
'
class
'
,
col
:
'col-6'
,
},
{
fild
:
'remark'
,
label
:
'备注'
,
col
:
'col-12'
,
type
:
'textarea'
,
bind
:
{
filled
:
true
,
label
:
'备注'
,
},
},
{
solt
:
'test'
,
col
:
'col-6'
,
},
{
fild
:
'aaa'
,
solt
:
'workingDay'
,
col
:
'col-6'
,
type
:
'text'
,
bind
:
{
label
:
'测试'
,
},
},
{
fild
:
'date1'
,
col
:
'col-6'
,
type
:
'date'
,
label
:
'日期1'
,
bind
:
{
label
:
'日期1'
,
filled
:
true
,
clearable
:
true
,
dateMask
:
'YYYY-MM-DD HH:mm:ss'
,
...
...
@@ -109,10 +103,10 @@ export const form = [
},
{
fild
:
'date2'
,
label
:
'日期2'
,
col
:
'col-6'
,
type
:
'date'
,
bind
:
{
label
:
'日期2'
,
filled
:
true
,
clearable
:
true
,
dateMask
:
'YYYY-MM-DD'
,
...
...
@@ -120,10 +114,10 @@ export const form = [
},
{
fild
:
'dateMultiple'
,
label
:
'日期多选'
,
col
:
'col-6'
,
type
:
'dateMultiple'
,
bind
:
{
label
:
'日期多选'
,
filled
:
true
,
clearable
:
true
,
dateMask
:
'YYYY/MM/DD'
,
...
...
@@ -131,10 +125,22 @@ export const form = [
},
{
fild
:
'dateRange'
,
label
:
'日期范围'
,
col
:
'col-6'
,
type
:
'dateRange'
,
bind
:
{
label
:
'日期范围'
,
filled
:
true
,
clearable
:
true
,
dateMask
:
'YYYY-MM-DD'
,
},
},
{
fild
:
'dateRangeMultiple'
,
label
:
'日期范围多选'
,
col
:
'col-6'
,
type
:
'dateRange'
,
bind
:
{
multiple
:
true
,
filled
:
true
,
clearable
:
true
,
dateMask
:
'YYYY/MM/DD'
,
...
...
@@ -142,13 +148,35 @@ export const form = [
},
{
fild
:
'time1'
,
label
:
'时间1'
,
col
:
'col-6'
,
type
:
'time'
,
bind
:
{
label
:
'时间1'
,
filled
:
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
:
[],
},
},
];
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